1、不同类型的sql,他们的执行流程是什么?
就以select为例讲解:
读取mybatis-config作为输入流,根据输入流创建SqlSessionManager,将dao的方法全限定名查询进行查询,此时会创建代理,委托给DefaultSqlSession,SqlSession是用户层的接口,主要提供给客户端使用,而真正调用执行sql的是Executor,通过方法的权限定名从解析成的配置对象configuration获取到相应的MapperStatement,在创建的代理的过程中已经创建了Executor,此时执行器接受MapperStatement执行查询工作,生成相应的cacheKey,首先从缓存里获取,能获取则直接返回,不能获取从数据拿,这其实就是一个简单的执行过程。借鉴图 来源:https://my.oschina.net/zudajun/blog/670373
2、mapper文件的是如何解析的?都被解析成什么数据了?
通过对xml的api进行了一次封装,不同的节点解析成不同的对象,有ParamterMapp,ResultMapp,MappedStatement,BoundSql等,最后都存放在configuration。
3、一级,二级缓存的执行原理是什么?
一级缓存是自动开启,使用的策略是永久缓存策略,是sqlSession级别的
二级缓存是SqlSessionFactory级别的,开启方式 <cache></cache>标签,会使用新的缓存,配置的属性将使用装饰器模式进行装饰,在select语句级别使用的useCache=true,将使当前的mapperstatement结果进行缓存,flushCache=true将影响一级和二级缓存
4、整体的架构又是什么?
上两幅图:来源:https://www.cnblogs.com/mengheng/p/3739610.html
源码包下的:来源:https://www.cnblogs.com/mengheng/p/3739610.html
5、插件的工作原理是什么?如何新增自己的插件?
有4处触发拦截器:
1)、创建参数处理器
2)、创建结果集处理器
3)、创建statement处理器
4)、创建执行器
新增自己的插件:
1)、实现Interceptor接口,并打标签@Interceptor属性是一个@Signature数组,里面有执行类型,方法签名,参数了类型
其中Plugin.wrap(target, this)是生成目标对象的代理。
2)、在配置文件配置插件标签:
6、$与#的根本区别是什么?
#:会在select|insert|delect|update标签解析是替换成?,为preparestament执行做准备,对于可以重复使用的preparestament直接利用,不会新建,提升效率。
$:会直接跟字段进行拼接,并可能带来sql注入等问题。
7、mybatis不支持的数据类型,我们如何定义我们自己的类型解析处理器?
实现抽象类:BaseTypeHandler
8、动态sql的是如何做到动态的?都有哪些标签可以视为动态的?
SqlSourceBuilder创建并解析相应的sqlSource,然后从sqlSource里获取BoundSql。
9、如何实现批量查询的?
通过BatchExecutor执行器,不断的将statement加入,最后统一执行。
10、结果集是如何映射的?
结果集映射无非是两种:
1)、通过resultMap进行属性和字段的映射
2)、通过别名进行映射
11、mybatis接口中的方法能否重载?
答案:不能。
从源码的角度来看,生成代理的时候,通过类的全限定名+“.”+方法名,从Configuration对象中获取MappedStatement。如果存在多个则会出现异常。
12、不同namespace空间下的id,能否相同呢?
答案:可以相同,因为在mybatis里是通过namespace+id保存的,如果仅使用id去查询将抛出异常,或者如果在同一命名空间下存在相同的id,将抛出异常,如果没有配置namespace,将要保证全局id是唯一的,否则出现异常。
13、结果集处理:可以借鉴一个这个图 来源:https://my.oschina.net/zudajun/blog/671075