环境说明
- JDK 17
- MySQL 8.0.32
- Mybatis 3.5.10
环境准备
导入相关依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
工具类
由于大多数情况下只需要创建一个 SqlSessionFactory(对应一个数据源),因此可以封装一个工具类来获取 sqlSession:
public class MybatisUtil {
//在类加载时就进行创建
private static SqlSessionFactory sqlSessionFactory;
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSession getSession(boolean autoCommit){
return sqlSessionFactory.openSession(autoCommit);
}
}
配置文件
MyBatis 配置文件顶层结构:
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)可以为实体类添加@Alias注解来指定别名
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)可以配置多环境,每个 SqlSessionFactory 实例只能选择一种环境
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
事务操作
注意在获取SqlSession
关闭自动提交来开启事务模式:
try(SqlSession sqlSession = SqlSessionUtil.openSession(false)){
Student student = new Student();
student.setName("agagGb");
student.setSex("女");
sqlSession.insert("insertStudent", student);
// sqlSession.rollback(); // 回滚事务
sqlSession.commit(); // 提交事务
}
缓存机制
MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。
Mybatis存在一级缓存和二级缓存,默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存(一级缓存无法关闭,只能调整)
try (SqlSession sqlSession = MybatisUtil.getSession(true)){
TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
Student student1 = testMapper.getStudentBySid(1);
Student student2 = testMapper.getStudentBySid(1);
System.out.println(student1 == student2);
}
两次得到的是同一个Student对象,即第二次查询并没有重新去构造对象,而是直接得到之前创建好的对象(一级缓存在进行DML操作或会话结束后,缓存会失效)。
开启二级缓存(在映射器XML文件中):
<cache/>
二级缓存是Mapper级别的,当一个会话失效时,它的缓存依然会存在于二级缓存中,因此如果再次创建一个新的会话会直接使用之前的缓存。
public static void main(String[] args) {
Student student;
try (SqlSession sqlSession = MybatisUtil.getSession(true)){
TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
student = testMapper.getStudentBySid(1);
}
try (SqlSession sqlSession2 = MybatisUtil.getSession(true)){
TestMapper testMapper2 = sqlSession2.getMapper(TestMapper.class);
Student student2 = testMapper2.getStudentBySid(1);
System.out.println(student2 == student);
}
}
开启二级缓存后两者得到的是同一个结果。
如果不希望某个方法开启缓存,将useCache属性设置为false。也可以使用flushCache="false"在每次执行后都清空缓存,这样在执行DML操作之后就不会清空缓存。:
<select id="getStudentBySid" resultType="Student" useCache="false">
select * from student where sid = #{sid}
</select>
注意:Spring与MyBatis整合时,MyBatis的一级缓存在没有事务存在的时候失效。SpringBoot中默认帮我们全局开启了二级缓存,如果想要使用二级缓存还需要在mapper上注明。
注解方式开启二级缓存
@CacheNamespace(blocking = true)
public interface StudentMapper {
...
日志系统
使用标准输出将日志信息打印到控制台(日志默认是关闭的)
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>