MyBatis

1、什么是MyBatis?

(1)MyBatis是一个半自动的ORM(对象关系映射)框架;他内部封装了JDBC,开发者只需要考虑SQL语句本身,不需要考虑驱动加载,创建连接,创建statement等过程;

(2)MyBatis通过XML或注解来配置和映射原生信息,将POJO(Plain Ordinary Java Object,普通java对象)映射成数据库中的记录;

(3)通过XML或注解的方式把将要执行的statement配置起来,通过java对象和statement的动态参数设置形成sql语句,让MyBatis框架执行sql语句,并把结果形成java对象返回;

2、MyBatis的优点?

(1)基于sql语句编程,相当灵活,不会对应用程序和数据库现有设计造成影响,SQL写在XML里,解除了sql与程序代码之间的耦合,支持编写动态SQL语句,并可重用;

(2)与JDBC相比,减少了JDBC代码的冗余,不用手动开关连接;

(3)可以很好的与各种数据库连接(底层是JDBC实现的,所以只要JDBC能连接的数据库,MyBatis都可以支持);

(4)可以与Spring集成;

(5)提供映射标签,支持对象和数据库的ORM字段关系映射,提供对象关系映射,支持对象关系组件维护;

动态SQL:如果嵌入到的高级语言中的SQL语句没有明确给出,如在java中定义了字符串str,然后采用prepareStatement对象的execute方法执行这个sql,该sql的值可能等于文本框读取的一个sql或者从键盘上输入的sql,但是具体是什么,在编译的时候,无法确定,只有等到运行的时候,在执行过程中才能确定,这种SQL叫动态SQL;

用mybatis对一张表进行的CRUD操作,都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。就可以用动态SQL来解决,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。

写一个动态SQL的例子:

3、MyBatis的缺点?

(1)SQL语句的编写数据量大,尤其是当字段多,关联表多时;

(2)SQL语句依赖数据库(动态SQL对于不同的数据库,语句不同),导致数据移植性差,不能随意更换数据库;

 

4、MyBatis使用什么场景?

(1)MyBatis专注于SQL本身,是一个足够灵活的DAO层;

(2)对性能要求很多,适用于那些变化多的项目,如互联网项目;

5、MyBatis与Hibernate有什么不同?

(1)MyBatis并不是一个完全的ORM框架,他是一个半自动的ORM,他需要程序员自己手动编写SQL语句;

(2)MyBatis直接编写原生sql语句,可以严格控制sql语句的执行性能,灵活性高,非常适合对数据关系模型要求不高的软件,因为这类软件需求变化频繁,一旦需求变化立即输出结果;但是灵活的MyBatis无法做到数据库无关性,如果需要实现多种数据库的软件,则需要自定义多个sql映射文件,工作量大;

(3)而Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用Hibernate开发,可以节省很多代码,提高效率;

6、#{} 和 ${} 的区别是什么?

#{} :预编译处理;${} :字符串替换;

MyBatis在处理 #{} 时,会将sql语句的 #{} 变成?,调用PrepareStatement的set方法来赋值;

MyBatis在处理 ${} 时,就是把 ${} 替换变量的值;

使用 #{} 可以有效的防止sql注入,提高系统的安全性;

7、当实体类中的属性名和表中的字段不一样,怎么办?

(1)可以使用别名

(2)可以使用<resultMap>来映射字段名和实体类的属性名一一对应;

8、模糊查询语句怎么写?

(1)在java代码里添加sql通配符;

(2)在sql语句中拼接通配符,会引起sql注入;

9、通常一个XML映射文件,都会有一个DAO接口与之对应,请问,这个DAO接口的工作原理是什么?DAO接口里的方法,参数不同时,方法能重载吗?

DAO接口就是Mapper接口;接口的权限名,就是映射文件namespace的值;Mapper接口的方法名,就是映射文件中Mapper的Statement的id值;接口方法中的参数,就是sql的参数;Mapper接口没有实现类,当调用接口的时候,接口权限名+方法名拼接成的字符串作为key,可唯一确定一个MapperStatement;在MyBatis中的<select>,<insert>,<update>,<delete>标签,都会被解析成一个MapperStatement;举例: com.mybatis.mapper.StudentDao.findStudentById,可以唯一找到namespace为 com.mybatis.mapper.StudentDao下面 id 为 findStudentById 的 MapperStatement。Mapper接口中的方法不能被重载,因为是权限名+方法名的保存和寻找的策略;Mapper接口的工作原理是jdk动态代理,MyBatis运行时会使用jdk动态代理为Mapper接口生成动态代理对象proxy,这个代理对象会拦截接口方法,转去执行MapperStatement代理的sql,然后将sql执行完的结果返回;

10、Mybatis是如何进行分页的?分页插件的原理是什么?

MyBatis是通过RowBounds对象进行分页的,他是针对ResultSet结果集进行的内存分页,不是物理分页,是逻辑分页;可以在sql内直接书写带有物理分页的参数来完成物理分页的功能,也可以分页插件来完成物理分页;

分页插件的基本原理是使用MyBatis提供的插件接口(pagehelper),实现自定义插件,在插件拦截方法内拦截待执行的sql,然后重写sql语句,根据dialect方言,添加对应的物理分页和物理分页参数;

11、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

(1)通过使用sql列别名的形式,将列的别名书写为类的属性名;

(2)使用<resultMap>标签,逐一定义数据库列名和对象属性名的映射关系;

有了列名和属性名,MyBatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回;

12、如何执行批量插入?

首先定义insert的语句;

进行批量插入操作;

13、如何获取自动生成的(主)键值?

insert方法执行成功后会返回一个int类型的值,该值是代表插入的行数;

如果采用自增策略,自动生成的键值在insert方法完成之后被设置到传入参数对象中;

14、Mybatis动态sql有什么用?执行原理?有哪些动态sql?

MyBatis动态sql可以在xml文件里,以标签的形式编写动态sql,执行原理是根据表达式的值完成逻辑判断并动态拼接sql的功能;

MyBatis提供了9种动态sql标签,if |trim |when |where |foreach |otherwise |bind |choose |set ;

15、Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?

<resultMap> , <selectKey> , <parameterMap> , <sql> , <include>,还有动态sql的9种标签;其中 <sql>是sql的片段标签,通过 <include>引入的sql片段,<selectKey>为不支持自增的主键生成策略标签;

16、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

不同的XML映射文件,如果配置了namespace,那么id就可以重复;否则不可以;因为namespace+id是作为Map <String,MapperStatement>的key使用的,如果没有namespace,就只剩下id了,那么如果重复的话,会导致数据相互覆盖;有了namespace,自然id就可以重复了;

17、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

Hibernate属于全自动的ORM映射工具,使用Hibernate查询关联对象或关联集合对象时,可以根据对象关系模型直接获取,所以他是全自动的;而MyBatis是半自动的ORM映射工具,使用Mybatis查询关联对象或关联集合对象时,必须要自己编写sql语句来完成;

18、MyBatis实现一对一有几种方式?具体怎么操作的?

联合查询和嵌套查询;

联合查询:几个表联合查询,只查询一次,通过在resultMap里面配置association节点配置一对一的类就可以完成;

嵌套查询:先查询一个表,根据这个表里的结果的外键id,再在另一个表里查询数据,也是通过association配置,但是另外一个表的查询是通过select属性配置;

19、MyBatis实现一对多有几种方式,怎么操作的?

联合查询和嵌套查询;

联合查询:几个表联合查询,只查询一次,通过在resultMap里面配置collection节点配置一对多的类就可以完成;

嵌套查询:先查询一个表,根据这个表里的结果的外键id,再在另一个表里查询数据,也是通过collection配置,但是另外一个表的查询是通过select节点配置;

20、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

MyBatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询;在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false;原理是使用CGLIB创建目标对象的动态代理对象,当调用目标对象时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是空值,那么就会单独发送事先保存好的查询关联B对象的sql语句,然后把B对象查询上来,在调用a.setB(b),于是a对象的b属性就有值了,接着完成a.getB().getName()方法的调用;这就是延迟加载的基本原理;延迟加载就是懒加载,先不执行,直到需要的时候,才执行;

21、Mybatis的一级、二级缓存?

(1)一级缓存:基于PerpetualCache的HashMap本地缓存,其作用域是Session,当Session flush或close时,该Session中的所有Cache将被清空,默认打开一级缓存;

 MyBatis 缓存机制是基于id进行缓存,MyBatis通过HashMap存储数据,使用键值对,id作为键;

(2)二级缓存:与一级缓存机制相同,都是采用PerpetualCache的HashMap缓存;不同在于其存储作用域是Mapper(namespace),并且可自定义存储源,如EhCache;默认不打开二级缓存,要开启二级缓存,使用二级存储类需要实现Serializable序列化接口(用来保存对象状态),可在他的映射文件中配置</cache>;用二级缓存的时候,多个SqlSession使用同一个Mapper的Sql语句去操作数据库;得到的数据存入二级缓存中;

<settings>

<!--开启二级缓存-->

<settingname="cacheEnabled"value="true"/>

</settings>

(3)对于缓存的更新机制,当某一个作用域(一级缓存session/二级缓存namespace)进行了C/U/D操作后,默认作用域下所有select中的缓存将被clear;

22、什么是MyBatis的接口绑定?有哪些实现方式?

接口绑定:MyBatis任意定义接口,然后让接口方法和sql语句绑定,这样直接调用接口方法就可以,这样比起原来的SqlSession提供的方法有更加灵活的选择和设置;

有两种实现方式:注解实现,在接口方法上加上注解,@Select,@Update等注解,里面包含sql来绑定;xml实现,在XML文件里写sql语句来绑定,这种情况下,要指定XML映射文件的namespace必须为接口的全路径;当Sql语句比较简单的时候,用注解来绑定,当SQL语句比较复杂时候,用XML绑定,一般用XML绑定的比较多;

23、使用MyBatis的mapper接口调用时有哪些要求?

(1)Mapper接口中的方法名和mapper.xml中定义的每个sql的id一样;

(2)Mapper接口中方法的输入参数类型和mapper.xml中定义的每个sql的parameterType类型一样;

(3)Mapper接口中方法的输出参数类型和mapper.xml中定义的每个sql的resultType类型一样;

(4)mapper.xml文件的namespace即是mapper接口的类路径;

24、简述Mybatis的插件运行原理,以及如何编写一个插件?

MyBatis仅可以编写针对ParameterHandler,ResultSetHandler,StatementHandler,Executor这四种接口的插件,MyBatis使用jdk动态代理来实现,为需要拦截的接口生成动态代理对象以实现接口方法的拦截,每当执行这四种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定的方法;

编写一个插件:实现MyBatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截的方法,记住,别忘了在配置文件中配置你写的插件。

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值