MyBatis SqlSession 的作用,以及如何使用 SqlSession 执行 SQL 语句

server/2025/3/13 12:25:14/

SqlSession 是 MyBatis 中非常重要的一个接口,它代表了与数据库的一次会话(session)。 可以将 SqlSession 理解为 JDBC 中的 Connection 对象加上一系列操作数据库的方法。 它负责:

SqlSession 的作用:

  1. 执行 SQL 语句: SqlSession 提供了执行 SQL 语句的方法,包括 selectinsertupdatedelete 操作。
  2. 获取 Mapper 接口的实例: SqlSession 可以获取 Mapper 接口的代理对象,从而通过 Mapper 接口来执行 SQL 语句 (这是推荐的方式)。
  3. 管理事务: SqlSession 可以控制事务的提交(commit)和回滚(rollback)。
  4. 维护数据库连接: SqlSession 内部持有数据库连接(Connection),并在会话结束时负责关闭连接(除非使用了外部事务管理器,如 Spring 的事务管理)。
  5. 缓存管理(一级缓存): SqlSession 拥有一个本地缓存(一级缓存),可以缓存查询结果,减少数据库访问次数(默认开启)。

如何使用 SqlSession 执行 SQL 语句:

SqlSession 的使用通常遵循以下步骤:

  1. 获取 SqlSessionFactory: SqlSessionFactorySqlSession 的工厂,负责创建 SqlSession 对象。通常情况下,SqlSessionFactory 在应用程序的生命周期内只需要创建一个实例(单例模式)。 SqlSessionFactory 可以通过 XML 配置文件或 Java 代码来创建。

  2. 通过 SqlSessionFactory 打开 SqlSession: 使用 SqlSessionFactoryopenSession() 方法打开一个新的 SqlSession

  3. 执行 SQL 语句:

    • 直接使用 SqlSession 的 API (不推荐): 使用 SqlSessionselectOne()selectList()insert()update()delete() 等方法直接执行 SQL 语句。 这种方式需要传入 SQL 语句的 ID(在 XML 映射文件中定义)和参数。
    • 获取 Mapper 接口的代理对象 (推荐): 使用 SqlSessiongetMapper() 方法获取 Mapper 接口的代理对象,然后调用 Mapper 接口的方法来执行 SQL 语句。
  4. 提交或回滚事务 (如果需要): 如果进行了数据库修改操作(insertupdatedelete),需要手动提交事务(commit())或回滚事务(rollback())。 如果只进行了查询操作(select),则不需要。

  5. 关闭 SqlSession: 使用 SqlSessionclose() 方法关闭会话,释放资源。 务必在 finally 块中关闭 SqlSession,以确保资源被正确释放。

代码示例 (两种方式):

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 com.example.mapper.UserMapper; // 假设的 Mapper 接口
import com.example.model.User; // 假设的 User 实体类import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class MyBatisExample {public static void main(String[] args) throws IOException {// 1. 获取 SqlSessionFactoryString resource = "mybatis-config.xml"; // MyBatis 配置文件路径InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 方式一:直接使用 SqlSession 的 API (不推荐)SqlSession session1 = null;try {session1 = sqlSessionFactory.openSession();// 执行查询User user1 = session1.selectOne("com.example.mapper.UserMapper.selectUserById", 1); // namespace + idSystem.out.println("方式一 (selectOne): " + user1);// 执行插入User newUser = new User("testuser", "testpassword");int rowsAffected = session1.insert("com.example.mapper.UserMapper.insertUser", newUser);System.out.println("方式一 (insert): 插入了 " + rowsAffected + " 行");// 执行更新newUser.setPassword("newpassword");session1.update("com.example.mapper.UserMapper.updateUser", newUser);//需要手动提交session1.commit();} finally {if (session1 != null) {session1.close();}}// 方式二:获取 Mapper 接口的代理对象 (推荐)SqlSession session2 = null;try {session2 = sqlSessionFactory.openSession();// 获取 Mapper 接口的实例UserMapper userMapper = session2.getMapper(UserMapper.class);// 执行查询User user2 = userMapper.selectUserById(1);System.out.println("方式二 (Mapper 接口): " + user2);// 执行查询List<User> users = userMapper.getUsersByName("%test%"); //假设定义了一个getUsersByName的方法System.out.println("方式二 (Mapper 接口, List): " + users);// 执行插入User newUser2 = new User("testuser2", "testpassword2");int rowsAffected2 = userMapper.insertUser(newUser2);System.out.println("方式二 (Mapper 接口, insert): 插入了 " + rowsAffected2 + " 行, 新用户 ID: " + newUser2.getId());  //假设使用了自增主键//执行删除userMapper.deleteUserById(newUser2.getId());  //假设定义了一个deleteUserById方法// 提交事务session2.commit();} catch (Exception e){//出现异常回滚if(session2 != null){session2.rollback();}e.printStackTrace();} finally {if (session2 != null) {session2.close();}}}
}

重要说明:

  • 线程安全: SqlSession 对象不是线程安全的,每个线程应该拥有自己的 SqlSession 实例。 不要将 SqlSession 实例作为类的成员变量或静态变量,否则会导致并发问题。 应该在方法内部创建和使用 SqlSession
  • 事务管理: openSession() 方法有多个重载版本:
    • openSession(): 默认不自动提交事务。
    • openSession(true): 自动提交事务(一般不推荐,除非你确定每次操作都立即提交)。
    • openSession(ExecutorType executorType): 指定执行器类型(SIMPLEREUSEBATCH)。
    • openSession(Connection connection): 使用外部提供的数据库连接。
    • openSession(TransactionIsolationLevel level): 设置事务隔离级别。
  • 与 Spring 集成: 在 Spring 项目中,通常不需要手动创建和关闭 SqlSession,Spring 会通过 SqlSessionTemplateMapperFactoryBean 来管理 SqlSession 的生命周期,并自动处理事务。
  • 一级缓存: 默认情况下,MyBatis 会为每个 SqlSession 开启一级缓存。在同一个 SqlSession 中,如果执行相同的 SQL 查询(相同的 SQL 语句和参数),MyBatis 会直接从缓存中获取结果,而不会再次访问数据库。 一级缓存的范围是 SqlSession 级别的。 可以通过 session.clearCache() 方法清除一级缓存。

总而言之,SqlSession 是 MyBatis 中执行 SQL 语句、管理事务和获取 Mapper 接口实例的核心接口。推荐使用 Mapper 接口的方式来执行 SQL 语句,这种方式更加简洁、类型安全,并且易于维护。


http://www.ppmy.cn/server/174622.html

相关文章

一文说清docker及docker compose的应用和部署

前言 本文视频版教程&#xff1a;一个视频说清docker及docker compose的应用和部署&#xff08;https://cloud.tencent.com/developer/video/82177&#xff09; 本期教程将介绍Docker和Docker compose的基础应用&#xff0c;通过实际应用来讲解具体使用方法和两者的区别。 假…

1.2 CogPMAlignTool(模板匹配工具), CogFixtureTool(坐标系转换工具)

‌ CogPMAlignTool‌是高精度模板匹配工具&#xff0c;主要用于图像的特征定位和匹配。 ‌ CogFixtureTool是主要用于图像坐标系转换和对齐&#xff0c;就可以把当前拍照的图片固定到之前模板的那张图片。 相当于使用工具CogPMAlignTool‌来测量出当前图片与注册…

使用 OptiSLang 和 MotorCAD 构建一个强大的电机优化元模型

介绍 在本文中&#xff0c;我们将检查这些敏感性分析的结果&#xff0c;并构建一个健壮的元模型&#xff0c;作为优化过程的基础。 本文涵盖&#xff1a; 解释敏感性分析结果了解元模型及其在优化中的重要性构建和完善最佳预后模型 &#xff08;MOP&#xff09;使用预后系数…

蛋白质功能预测论文阅读记录2025(DPFunc、ProtCLIP)

前言 最近研究到瓶颈了&#xff0c;怎么优化都提升不了&#xff0c;遂开始看点最新的论文。 DPFunc 2025.1.2 Nature Communication 中南大学 论文地址&#xff1a;DPFunc: accurately predicting protein function via deep learning with domain-guided structure inform…

AtCoder ABC E - Min of Restricted Sum 题解

根据输入考虑建图&#xff0c;x、y两个下标的边权为z,建无向图 这样我们可以得到一些连通块。根据异或和的性质&#xff0c;对于每一个连通块&#xff0c;我们只要知道其中一个点的点权就能推出所有的点权。 最小值考虑贪心&#xff0c;针对当前连通图所有点权二进制数的每一…

Express + MongoDB + multer 解决文件上传 originalname 中文乱码

出现originalname中文乱码&#xff0c;是因为请求时给后端的是 UTF-8 编码的文件名&#xff0c;而后端 Node.js 在解析文件名时&#xff0c;是以 ISO-8859-1 编码来解析的。 一、手动转换编码 在接收到文件后&#xff0c;对文件名进行编码转换。 1. 单文件 // multer配置 c…

深度解读:OpenAI发布GPT-5的技术突破与商业影响

引言 2025年2月&#xff0c;OpenAI正式发布GPT-5&#xff0c;这一被誉为“AI新纪元开篇之作”的模型&#xff0c;不仅实现了技术架构的颠覆性创新&#xff0c;更以免费开放策略引发行业地震。本文将从技术突破、商业影响、行业竞争格局及未来挑战四个维度&#xff0c;全面解析…

【DevOps】通过 Azure DevOps 部署启用私有端点的应用服务

推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 **实验**测试 1:使用 Microsoft 托管代理部署测试 2:在 Linux VM (Ubuntu 20.04) 上使用自托管代理部署有一种常见的场景是,客户希…