xml 映射文件中,除了常见的 select、insert、update、delete 标签之外,还有哪些标签?
<resultMap>
、 <parameterMap>
、 <sql>
、 <include>
、 <selectKey>
trim、where、set、foreach、if、choose、when、otherwise、bind
MyBatis接口是否支持方法重载
在Java类中是支持方法重载,但是在MyBatis中是不允许方法重载的。
每个标签<select> <update> <delete> <insert> 最终存储是 namespace+id作为key进行存储,
java文件两个方法名相同,mybatis xml文件对应ID重复会报错。
namespace ---接口全限定名
id ---方法名
namespace 作用和要求
作用:给mapper下所有增删改查分类分组
要求:namespace不能为空,跟接口绑定时,namespace为接口的全限定名
不同的Mapper.xml中ID是否可以允许重复?
不同的namespace 可以允许重复
mapper.xml 如何获取方法参数
- 使用 #{param1} #{param2} #{param3}
- 如果 方法使用注解@param("") XML可以使用指定名字 #{name}
- 如果方法使用对象,XML可以使用对象属性名 #{属性名}
#{} 和 ${} 的区别是什么?
#{}sql参数占位符,${}相当于字符串拼接,可用于动态设置表名、列名
结果填充的几种方式
Auto Mapping:当查询表的列名和实体类的属性名相同时,MyBatis直接按照列名填充到属性名中。
别名方式:如果数据库中表的列名和属性各不相同,可以在投影中通过别名的方式让别名对应上属性名。
resultMap方式:列和属性的映射关系
实体类是否必须有 getter 和 setter 方法?
不是,如果实体类不存在getter和setter 方法,会使用反射直接访问类中属性。
如何实现关联对象查询?
N+1 查询方式:支持延迟加载
多表联合查询方式:不支持延迟加载
联合查询结果集标签:<association>、<collection>
如何实现延迟加载?
延迟加载只出现在N+1查询方式
1.设置全局开关
2.在<association>或<collection>中fetchType控制,lazy表示延迟加载。eager表示立即加载
缓存机制
- 一级缓存默认是开启的,有效范围必须时同一个sqlsession对象,且每次缓存同一个方法中相同的sql语句。当关闭后释放缓存中内容(但是整合了Spring,Mybatis的一级缓存默认就失效了)
- 二级缓存是要手动配置开启的(需要在映射文件添加<cache>标签启动,可以跨SqlSession),当sqlsession 提交或关闭时把一级缓存的内容放到二级缓存。
- 每次查询首先查询二级缓存,没有就查询一级缓存,再没有就查询数据库,查询后结果放入一级缓存。
spring结合mybatis后mybaits一级缓存失效分为两种情况:
- 如果没有开启事务,每一次sql都是用的新的SqlSession,这时mybatis的一级缓存是失效的。
- 如果有事务,同一个事务中相同的查询使用的相同的SqlSessioon,此时一级缓存是生效的。
MyBatis 都有哪些 Executor 执行器?
SimpleExecutor
:开启一个 Statement 对象,用完立刻关闭 Statement 对象。ReuseExecutor
:重复使用 Statement 对象。BatchExecutor:
缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。
四大核心接口
ParameterHandler
、 ResultSetHandler
、 StatementHandler
、 Executor
自定义插件
@Intercepts({@Signature(type = Executor. class, method = "query",
args = {MappedStatement. class, Object. class, RowBounds. class, ResultHandler. class})})
public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation. getTarget(); //被代理对象
Method method = invocation. getMethod(); //代理方法
Object[] args = invocation. getArgs(); //方法参数
// do something . . . . . . 方法拦截前执行代码块
Object result = invocation. proceed();
// do something . . . . . . . 方法拦截后执行代码块
return result;
}
public Object plugin(Object target) {
return Plugin. wrap(target, this);
}
}
MyBatis 使用了哪些设计模式
代理模式(Mapper)、工厂模式(SqlSession)、建造者模式(SqlSessionFactoryBuilder)