咕泡-MyBatis 实用篇作业

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1. Mapper在spring管理下其实是单例,为什么可以是一个单例?

  • 首先,mapper 内部不包含 成员字段,无状态单例是安全的
  • 另外,一直存在不用每次调用都new 一个新实例

2. MyBatis在Spring集成下没有mapper的xml文件会不会报错,为什么?

  • 不会报错,因为支持 xml 和 annotation 两种

3. TypeHandler手写

  • 继承自 BaseTypeHandler
  • public class ExampleTypeHandler extends BaseTypeHandler
  • 配置到configuration 里面

d8d7265116e3e4a88d0e63bf081141c919d.jpg

  • 具体使用

咕泡-MyBatis 实用篇作业_第1张图片

  • 比如 String 和Date 之间的互转

咕泡-MyBatis 实用篇作业_第2张图片

4. 手写Plugin,多个interceptor到底谁先执行?顺序由谁决定的?

  • 允许使用插件拦截的接口

咕泡-MyBatis 实用篇作业_第3张图片

  • 根据签名判断其拦截点,根据jdbc 执行顺序,执行到相应的点,进行执行

570071af2387493ed6985e3a6cf3893e7b8.jpg

  • 配置到 configuration 里面

咕泡-MyBatis 实用篇作业_第4张图片

1.怎么验证一级缓存的存在?

  • 相同的查询,连续查询两遍,记录查询用时,会发现第二次快得多
  • update、 insert、delete 等语句会触发清除缓存
  • 一级缓存默认开启,SqlSession 级别的
  • 二级缓存默认关闭,SqlSessionFactory 级别的 

二级缓存是需要配置来开启的:

801e13c5489bb01ca9ad706038d846acd39.jpg

  • 所以,一级缓存,在存在俩sqlsession 时,可能存在脏数据的情况
    •  比如,sqlsessionA 两次相同查询t 表中间,sqlsessionB 更新了t表数据,第二次查询的数据就是可能已被修改的脏数据

2.验证N+1问题

  • 所谓级联查询(嵌套查询)

咕泡-MyBatis 实用篇作业_第5张图片

  • 外层查询的一条结果数据,由内层查询获得
  • 外层查询一次,获得结果数N ,就要进行N 次内层查询(官方不鼓励使用,这样产生大量1+N次查询)

由于1+N 问题的性能损耗,可以考虑配合使用 延时加载

咕泡-MyBatis 实用篇作业_第6张图片

  • 配置到 configuration 里面

咕泡-MyBatis 实用篇作业_第7张图片

1、TestMapper 作者为什么要设计这样的形式来做?为什么不是一个class而是一个interface?

  • 首先使用 interface 接口已经可以满足,根据全限定名+方法名找到对应的SQL语句,然后MapperProxy代理实现具体的执行
  • 所有的执行套路都是一样的,xml文件里面配置也很清楚了,不需要class
  • 保留interface 的原因是用户使用方便

2.org.apache.ibatis.executor.BaseExecutor#queryFromDatabase 322行这行代码的意义

  • 322行这行代码的意义是声明一个占位符,当发送一次查询数据的请求时,设置该占位符 告诉其他请求 正在查询数据库,请其他请求先阻塞或休眠。
  • 当这次请求查询到数据之后,将真正的数据放到占位符的位置,缓存数据。如果其他请求与该次请求查询的数据时一样的,直接从缓存中拿数据减少了查询请求对数据库的压力

咕泡-MyBatis 实用篇作业_第8张图片

3.MyBatis的plugin实现机制

  • interceptorChain.pluginAll(executor) 在configuration 内部注册所有的 plugin

咕泡-MyBatis 实用篇作业_第9张图片

  • 本质就是getSignatureMap 方法,扫描所有注解,对配置的Signature 方法进行 动态代理
     

咕泡-MyBatis 实用篇作业_第10张图片

  • 代理类就是public class Plugin implements InvocationHandler
  • 执行Plugin 的invoke 会判断该方法是否被代理(signatureMap 里面有没有)

咕泡-MyBatis 实用篇作业_第11张图片

  • 如果有执行 intercept 方法

咕泡-MyBatis 实用篇作业_第12张图片

  • 该方法最后一行执行的proceed 方法,其实就是该方法的invoke 执行

6a8a2fa73c784edc2aa33b7de565f73b1b0.jpg

4.lazy loading 是怎么做到的?

  • 懒加载在级联查询时用到了,SimpleStatementHandler 里面query结果

咕泡-MyBatis 实用篇作业_第13张图片

  • DefaultResultSetHandler 处理结果
  • handleResultSets -->handleResultSets -->...getRowValue-->createResultObject 

咕泡-MyBatis 实用篇作业_第14张图片

  • 如果有嵌套查询且开启了懒加载 那么会使用代理工厂来处理(代理工厂类型cglib或javasissit类型(默认))
  • 针对某一个属性,当执行

咕泡-MyBatis 实用篇作业_第15张图片

  • protected Set lazyLoadTriggerMethods = new HashSet(Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" }));
  • 在嵌套查询的时候 get/set 方法会触发 ResultLoaderMap LoadPair load() 方法去查询(我看源代码的理解),我找到了触发函数lazyLoadTriggerMethods 里面没有get/is  依赖的是PropertyNamer.isGetter(methodName)

转载于:https://my.oschina.net/u/3847203/blog/2088288

你可能感兴趣的:(咕泡-MyBatis 实用篇作业)