MyBatis事务、延迟加载、缓存、注解
半塘 2024/1/12 MyBatis框架
# 1、事务
MyBatis是一个独立的持久层框架,它本身不提供事务管理的功能。但是,MyBatis可以与Spring框架集成,利用Spring的事务管理功能来管理数据库事务。
# 1.1、事务原理
事务我们在Spring章节中已经讲过了,可以参考:Spring事务详解
# 1.2、MyBatis开启事务
- 增加Spring事务依赖
<!-- spring事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
1
2
3
4
5
6
2
3
4
5
6
- MyBatisConfig配置将数据源给Spring事务管理器管理
@Bean
public TransactionManager getTrans(DataSource dataSource){
DataSourceTransactionManager trans = new DataSourceTransactionManager();
//设置数据源
trans.setDataSource(dataSource);
return trans;
}
1
2
3
4
5
6
7
2
3
4
5
6
7
- 使用XML方式配置,效果同上
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--连接数据库这里读取的是配置文件-->
<context:property-placeholder location="jdbc.properties"/>
<!--连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<!--事务整合-->
<!-- 配置事务管理器 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--事务属性-->
<tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<tx:method name="Query" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 2、延迟加载
MyBatis的延迟加载是指在需要用到数据的时候进行加载,不需要用到数据就不进行加载。
延迟加载的原理
- 当查询主记录时,相关的关联记录并不会立即加载。
- 当访问这些关联记录时,MyBatis 会触发加载。
MyBatis开启延迟加载
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis核心配置文件-->
<configuration>
<settings>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 3、缓存
# 3.1、缓存特性
- MyBatis缓存是将查询的数据存在于内存中的临时数据
- 减少和数据库交互的次数,提高执行力效率
- 适用于缓存的数据:经常查询的数据、不经常改变的数据、数据的正确与否对最终结果影响不大的
# 3.2、一级缓存
- 一级缓存是MyBatis中SqlSession对象的缓存。
- 当我们执行查询之后,查询的结果会同时存入得到SqlSession大为我们提供的一块区域中。
- 该区域是一个Map。
- 当我们再次查询同样的数据,MyBatis会先去SqlSession中查询是否有,有的话直接拿出来用。
- SqlSession销毁时,一级缓存也就消失了。
- 内存地址时一致的 那么就说明了第二次查询使用的是缓存。
- 可通过sqlSession.clearCache()清空一级缓存。
- MyBatis的一级缓存当调用SqlSession的修改,添加,删除,commit(),close() 等方法时就会自动清空缓存。
- MyBatis 的一级缓存是默认开启的。
# 3.3、二级缓存
- 二级缓存是MyBatis中SqlSessionFactory对象的缓存(工厂的缓存)。
- 同一个SqlSessionFactory创建出来的多个SqlSession对象,共享同一个二级缓存
- 二级缓存中存放的数据,而不是对象,因此使用 == 比较对象的内存的地址是false
开启二级缓存有三种情况
- 全局开启,通过核心配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis核心配置文件-->
<configuration>
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 当前的映射文件支持二级缓存
在UserMapper.xml中加入<cache></cache>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace-绑定一个对应dao/mapper接口-->
<mapper namespace="com.xygalaxy.mapper.UserMapper">
<!--当前映射文件开启二级缓存-->
<cache></cache>
</mapper>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 当前的SQL操作支持缓存
<select id="getUserList" resultType="com.xygalaxy.pojo.UserPO" useCache="true" flushCache="true">
select * from user
</select>
1
2
3
2
3
- useCache="true"表示当前查询开启二级缓存
- flushCache的默认值是false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。
# 4、注解
对于不复杂的SQL时,创建Mapper.xml映射文件显得很麻烦臃肿,所以MyBatis还提供了注解方式。在前面的章节我们也有用过不少。
# 4.1、@Select
@Mapper
@CacheNamespace
public interface UserMapper {
@Select("select * from user where username like CONCAT('%', #{arg0}, '%') and email like CONCAT('%', #{arg1}, '%')")
List<UserPO> selectUserMultiparameter(String name,String email);
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 4.2、@Insert
@Insert("insert into user(id,username,password,email) values(#{id},#{username},#{password},#{email})")
@SelectKey(statement="select if(max(id) is null, 1, max(id) +1) as id from user", keyProperty="id", before=false, resultType=int.class)
int saveUser(UserPO userPO);
1
2
3
2
3
# 4.3、@Update
@Update({"<script>",
"update user",
" <set>",
" <if test='username != null'>username=#{username},</if>",
" <if test='password != null'>password=#{password},</if>",
" <if test='email != null'>email=#{email},</if>",
" </set>",
"where id=#{id}",
"</script>"})
void updateUserById(UserPO userPO);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 4.4、@Delete
@Delete("delete from user where id = #{id}")
int deleteUserById(int id);
1
2
2
# 4.4、@Results
当结果和PO对象不一致时,需要使用@Results注解来映射它们。
@Select("select * from user")
/*用了Results注解的id属性后,在别的地方 直接用id名即可
* 例如 @ResultMap(value={userMap})
**/
@Results(id="userMap",value = {
// 如果id为true表示 该行设置的是主键
@Result(id = true,property = "id",column = "id"),
@Result(property = "name",column = "name"),
@Result(property = "password",column = "password")
})
List<UserPO> selectAllUser();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4.5、@CacheNamespace
@CacheNamespace 用于为 MyBatis 的 Mapper 接口启用缓存功能。通过使用这个注解,你可以将 MyBatis 的查询结果缓存起来,从而提高应用程序的性能。
@CacheNamespace
public interface UserMapper {
}
1
2
3
4
2
3
4
# 4.6、@Mapper
@Mapper 是 MyBatis-Spring 集成中的一个注解,用于将接口声明为 MyBatis 的 Mapper。通过使用这个注解,你可以将 MyBatis 的映射文件和接口绑定在一起,并自动将 SQL 语句映射到接口的方法上。
@Mapper
public interface UserMapper {
}
1
2
3
4
2
3
4