一、原始代码与问题分析
原始获取 SqlSessionFactory 代码
java
运行
// 2.1 获取SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
存在的两个核心问题
- 代码重复:每次获取工厂都要写这三段代码,冗余且难维护
- 工厂重复创建 :
SqlSessionFactory是重量级对象,每次创建都要解析 XML 配置、构建环境,频繁创建会严重影响性能
二、优化方案:MyBatis 工具类
通过静态代码块 + 工具类,实现工厂的单例创建与全局复用:
java
运行
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtils {
// 1. 静态变量,保存唯一的SqlSessionFactory实例
private static SqlSessionFactory sqlSessionFactory;
// 2. 静态代码块:类加载时执行,仅执行一次
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new RuntimeException("MyBatis配置文件加载失败", e);
}
}
// 3. 对外提供获取SqlSession的方法
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
// 重载方法,支持自动提交事务
public static SqlSession getSqlSession(boolean autoCommit) {
return sqlSessionFactory.openSession(autoCommit);
}
}
三、优化后的使用方式
java
运行
// 业务代码中直接调用工具类获取SqlSession
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectAll();
sqlSession.close();
四、优化的核心优势
表格
| 优化点 | 说明 |
|---|---|
| 代码复用 | 所有业务代码统一调用工具类,无需重复编写工厂创建逻辑 |
| 性能提升 | SqlSessionFactory 仅在类加载时创建一次,避免重复解析配置文件 |
| 异常统一处理 | 配置文件加载异常在工具类中统一抛出,业务代码无需重复处理 |
| 简化调用 | 直接通过工具类获取 SqlSession,代码更简洁 |
补充说明
SqlSessionFactory本身是线程安全的,因此可以全局单例复用SqlSession是线程不安全的,必须每次请求 / 业务操作时新建,用完及时关闭- 静态代码块的特性保证了工厂只会被创建一次,且在类加载时完成初始化