参考资料:https://my.oschina.net/zudajun/blog/747682

 

1、#{}和${}的区别?

  ${}是Properties文件的占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${name}会被静态替换为my.name.is.xxx。

  #{}是sql参数占位符,mybatis会将SQL中的#替换为?,在SQL执行前使用PreparedStatement的参数设置方法,按序给SQL的?占位符设置参数值,#{item.name}的取值方式为使用反射从参数对象中获取item对象的name属性,相当于param.item.getName()。

2、常见标签

  select,update,insert,delete,resultMap,parameterMap,动态SQL的9个标签:trim,where,set,foreach,if,choose,when,otherwise,bind,<sql>为SQL片段标签,通过<include>标签引入SQL片段,<selectKey>不支持自增的主键生成策略标签。

3、最佳实践中,通常是一个xml映射文件会对应一个Dao层接口,这个Dao层的工作原理是什么?Dao层接口里的方法,参数不同时可以重载么?

  Dao层接口就是Mapper层接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名就是映射文件中MapperedStatement的ID值,接口内的参数就是传递给SQL的参数。

  Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名作为key,定位唯一MapperedStatement,因此不能重载。

  Dao接口的工作原理是JDK动态代理,Mybatis运行会使用JDK动态代理为Dao接口生成Proxy对象,代理Proxy对象会拦截接口方法,转而执行MapperStatement代表的SQL,然后返回执行结果。

4、Mybatis是如何分页的,插件的执行原理是什么?

  Mybatis使用RowBounds对象进行分页,它针对resultSet结果集进行内存分页。

  分页插件是物理分页,基本原理是拦截待执行的sql,添加对应的物理分页语句和分页参数,如:select * from table_A ,被拦截后重写为:select a.* from (select * from table_A)  a limit 0,10;

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

  Mybatis仅可以针对 ParameterHandler,ResultSetHandle,StatementHandler,Executor 4个接口编写插件,Mybatis使用动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这四种接口对象的方法时,就进入拦截方法,具体就是InvocationHandler的invoke()方法(只拦截你指定需要拦截的方法)。

  实现Mybatis的Interceptor接口,并复写intercept()方法,然后给插件编写注解,指定拦截哪个接口的哪个方法,最后在配置文件中配置你编写的插件。

6、Mybatis批量插入,能返回数据库主键列表么?

  JDBC可以所以mybatis也可以。

7、Mybatis动态SQL是做什么的,都有哪些动态SQL,简述一下动态SQL的执行原理  

  在XML映射文件内,通过标签编写动态SQL,完成逻辑判断和动态拼接SQL的功能,mybatis 提供了9种动态SQL标签 trim、where、choose、when、otherwise、if、foreach、set、bind。工作原理是使用OGNL从SQL参数对象中计算表达式的值,根据表达式的值动态拼接SQL。

8、Mybatis是如何将视SQL结果封装为目标对象并返回的,都有哪些形式?

  第一种:<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。

  第二种:使用SQL列的别名功能,A_NAME as name,Mybatis能根据别名找到对应的属性名。

  有了列名属性名的映射关系,Mybatis通过反射创建对象,同时通过反射给对象逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

9、Mybatis能执行一对一、一对多的关联查询么?都有哪些实现方式,他们之间的区别是什么?

  Mybatis能执行N对N的任意查询,关联对象查询有两种实现方式,一种是单独发送一个SQL查询关联对象,然后赋值给主对象,然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用join查询,一部分列是A对象的属性值,另一部分列是关联对象B的属性值,发送一个sql可以把主对象和其关联对象都查出来。当join查询出100条而主对象只有5个时,就需要靠<resultMap>的字标签<id>指定唯一确定一条记录的id列,<id>可以是多个,代表联合主键的语意。

10、Mybatis是否支持延时加载?如何支持,原理是什么?

  Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的是一对一,collection指的是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。

  原理是,使用GCLIB创建目标对象的代理对象,当调用目标方法时进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()的值是null,那么就会发送事先保存好的查询关联B对象的SQL,把B查出来,然后调用a.setB(b),于是a对象的b就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的原理。当然,除了Mybatis Hibernate也是这么回事。

11、Mybatis的XML映射文件中不同映射文件 id能否相同?

  不同映射文件中如果配置了namespace,那么id可以相同。

12、Mybatis如何执行批处理?

  使用BatchExecutor完成批处理。

13、Mybatis有哪些Executor执行器,他们之间的区别?

  Mybatis有三种基本的Executor执行器,SimpleExecutor,ReuseExecutor,BatchExecutor。

  SimpleExecutor:每执行一次update或者select,就开启一个statement对象,用完立即关闭statement对象。

  ReuseExecutor:执行update或select以SQL作为key查找Statement对象,存在就使用,不存在就创建,使用后不关闭,放在Map<String,Statement> 内,供下一次使用,就是重复使用。

  BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有SQL添加到批处理中(addBatch()),等待统一执行(executorBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executorBatch()批处理。与JDBC相同。

14、Mybatis中如何指定使用哪一种Executor执行器?

  Mybatis配置文件中可以指定磨人的ExecutorType执行器类,也可以手动给DefaultSqlSessionFactory的创建SQLSession的方法传递ExecutorType类型参数。

15、Mybatis是否可以映射Enum枚举类?

  Mybatis可以映射枚举类,不单可以映射枚举类,Mybatis可以映射任何对象到表的一列上。映射方式是定义一个TypeHandler,实现TypeHandler的setParameter()和getResult()接口方法。

  TypeHandler有两个作用,一是完成从JavaType到JDBCType的转换,二是完成JDBCType到JavaType的转换,体现为setParameter()和getResult()两个方法,分别代表SQL问号占位符参数和获取列查询结果。

16、Mybatis映射文件中,如果A标签通过include引用B标签的内容,请问,B标签能否定义在B标签后面?

  虽然Mybatis解析XML映射文件是按顺序的,但是被引用的B标签可以定义在任何地方,因为Mybatis解析A标签时发现引用B标签,但此时B标签还未解析到,Mybatis会将A标签也标记为未解析,然后继续向下解析,当全部解析完后,Mybatis会重新解析之前未接洗的标签,此时B标签已解析,A标签也就可以解析了。

17、简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系?

  Mybatis将所有XML配置信息都封装到All-In-One重量级对象Configuration内部。在XML映射文件中,<parameterMap>标签会被解析为ParameterMap对象,其每个子元素会被解析为ParameterMapping对象。

  <resultMap>标签会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping对象。<select><delete><update><insert>均会被解析为MapperedStatement对象,标签内的SQL会解析为BoundSql对象。

18、为什么说Mysql是半自动ORM映射工具?他与全自动的区别在哪?

  Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或关联集合对象是,可以根据对象关系模拟直接获取,所以说是全自动。而Mybatis需要手动编写SQL完成,所以称为半自动。

  

  

  

  

 

 

  

  

  

 

  

 

  

相关文章: