MyBatis
缓存
一级缓存
SqlSession级别,同一会话中多次重复的查询会使用以及缓存,默认开启
二级缓存
Mappr级别,需要在Mappr显性的开启,不同会话使用同样的Sql会查询二级缓存
Mapper.XML文件中常用标签
- sql脚本相关
select、insert、update、delete - 动态sql相关
指定sql的基本数据类型:<resultMap>、 <parameterMap>、 <sql>、 <include>、 <selectKey>
动态组件sql:trim|where|set|foreach|if|choose|when|otherwise|bind
针对<sql>标签的脚本可以使用<include>标签引入
Dao的实现原理,方式是否可以重载
通过xml文件中的namspace与dao接口进行管理,xml中使用sql语句段的id与dao接口中的方法名进行绑定;当dao接口中的方法名重复,但是参数不一样时,可以重载使用,实例:
/**
* Mapper接口里面方法重载
*/
public interface StuMapper {
List<Student> getAllStu();
List<Student> getAllStu(@Param("id") Integer id);
}
//xml文件
<select id="getAllStu" resultType="com.pojo.Student">
select * from student
<where>
<if test="id != null">
id = #{id}
</if>
</where>
</select>
Mybatis的插件(拦截器)使用
MyBatis 仅可以编写针对 ParameterHandler、 ResultSetHandler、 StatementHandler、 Executor 这 4 种接口的插件,MyBatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke() 方法,当然,只会拦截那些你指定需要拦截的方法。
使用过程:
- 定义拦截器
@Intercepts({
@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class)
})
public class BaseDataInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
return invokeSetParameter(invocation);
}
private Object invokeSetParameter(Invocation invocation) throws Exception {
return null;
}
@Override
public Object plugin(Object target) {
return Interceptor.super.plugin(target);
}
@Override
public void setProperties(Properties properties) {
properties.put("connectionInitSqls", "set names 'utf8mb4'");
Interceptor.super.setProperties(properties);
}
}
- 在Mybatis配置文件中的sqlSession部分添加拦截器
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(
// 设置mybatis的xml所在位置,这里使用mybatis注解方式,没有配置xml文件
new PathMatchingResourcePatternResolver().getResources("classpath*:com/zwj/learn/springcloud/**/dao/*.xml"));
// 注册typehandler,供全局使用
bean.setTypeHandlers(new UuidTypeHandler());
BaseDataInterceptor sqlInterceptor = new BaseDataInterceptor();
//创建属性值
//将属性值设置到插件中
Properties properties = new Properties();
sqlInterceptor.setProperties(new Properties());
bean.setPlugins(sqlInterceptor);
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
// 配置SQL打印日志
configuration.setLogImpl(StdOutImpl.class);
//开启驼峰映射配置
configuration.setMapUnderscoreToCamelCase(true);
bean.setConfiguration(configuration);
return bean.getObject();
}
<resultMap>与<resultType>的区别
resultMap需要自己提供映射配置,resultType会自动根据指定的数据类型做自动封装。
<resultMap>实现一对一和一对多映射
- 一对一
<resultMap id="userResultMap" type="com.example.User">
<id column="id" property="id" />
<result column="username" property="username" />
<result column="password" property="password" />
</resultMap>
<select id="selectUserById" resultMap="userResultMap" parameterType="int">
SELECT * FROM user WHERE id = #{id}
</select>
- 一对多
<resultMap id="userResultMap" type="com.example.User">
<id column="id" property="id" />
<result column="username" property="username" />
<result column="password" property="password" />
<collection property="orders" ofType="com.example.Order">
<result column="order_id" property="id" />
<result column="order_name" property="name" />
</collection>
</resultMap>
<select id="selectUserWithOrdersById" resultMap="userResultMap" parameterType="int">
SELECT u.*, o.*
FROM user u
LEFT JOIN order o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
批量插入
xml中使用foreach标签
<insert id="insertBatch" parameterType="list">
INSERT INTO your_table (column1, column2, ...)
VALUES
<foreach collection="list" item="item" index="index" separator=",">
(#{item.property1}, #{item.property2}, ...)
</foreach>
</insert>
Mybatis执行器Executor
- SimpleExecutor:
每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。 - ReuseExecutor:
执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map<String, Statement>内,供下一次使用。简言之,就是重复使用 Statement 对象。 - BatchExecutor:
执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。
使用方式:
在Mybatis配置中的sqlSession部分添加执行器。