Mybatis相关面试题

MyBatis的执行流程?

1.通过SqlSessionFactory创建SqlSessionFactory
在SqlSessionFactoryBuilder的build方法中使用XMLConfigBuilder用来解析
配置文件mybatis-config.xml 然后创建并返回一个DefaultSqlSessionFactory
2.通过SqlSessionFactory创建SqlSession,用于执行Sql语句
3.通过SqlSessionFactory创建SqlSession,用于执行Sql语句
4.通过MapperProxy调用Mapper中相应的方法。
5.提交或者回滚
6.关闭Session

Mybatis中的#{}和${}有什么区别?

#{}内部使用预编译PreparedStatement机制执行SQL,支持?占位符,可以防止SQL注入
{} 内部使用Statement机制将参数和SQL拼接在一起发送执行,不支持?占位符,参数只能拼接。
只有能用的占位符的地方,都建议使用#{}
如果是表名或字段名或者like 建议使用${}

Mybatis是如何进行分页的?分页插件的原理?

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集进行的分页,非物理分页,假分页。
可以在sql内直接书写带物理分页的参数来完成物理分页,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件。
在插件的拦截方法内拦截待执行的Sql,然后重新Sql,添加分页语句。

Mybatis的插件运行原理?怎样编写一个插件?

Mybatis仅可以针对ParameterHandler、ResultSetHandler、StatementHandler、Excecutor这四种接口的插件
Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能。
每当执行这四种接口对象方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke()方法
当然,它只会拦截你那些指定需要拦截的方法。
实现Mybatis的Interceptor接口并复写intercept方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,做完之后需要在配置文件中配置编写的插件

通常一个Xml映射文件都会有一个Mapper接口与之对应,这个接口的工作原理是什么?Mapper接口里的方法可以重载吗?

1.Mapper接口的全限定名,是映射文件中的namespace的值。
2.接口中的方法,就是映射文件中MappedStatement的id值。
3.接口方法内的参数,就是传递给sql的参数。
4.Mapper接口是每页实现类的,当调用接口方法时,接口的全限定名+方法名拼接
字符串作为key值,可唯一定位一个MapperStatement。

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

Mapper接口里的方法,是不能重置的,因为是全限定名+方法名的保存和寻找策略。

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

1.还有很多其它的标签
resultMap、parameterMap、sql、include、SelectKey
2.另外,还有动态标签
trim、here、set、foreach、if、choose、when、otherwise、bind等

动态sql的执行原理?

Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能
其执行原理是使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,最后来完成动态 sql 的功能

Mybatis 批量添加用的什么标签?动态标签 foreach 有哪些属性?

foreach标签
foreach标签的属性有

  • collection:指定输入对象中集合属性
  • index:这个属性用来指定用来访问迭代集合下标的名称。如:index=“myIndex”,则#{myIndex}用来访问当前迭代的下标。
  • item:每次遍历生成的对象
  • open:开始遍历时拼接的串
  • close:结束遍历时两个对象需要拼接的串
  • separator:用来分割 foreach 元素迭代的每个元素;

MyBatis 底层是如何将 resultSet 转换成对象的?

通过反射动态获得实体类的对象
通过反射给对象中的属性赋值

当实体类与表中字段不一致如何映射?

ResultMap标签、别名、开启下划线转驼峰

Mybatis 的 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?不能重复的原因?

不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复
由于 namespace 不是必须的,如果没有配置 namespace,那么 id 不能重复

namespace + id 是作为 Map<String, MappedStatement>的 key 使用的,如果没有 namespace,只剩下 id,这时 id 重复会导致数据互相覆盖。

MyBatis实现一对一、一对多有几种方式 ? collection 关联集合对象的延迟加载?

一对一
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置
association节点配置一对一的类就可以完成;
嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通
过association配置,但另外一个表的查询通过select属性配置。
一对多
有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap里面的
collection节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的 结果的外
键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点
配置。

在 Mybatis 配置文件中,可以配置是否启用延迟加载<setting name=”lazyLoadingEnabled” value=true 或 false>
StudentMapper dao = Session.getMapper();
Student stu = Dao.selectById(id);
System.out.println(stu);

它的原理是使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,发送事先保存好的查询关联对象的 sql,把关联对象查询出来,然后进行赋值;

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

Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以称之为半自动 ORM 映射工具。
全自动 Hibernate :执行效率低 省事 不灵活 add(stu)
半自动:效率高 灵活

说一下MyBatis的SelectKey标签的使用?

SelectKey这个标签主要解决 "添加数据"时 不支持主键自动生成的问题,它可以很随意的设置生成主键的方式
SelectKey需要注意order属性
MySql这类支持自动增长的数据库中,order需要设置为after才会取到正确的值

Oracle这样取序列的情况 order需要设置为before,否则会报错

说一下 SqlsessionfactoryBean 的作用?SqlSessionFactoryBean 和 和SqlSessionFactory 有什么区别?

在 Spring 整合 MyBatis 的时,我们需要配值 SqlSessionFactoryBean 来充当 SqlSessionFactory;
SqlSessionFactoryBean 实现了 Spring 的 FactoryBean接口,实现在和接口的时候,泛型处就是写的
SqlSessionFactory,
所以说实际使用 SqlSessionFactoryBean 时候,实际上在 spring ioc 容器中的 Bean 是 SqlSessionFactory
当把这个 bean 注入到 Spring 中去了以后,IOC 容器中的其他类型就可以拿到 SqlSession 实例了,进而就可执行 SQL 任务了。

附:SqlSessionFactoryBean 的定义

public class SqlSessionFactoryBean implements
FactoryBean<SqlSessionFactory>,InitializingBean,ApplicationListener<ApplicationEvent> {
}

了解 MyBatis 的缓存吗?简单说一下 ?

MyBatis 提供了一级缓存和二级缓存的支持;
一级缓存:

  • 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 SqlSession,当 SqlSession flush 或 close 之后,该 Session
    中的所有 Cache 就将清空;
  • 另外不同的 SqlSession 之间的缓存数据是互相不影响的;
    二级缓存:
  • 耳机缓存开启方式是在 Mapper 的配置文件配置;
  • 与一级缓存其机制相同,不同在于其存储作用域为 Mapper,并且可自定义存储源,如 Ehcache;
  • 二级缓存是跨 SqlSession 的,多个 SqlSession 可以共用二级缓存;
  • 进行了“添加、更新和删除”操作后,会刷新对应的缓存的数据。
    MyBatis 查询顺序:二级缓存→一级缓存→数据库
    MyBatis 主要提供了以下几个刷新和置换策略:
  • LRU:(Least Recently Used),最近最少使用算法,即如果缓存中容量已经满了,会将缓存中最近做少被使用的缓存记录清除
    掉,然后添加新的记录;
  • FIFO:(First in first out),先进先出算法,如果缓存中的容量已经满了,那么会将最先进入缓存中的数据清除掉;
  • Scheduled:指定时间间隔清空算法,该算法会以指定的某一个时间间隔将 Cache 缓存中的数据清空;
  • SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象;
  • WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象。

说一下 MyBatis 的 的 selectKey 标签的使用 ?

selectKey 这个标签主要用于解决“添加数据”时不支持主键自动生成的问题,他可以很随意的设置生成主键的方式;
selectKey 需要注意 order 属性
MySql 这类支持自动增长类型的数据库中,order 需要设置为 after 才会

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值