2.1Mybatis输入输出支持的类型有哪些?

Mybatis中Dao映射配置中的parameter属性表示输入参数类型,它对应Dao接口方法的参数类型有三种:
(1)基本数据类型+String类型:如整数、小数、字符串等;
(2)自定义的实体类pojo,要输入类的全限定名。
输出参数有两种表示形式,分别是resultType和resultMap。
resultType可以指定结果集的类型,它可以支持基本数据类型和实体类型,但pojo类中的属性名必须和查询到的数据库表的字段名保持一致;如果不一致的话可以使用resultMap手动实现将pojo类的属性名与数据库表的字段名映射,可以实现更加复杂的查询,在一对多、多对一的关联查询中也经常使用。

2.2Mybatis中如何实现一对多关联查询?

一对多可以使用collection标签来实现,pojo实体类中为了能实现一对多的存储关系,需要在主实体类上增加集合属性,用于封装子表对应的实体类。
(1)通过select标签定义查询主表的sql语句,返回结果通过resultMap进行映射;
(2)在resultMap中,除了映射主表属性,还要通过collection标签映射子表属性,该标签包括以下内容:
通过property属性指定子表属性名;
通过javaType属性指定封装子表属性的集合类型;
通过ofType属性指定字表的实体类型;

  1. <select id="getTeacher" resultMap="teacherstudent">
  2. select t.id tid,t.name tname,s.id sid,s.name sname from teacher t,student s where t.id=s.tid;
  3. </select>
  4. <resultMap id="teacherstudent" type="teacher">
  5. <result property="id" column="tid"/>
  6. <result property="name" column="tname"/>
  7. <collection property="students" javaType="ArrayList" ofType="student">
  8. <result property="id" column="sid"/>
  9. <result property="name" column="sname"/>
  10. </collection>
  11. </resultMap>

如果是多对一的关联查询,可以使用association标签来实现。

  1. <select id="getStudent" resultMap="studentteacher">
  2. select s.id sid,s.name sname,t.name tname from student s,teacher t where s.tid=t.id;
  3. </select>
  4. <resultMap id="studentteacher" type="student">
  5. <result property="id" column="sid"/>
  6. <result property="name" column="sname"/>
  7. <association property="teacher" javaType="teacher">
  8. <result property="name" column="tname"/>
  9. </association>
  10. </resultMap>

2.3Mybatis的$和#有什么区别?

使用#设置参数时,mybatis会创建预编译的sql语句,参数为sql中的占位符(?),然后在执行sql语句时会为预编译sql中的占位符(?)赋值。预编译的sql语句执行效率高,并且可以防止sql注入功能。
使用$设置参数时,mybatis只是创建普通sql语句,然后在执行sql语句时,mybatis将参数直接拼入到sql里。这种方式在效率、安全性上不如前者,不能防止sql注入。
#和$在使用中的技巧:
(1)无论是单个参数还是多个参数,都建议使用注解@Param(“”)
(2)能用#的地方就用#,不用或少用$
(3)表名做参数时,必须用$ 如:select from ${tableName}
(4)order by时,必须用$,如:select
from table_name order by $ {columnName}

2.4Mybatis的xml文件和怎么和Mapper接口绑定的?

通过xml文件中,通过根标签中的namespace属性进行绑定,即namespace属性的值需要配置成接口的全限定名称,Mybatis内部就会通过这个值将接口与xml关联起来。

2.5Mybatis分页和自己写的分页哪个效率高?

在Mybatis中,我们可以通过分页插件实现分页,也可以通过分页sql自己实现分页。其中分页插件的原理是拦截查询sql,在这个sql基础上自动为其添加limit分页条件,它会大大提高开发效率,但是无法对分页语句做出有针对性的优化,比如分页偏移量很大的情况,而在这种情况下自己写的分页sql里是可以灵活实现的。

2.6了解Mybatis缓存机制吗?

mybatis的缓存分为一级缓存和二级缓存。
一级缓存也叫本地缓存,一级缓存的作用域默认是sqlSession,mybatis默认会开启。在同一个sqlSession中查询时,第一次查询mybatis会把执行的方法和参数通过算法生成缓存的键,将键和查询结果存入一个Map对象中。如果同一个sqlSession中之后执行的方法和参数完全一致,那么通过算法会生成相同的键值,当Map中已经有该键值,就会返回缓存中的对象。当执行sql查询中间发生了增删改的操作,mybatis就会把sqlSession中的缓存清空。一级缓存的范围有session和statement两种,默认是Seesion,如果不想使用一级缓存,可以把一级缓存的作用域改成statement,这样每执行完一个sql语句都会清空一级缓存。但不建议这样做。
二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个sqlSession共享,mybatis需要手动设置启动二级缓存。
工作机制:
同数据库交互的一次会话,会将查询的结果存储到一级缓存中。当我们关闭当前会话时,一级缓存中的数据也会消失。但我们想要的是,即使关闭了sqlSession,依然能够从缓存中直接取数据而不经过数据库,所以就诞生了二级缓存。在会话关闭后,一级缓存中的数据被保存到二级缓存的,新的会话只要是同一个nameSpace下的映射文件,且之前的查询结果已经保存至了二级缓存,就可以直接从二级缓存中获取结果。查询顺序是先经过二级缓存,如果二级缓存中没有,就去一级缓存中取,如果一级缓存中也没有,就需要访问数据库查询结果, 并将此次查询结果保存至一级缓存,当当前会话关闭后,数据保存至二级缓存中。
(1)如果需要频繁增删改数据,建议不使用二级缓存,因为任何增删改的操作都会刷新二级缓存,二级缓存频繁刷新将降低系统性能。
(2)使用二级缓存有可能出现数据不一致的现象。
注意:
(1)由于二级缓存是基于namespace级别的,不同的namespace数据不相干扰。但如果多个namespace均对同一个表进行操作,那么这多个namespace的数据可能就会出现不一致现象。
(2)如果一个表和其他表有关联关系,那么就可能存在多个namespace操作同一数据的现象。而不同namespace的数据互不干扰,所以也有可能多个namespace的数据不一致现象。
二级缓存的效果:
(1)映射语句文件中的所有select语句包括参数和结果集都会被缓存;
(2)映射语句文件中所有insert\update\delete语句都会刷新缓存;
(3)二级缓存默认能缓存5000个key-value元素,缓存会使用LRU算法来淘汰数据;
(4)缓存会存储集合或对象(无论查询方法返回什么类型的值)的1024个引用;