欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java面试题冲刺第九天--MyBatis

程序员文章站 2022-03-30 17:03:03
目录面试题1:你怎么理解orm框架,常见的orm框架都有哪些?追问1:大家都在用mybatis,mybatis都有哪些优势?面试题2:相比较hibernate与mybatis,你有哪些看法?面试题3:...

面试题1:你怎么理解orm框架,常见的orm框架都有哪些?

正经回答:

对象关系映射(object relational mapping,简称orm),主要实现程序对象到关系数据库数据的映射。

Java面试题冲刺第九天--MyBatis

java编程免不了和数据库打交道,那么如何高效便捷地操作数据库,也是一个需要应对的问题,原生的基于jdbc的方式非常低效,而且要写一大堆无用的模板代码,不值得选取。orm是对jdbc的封装,让我们不需要重复的造*,目前已经有很多优秀的orm框架可供使用了,常见的比如mybatis(batis)、hibernate、jpa、jdo等。

优点:

  • orm是对jdbc的封装,从而解决了jdbc的各种存在问题,提高效率
  • 使开发更加对象化
  • 可移植性强
  • 可以很方便地引入数据缓存之类的附加功能

缺点:

  • 自动化进行关系数据库的映射需要消耗少量系统性能。
  • 在处理多表联查、where条件复杂之类的查询时,orm的语法会变得复杂。

市面上主流orm框架:

  • ejb:重量级、高花费的orm技术,支持jpa,尤其是ejb3低侵入式 的设·计,增加了annotation
  • hibernate:开源,支持jpa ,被选作jboss的持久层解决方案
  • ibatis:”sql mapping”框架,apache软件基金组织的子项目,后 转google code旗下,ibatis3.x正式更名为mybatis
  • spring data jpa:spring框架中的子模块
  • toplink:oracle公司的产品
  • open jpa:apache软件基金组织的开源项目

追问1:大家都在用mybatis,mybatis都有哪些优势?

  • mybatis入门简单;在使用上,对于熟悉编写sql的同学来说,基本上是即学即用。
  • mybatis对jdbc的抽象封装程度更高,spring jdbc要想实现的细节很多,例如mybatis封装了更多的对象映射。
  • 支持注解,面对接口开发,效率高,分分钟解决一个sql。
  • 对于复杂的sql,springjdbc编写麻烦,动态sql语句设计也麻烦,相比之下,mybatis更加灵活且人性化。
  • mybatis的高度封装,使得程序员可专注与业务层,开发效率高。所以选择mybatis的开发公司多。

面试题2:相比较hibernate与mybatis,你有哪些看法?

正经回答:

hibernate与mybatis都可以是通过sessionfactorybuider由xml配置文件生成sessionfactory,然后由sessionfactory 生成session,最后由session来开启执行事务和sql语句。其中sessionfactorybuider,sessionfactory,session的生命周期都是差不多的。

hibernate和mybatis都支持jdbc和jta事务处理。

mybatis优势

  • mybatis可以进行更为细致的sql优化,可以减少查询字段。
  • mybatis容易掌握,而hibernate门槛较高。

hibernate优势

  • hibernate的dao层开发比mybatis简单,mybatis需要维护sql和结果映射。
  • hibernate对对象的维护和缓存要比mybatis好,对增删改查的对象的维护要方便。
  • hibernate数据库移植性很好,mybatis的数据库移植性不好,不同的数据库需要写不同sql。
  • hibernate有更好的二级缓存机制,可以使用第三方缓存。mybatis本身提供的缓存机制不佳。

Java面试题冲刺第九天--MyBatis

摘自某乎上的经典总结:

hibernate

  • hibernate功能强大,数据库无关性好,o/r映射能力强,如果你对hibernate相当精通,而且对hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
  • hibernate的缺点就是学习门槛不低,要精通门槛更高,而且怎么设计o/r映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好hibernate方面需要你的经验和能力都很强才行。

mybatis

  • mybatis入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的sql使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
  • mybatis的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。 深入追问: 追问1:hibernate与mybatis 的缓存机制都有哪些区别?

相同点:

hibernate和mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通过实现你自己的缓存或为其他第三方缓存方案,创建适配器来完全覆盖缓存行为。

不同点:

hibernate的二级缓存配置在sessionfactory生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置是那种缓存。

mybatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且mybatis可以在命名空间*享相同的缓存配置和实例,通过cache-ref来实现。

两者比较:   因为hibernate对查询对象有着良好的管理机制,用户无需关心sql。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。

而mybatis在这一方面,使用二级缓存时需要特别小心。如果不能完全确定数据更新操作的波及范围,避免cache的盲目使用。否则,脏数据的出现会给系统的正常运行带来很大的隐患。

面试题3:mybatis中的#{}和${}有哪些区别

正经回答:

-- #{}
<select id="userlogin" parametertype="java.util.map" resultmap="userresmap">
select id, username, password, role
from user
where username = #{username}
and password = #{password}
</select>
-- ${}
<select id="userlogin" parametertype="java.util.map" resultmap="userresmap">
select id, username, password, role
from user
where username = ${username}
and password = ${password}
</select>

1.#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

如:where username=#{username},如果传入的值是111,那么解析成sql时的值为where username=“111”, 如果传入的值是id,则解析成的sql为where username=“id”.

2.$将传入的数据直接显示生成在sql中。

如:where username=${username},如果传入的值是111,那么解析成sql时的值为where username=111;

那么,如果传入的值是:;drop table user;会怎么样?解析后的sql为:

select id, username, password, role from user where username=;drop table user;

#方式能够很大程度防止sql注入,$方式无法防止sql注入。

$方式一般用于传入数据库对象,例如传入表名;

一般能用#的就别用$,若不得不使用 “${xxx}” 这样的参数,要手工地做好过滤工作,来防止sql注入攻击。

在mybatis中,“${xxx}”这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。

综上,我们在编写mybatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。

深入追问:

追问1:什么是sql注入?

sql注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的sql语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者)

Java面试题冲刺第九天--MyBatis

说到sql注入,相信大家都不陌生,这是黑客同学常用的一种攻击方式。攻击者在界面的表单信息或url上输入一些奇怪的sql片段(例如“or ‘1'='1'”这样的语句),有可能入侵参数检验不足的应用程序。

所以,在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性要求很高的应用中(比如银行软件),经常使用将sql语句全部替换为存储过程这样的方式,来防止sql注入。这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。

追问2:mybatis是如何做到防止sql注入的?

mybatis框架作为一款半自动化的持久层框架,其sql语句都要我们自己手动编写,这个时候当然需要防止sql注入。其实,mybatis的sql是一个具有“输入+输出”的功能,类似于函数的结构,参考上面的两个例子。

其中,parametertype表示了输入的参数类型,resulttype表示了输出的参数类型。回应上文,如果我们想防止sql注入,理所当然地要在输入参数上下功夫。上面代码中使用#的即输入参数在sql中拼接的部分,传入参数后,打印出执行的sql语句,会看到sql是这样的:

select id, username, password, role from user where username=? and password=?

不管输入什么参数,打印出的sql都是这样的。这是因为mybatis启用了预编译功能,在sql执行前,会先将上面的sql发送给数据库进行编译;执行时,直接使用编译好的sql,替换占位符“?”就可以了。因为sql注入只能对编译过程起作用,所以这样的方式就很好地避免了sql注入的问题。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注的更多内容!