mybatis 问答
1、什么是mybatis
mybatis是半orm(对象关系映射)框架
1)内部封装了jdbc,不用再手动加载驱动,创建连接,创建statement
2)注解或xml形式,pojo映射成数据库记录,不用手动设置参数
将要执行的statement配置起来,通过java对象和statement的sql的动态参数,构成可以执行的sql,再将结果映射成java对象
(执行sql到result返回的过程)
2、mybatis和hibernate区别
mybatis不是完全的orm框架,还需要开发者自己写sql
hibernate对象关系映射较好
3、#{}和${}的区别
#{}:预编译,mybatis会将其替换成?,再用preparedStatement的set进行赋值,可以防止sql注入
${}:替换成变量的值
4、实体类的属性名 和表的字段名不一致时,怎么办
1)select aaa id from table; 查询时取字段别名
2)用resultmap 进行映射
5、Mapper的工作原理,方法参数不同时,能否重载
dao接口就是mapper接口,mapper没有实现类,接口限定名+方法名 拼出的key值,可唯一定位到 MappedStatement
在mybatis中,<select><insert><delete><update>都会解析成一个MappedStatement 对象
举例:com.mybatis3.mappers.StudentDao.findStudentById,
可以唯一找到 namespace 为com.mybatis3.mappers.StudentDao 下面 id 为findStudentById 的 MappedStatement。
Mapper里面的方法,不能重载,因为用的是 接口限定名+方法 的保存和查找策略
工作原理是jdk动态代理,为mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MappedStatement 代表的sql,再返回结果
1 private static class DefaultMethodInvoker implements MapperMethodInvoker { 2 private final MethodHandle methodHandle; 3 4 public DefaultMethodInvoker(MethodHandle methodHandle) { 5 super(); 6 this.methodHandle = methodHandle; 7 } 8 9 @Override 10 public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable { 11 return methodHandle.bindTo(proxy).invokeWithArguments(args); 12 } 13 }
6、如何分页,分页插件的原理
RowBounds进行分页,不过这是对resultset进行内存分页,不是物理分页
可以在sql里面写带有物理分页的参数;或者用分页插件
插件的拦截方法里面 拦截要执行的sql,根据dialect 增加分页语句和参数
7、获取自动生成的key
<insert id="insertname" usegeneratedkeys="true" keyproperty="id"> insert into names (name) values (#{name}) </insert> name name = new name(); name.setname("fred"); int rows = mapper.insertname(name); // 完成后,id 已经被设置到对象中 system.out.println("rows inserted = " + rows); system.out.println("generated key value = " + name.getid());
8、用了哪几个动态代理
mapper用了jdk动态代理,延迟加载用了 cglib代理
9、延迟加载原理
mybatis只是对关联对象进行延迟加载,对主加载对象还是直接查询的
直接加载:lazyLoadingEnabled=false
侵入式延迟:lazyLoadingEnabled=true,aggressiveLazyLoading=true
深度延迟:lazyLoadingEnabled=true,aggressiveLazyLoading=false 执行到关联对象详情时,才查询
后面2个延迟的 区别是啥??
cglib创建目标代理对象(一般映射的是javabean,没有接口,所以不能用jdk动态代理),等到调用方式时,才执行语句。
10、一二级缓存
一级缓存:hashmap, 作用域 session
二级缓存:作用域 namespace
11、接口绑定,实现方式
任意定义接口,方法和sql绑定在一起
两种方式:
1)注解 @select @update
2)xml:复杂sql可以用这个,要指定xml文件里面的namespace是 接口的全路径名
12、
参考地址:
http://gitbook.chenqiong.net/part1/4/3/1.html
备注:公众号清汤袭人能找到我,那是随笔的地方