参考JavaGuide面试突击里面的mybatis部分
目录
1、mybatis原理 / 核心流程
2、Dao接口的工作原理是什么?Dao 接口里的方法,参数不同时能重载吗?
3、Mybatis是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?
4、Mybatis 能执行⼀对⼀、⼀对多的关联查询吗?都有哪些实现方式,以及它们之间的区别。
5、mybatis延迟加载怎么做的?原理是什么?
6、Mybatis 都有哪些 Executor 执行器?它们之间的区别是什么?
7、Mybatis 映射文件中,如果 A 标签通过 include 引用了 B 标签的内容,请问,B 标签能否定义在 A 标签的后面,还是说必须定义在 A 标签的前面?
1、mybatis原理 / 核心流程
- mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件中构建出SqlSessionFactory。然后,SqlSessionFactory的实例直接开启一个SqlSession。再通过SqlSession实例获得Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。
①接口的全限名,就是映射文件中的 namespace的值。接口的方法名,就是映射文件中 MappedStatement 的 id 值。在 Mybatis中,每⼀个
delete from mmall_order where id = #{id,jdbcType=INTEGER}
②不能重载的,因为是全限名+方法名的保存和寻找策略。
Dao 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理 proxy 对象,代理对象 proxy 会拦截接口方法,转而执行 MappedStatement 所代表的 sql,然后将 sql 执行结果返回。
3、Mybatis是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置namespace,那么 id 不能重复;毕竟 namespace 不是必须的,只是最佳实践而已。原因就是 namespace+id 是作为 Map
的 key 使用的,如果没有namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,⾃然 id 就可以重复,namespace 不同,namespace+id ⾃然也就不同。
第⼀种是使用 一对一:比如订单表关联用户表,查出哪个订单的信息及对应用户。 这种情况下我们需要定义出来一个pojo作为返回的resulttype。 一对多:比如用户表关联订单表,查出哪个用户的信息及对应用户的一些订单。 xml: 这种我们也要定义一个pojo来接收返回对象,是一个包含用户相关字段以及一个List 同时用resultMap配置好对应字段的关系,把一对多的订单信息配置在collection里。 如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。 所以延迟加载即先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。 原理: Mybatis 仅支持 association 关联对象(⼀对⼀查询)和 collection 关联集合对象(⼀对多查询)的延迟加载。在 Mybatis 配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false 。 它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName() ,拦截器 invoke() 方法发现 a.getB() 是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName() 方法的调用。这就是延迟加载的基本原理。 Mybatis 有三种基本的 Executor 执行器, SimpleExecutor 、 ReuseExecutor 、 BatchExecutor 。可以在配置文件中指定。 作用范围:Executor 的这些特点,都严格限制在 SqlSession ⽣命周期范围内。 虽然 Mybatis 解析 Xml 映射⽂件是按照顺序解析的,但是,被引⽤的 B 标签依然可以定义在任何地⽅,Mybatis 都可以正确识别。 欢迎分享,转载请注明来源:内存溢出//sql
SimpleExecutor :每执行⼀次 update 或 select,就开启⼀个 Statement 对象,用完立刻关闭
Statement 对象。
ReuseExecutor :执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,⽽是放置于 Map
BatchExecutor :执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都添加到批处理中(addBatch()),等待统⼀执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐⼀行 executeBatch()批处理。与JDBC 批处理相同。
原理是,Mybatis 解析 A 标签,发现 A 标签引用了 B 标签,但是 B 标签尚未解析到,尚不存在,此时,Mybatis 会将 A 标签标记为未解析状态,然后继续解析余下的标签,包含 B 标签,待所有标签解析完毕,Mybatis 会重新解析那些被标记为未解析的标签,此时再解析 A 标签时,B标签已经存在,A 标签也就可以正常解析完成了。
评论列表(0条)