MyBatis 中的 SqlSession 是执行数据库操作的核心对象,它代表了一次数据库会话。通过 SqlSession,开发者可以执行 SQL 命令、获取 Mapper 接口、管理事务等。
1. SqlSession 的作用
- 执行 SQL:直接运行 SQL 语句(如
select、insert、update、delete)。 - 获取 Mapper:通过
getMapper()方法获取 Mapper 接口的代理对象,简化数据库操作。 - 事务管理:支持手动提交(
commit())和回滚(rollback()),或通过配置自动提交。 - 配置管理:关联
Configuration对象,访问 MyBatis 全局配置。
2. SqlSession 的生命周期
-
非线程安全:每个线程应使用独立的 SqlSession 实例,避免多线程冲突。
-
作用域建议:
- 方法级别:在方法内部创建,使用后及时关闭(推荐)。
- 请求级别:在 Web 应用中,每个 HTTP 请求创建一个 SqlSession,请求结束后关闭。
- 会话级别:长期存在的场景(如桌面应用),需手动管理事务和关闭。
3. 获取 SqlSession
通过 SqlSessionFactory 创建:
SqlSessionFactory sqlSessionFactory = ...; // 通常从配置文件中构建
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
// 执行数据库操作
} // 自动关闭,避免资源泄漏
4. 常用方法
4.1 执行 SQL
selectOne(String statement, Object parameter)执行返回单个结果的 SQL,若结果不唯一会抛出异常。selectList(String statement, Object parameter)执行返回列表的 SQL。selectMap(String statement, Object parameter, String mapKey)将结果集转换为 Map,指定 Map 的键字段。insert(String statement, Object parameter)执行插入操作,返回影响行数。update(String statement, Object parameter)执行更新操作。delete(String statement, Object parameter)执行删除操作。
4.2 获取 Mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectById(1);
4.3 事务控制
-
手动提交:
sqlSession.commit(); // 提交事务 sqlSession.rollback(); // 回滚事务 -
自动提交:
java复制代码 SqlSession sqlSession = sqlSessionFactory.openSession(true); // autoCommit=true
5. 最佳实践
-
资源管理:使用
try-with-resources(Java 7+)自动关闭 SqlSession:try (SqlSession sqlSession = sqlSessionFactory.openSession()) { // 操作数据库 sqlSession.commit(); } // 自动关闭 -
避免长事务:长时间未提交的 SqlSession 会占用数据库连接,需及时提交或回滚。
-
与 Spring 集成:在 Spring 中,通过
SqlSessionTemplate自动管理 SqlSession 生命周期,无需手动关闭。
6. 底层原理
- 动态代理:
getMapper()通过 JDK 动态代理生成 Mapper 接口的实现类,将方法调用转换为 SQL 执行。 - Executor:SqlSession 内部依赖
Executor对象(如SimpleExecutor、ReuseExecutor)执行 SQL。 - Configuration:SqlSession 持有
Configuration对象,存储 MyBatis 全局配置(如映射文件、类型处理器)。
7. 常见问题
- Q:SqlSession 线程安全吗? A:非线程安全,需在多线程环境下为每个线程创建独立实例。
- Q:未关闭 SqlSession 会导致什么问题? A:数据库连接泄漏,最终可能耗尽连接池资源。
- Q:如何避免 N+1 查询问题? A:通过懒加载(
lazyLoadingEnabled)或联表查询优化,合理使用selectList批量查询。
总结
SqlSession 是 MyBatis 与数据库交互的桥梁,合理使用其方法和生命周期管理,能确保数据访问层的高效性和安全性。在集成框架(如 Spring)中,通常无需手动管理 SqlSession,但理解其原理对优化性能和排查问题至关重要。