1.xml映射文件都会写一个Dao接口与之对应,Dao工作原理是什么,Dao接口里的方法参数不同时,方法能重载么
Dao接口即Mapper接口,接口的全限名,映射文件中的namespace的值,
接口的方法名就是映射文件中Mapper的Statement的id值
接口方法内的参数就是传递给sql的参数
调用接口时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement,每个标签(select,insert…)都会被解析为一个MapperStatement对象。
Mapper接口里的方法是不能重载的,因为使用全限名+方法名的保存和寻找策略。
工作原理:JDK动态代理,Mybatis运行时会使用JDK 动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MapperStatement所代表的的sql,然而将sql执行结果返回。
2. Mybatis如何分页,分页插件原理是什么
使用RowBounds对象进行分页,针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成屋里分页功能,也有使用分页插件来完成物理分页。
分页插件原理:使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
3.mybatis的xml映射文件中,不同的xml映射文件,id是否可以重复?
不同的xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复。
原因:namespace+ id是作为Map
4.mybatis是否支持延迟加载,原理?
mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指一对一,collection指一对多查询,在配置文件中,lazyLoadingEnabled=true|false,是否启用延迟加载
原理:使用cglib创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName,拦截器invoke方法发现a.getB是null值,name会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB.getName方法的调用。
5.mybatis一级,二级缓存
一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session flush或close后,该Session中的所有Cache就将清空,默认打开一级缓存。
二级缓存与一级缓存机制相同,默认PerpetualCache,HashMap存储,不同为:存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcache,默认不打开二级缓存,要开启二级缓存,使用二级缓存属性累的需要实现Serializable序列化接口(保存对象的状态),可在它的映射文件中配置
对于缓存数据更新机制,当某个作用域(一级缓存Session/二级缓存Namespaces)的进行CUD操作后,默认该作用域下所有select的缓存将被clear。
mybatis中的一级缓存和二级缓存
6.mybatis插件的运行原理,如何编写?
mybatis仅可以编写针对ParameterHandler,ResultSetHandler,StatementHandler,executor4种接口的插件,mybatis使用jdk动态代理,为需要拦截的接口生成代理对象实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke方法,只会拦截指定需要拦截的方法
编写插件:实现Mybatis的interceptor接口并复写intercept方法,然后在给插件编写注解,指定要拦截哪个接口的哪些方法即可,需在配置文件配置编写的插件。
7.mybatis有哪些?
① SimpleExecutor:每执行一次update或select,就开启一个statement对象,用完立刻关闭statement对象
②ReuseExecutor:执行update或select,以sql作为key查找statement对象,存在就使用,不存在就创建,用完后,不关闭statement对象,而是放置于map
③BatchExecutor:完成批处理