1.4 SqlSession


文档摘要

1.4 SqlSession 1.4 SqlSession:MyBatis 的灵魂接口 SqlSession 是 MyBatis 中最重要的接口之一,它代表了与数据库的一次会话。你可以把它想象成 JDBC 中的 对象,但 SqlSession 提供了更高级、更便捷的操作数据库的方式。SqlSession 提供了执行 SQL 命令、获取映射器实例、管理事务等功能。 1.4.1 SqlSession 的作用 SqlSession 在 MyBatis 中扮演着核心角色,主要负责以下职责: 执行 SQL 语句: SqlSession 提供了多种执行 SQL 语句的方法,例如 , , , , 等。

1.4 SqlSession

1.4 SqlSession:MyBatis 的灵魂接口

SqlSession 是 MyBatis 中最重要的接口之一,它代表了与数据库的一次会话。你可以把它想象成 JDBC 中的 Connection 对象,但 SqlSession 提供了更高级、更便捷的操作数据库的方式。SqlSession 提供了执行 SQL 命令、获取映射器实例、管理事务等功能。

1.4.1 SqlSession 的作用

SqlSession 在 MyBatis 中扮演着核心角色,主要负责以下职责:

  • 执行 SQL 语句: SqlSession 提供了多种执行 SQL 语句的方法,例如 selectOne, selectList, insert, update, delete 等。

  • 获取 Mapper 接口: 通过 SqlSession,你可以获取与 XML 映射文件关联的 Mapper 接口实例,从而以面向对象的方式操作数据库。

  • 事务管理: SqlSession 提供了事务控制的方法,例如 commit, rollback, close 等。

  • 缓存管理: SqlSession 内部维护了一级缓存,用于提高查询效率。

1.4.2 SqlSession 的生命周期

SqlSession 的生命周期应该尽可能短。最佳实践是在一个请求或一个业务逻辑单元中使用一个 SqlSession 实例。用完后应该立即关闭 SqlSession,释放资源。

1.4.3 SqlSession 的获取

SqlSession 通常通过 SqlSessionFactory 获取。SqlSessionFactory 是 MyBatis 的核心组件,负责创建 SqlSession 实例。

// 从 SqlSessionFactory 获取 SqlSession SqlSession sqlSession = sqlSessionFactory.openSession();

SqlSessionFactory.openSession() 方法有多个重载版本,可以指定是否自动提交事务、事务隔离级别等。

  • openSession(): 创建一个非自动提交事务的 SqlSession。

  • openSession(boolean autoCommit): 创建一个 SqlSession,可以指定是否自动提交事务。

  • openSession(TransactionIsolationLevel level): 创建一个具有指定事务隔离级别的 SqlSession。

  • openSession(ExecutorType execType): 创建一个具有指定执行器类型的 SqlSession。

  • openSession(ExecutorType execType, boolean autoCommit): 创建一个具有指定执行器类型和自动提交设置的 SqlSession。

  • openSession(Connection connection): 使用现有的 JDBC 连接创建 SqlSession。

  • openSession(ExecutorType execType, Connection connection): 使用现有的 JDBC 连接和指定的执行器类型创建 SqlSession。

1.4.4 SqlSession 的常用方法

SqlSession 提供了丰富的 API,用于执行各种数据库操作。以下是一些常用的方法:

  • selectOne(String statement, Object parameter): 执行一个查询,返回单个结果对象。

  • selectList(String statement, Object parameter): 执行一个查询,返回结果对象列表。

  • selectMap(String statement, Object parameter, String mapKey): 执行一个查询,返回一个以 mapKey 属性值为键,结果对象为值的 Map。

  • insert(String statement, Object parameter): 执行一个插入操作,返回受影响的行数。

  • update(String statement, Object parameter): 执行一个更新操作,返回受影响的行数。

  • delete(String statement, Object parameter): 执行一个删除操作,返回受影响的行数。

  • commit(): 提交事务。

  • rollback(): 回滚事务。

  • close(): 关闭 SqlSession,释放资源。

  • getMapper(Class<T> type): 获取 Mapper 接口的实例。

1.4.5 SqlSession 的代码实践

以下是一个使用 SqlSession 的简单示例,假设我们有一个 User 实体类和一个 UserMapper 接口。

  1. 定义实体类 User:

    public class User { private Integer id; private String username; private String email; // Getters and setters public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
  2. 定义 Mapper 接口 UserMapper:

    public interface UserMapper { User selectUserById(Integer id); List<User> selectAllUsers(); int insertUser(User user); int updateUser(User user); int deleteUser(Integer id); }
  3. 编写 XML 映射文件 UserMapper.xml:

    <?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"> <mapper namespace="com.example.mapper.UserMapper"> <select id="selectUserById" parameterType="java.lang.Integer" resultType="com.example.entity.User"> SELECT id, username, email FROM users WHERE id = #{id} </select> <select id="selectAllUsers" resultType="com.example.entity.User"> SELECT id, username, email FROM users </select> <insert id="insertUser" parameterType="com.example.entity.User"> INSERT INTO users (username, email) VALUES (#{username}, #{email}) </insert> <update id="updateUser" parameterType="com.example.entity.User"> UPDATE users SET username = #{username}, email = #{email} WHERE id = #{id} </update> <delete id="deleteUser" parameterType="java.lang.Integer"> DELETE FROM users WHERE id = #{id} </delete> </mapper>
  4. 使用 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class MyBatisExample { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; // 替换为你的 MyBatis 配置文件 InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession sqlSession = sqlSessionFactory.openSession()) { // 获取 Mapper 接口实例 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 查询用户 User user = userMapper.selectUserById(1); System.out.println("User: " + user.getUsername() + ", " + user.getEmail()); // 插入用户 User newUser = new User(); newUser.setUsername("testUser"); newUser.setEmail("test@example.com"); int insertedRows = userMapper.insertUser(newUser); System.out.println("Inserted rows: " + insertedRows); // 提交事务 sqlSession.commit(); // 查询所有用户 List<User> allUsers = userMapper.selectAllUsers(); allUsers.forEach(u -> System.out.println("User: " + u.getUsername() + ", " + u.getEmail())); } catch (Exception e) { // 处理异常,回滚事务 sqlSession.rollback(); e.printStackTrace(); } } }

    代码解释:

    • 首先,我们从 mybatis-config.xml 文件中加载 MyBatis 配置,创建 SqlSessionFactory

    • 然后,我们使用 sqlSessionFactory.openSession() 创建一个 SqlSession 实例。

    • 通过 sqlSession.getMapper(UserMapper.class) 获取 UserMapper 接口的实例。

    • 使用 userMapper 执行数据库操作,例如查询、插入等。

    • 如果操作成功,调用 sqlSession.commit() 提交事务。

    • 如果发生异常,调用 sqlSession.rollback() 回滚事务。

    • 最后,务必调用 sqlSession.close() 关闭 SqlSession,释放资源。 这里使用了try-with-resources语句,SqlSession实现了AutoCloseable接口,所以可以自动关闭资源。

1.4.6 SqlSession 的事务管理

SqlSession 提供了编程式事务管理的方式。默认情况下,SqlSession 创建的连接不会自动提交事务。你需要手动调用 commit() 方法提交事务,或者调用 rollback() 方法回滚事务。

示例:

try (SqlSession sqlSession = sqlSessionFactory.openSession()) { try { // 执行数据库操作 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.insertUser(new User()); userMapper.updateUser(new User()); // 提交事务 sqlSession.commit(); } catch (Exception e) { // 回滚事务 sqlSession.rollback(); throw e; } }

1.4.7 SqlSession 的一级缓存

SqlSession 内部维护了一级缓存,也称为本地缓存。一级缓存的生命周期与 SqlSession 相同。当你在同一个 SqlSession 中执行相同的查询时,MyBatis 会首先从一级缓存中查找结果,如果找到则直接返回,避免重复查询数据库。

一级缓存的特点:

  • 作用域:SqlSession 级别。

  • 存储方式:HashMap。

  • 失效条件:

    • SqlSession 关闭。

    • 执行了任何 update、insert、delete 操作,都会清空缓存。

    • 手动调用 sqlSession.clearCache() 清空缓存。

示例:

try (SqlSession sqlSession = sqlSessionFactory.openSession()) { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 第一次查询,会查询数据库 User user1 = userMapper.selectUserById(1); System.out.println("First query: " + user1.getUsername()); // 第二次查询,会从一级缓存中获取 User user2 = userMapper.selectUserById(1); System.out.println("Second query: " + user2.getUsername()); // 修改用户信息,会清空一级缓存 User updateUser = new User(); updateUser.setId(1); updateUser.setUsername("newUsername"); userMapper.updateUser(updateUser); sqlSession.commit(); // 第三次查询,会重新查询数据库 User user3 = userMapper.selectUserById(1); System.out.println("Third query: " + user3.getUsername()); }

1.4.8 SqlSession 的 ExecutorType

ExecutorType 用于控制 SqlSession 执行 SQL 语句的方式。MyBatis 提供了三种 ExecutorType

  • SIMPLE: 默认的执行器类型,为每个 SQL 语句创建一个新的 Statement 对象。

  • REUSE: 重用 Statement 对象,可以提高性能,尤其是在执行大量相同 SQL 语句时。

  • BATCH: 批量执行 SQL 语句,可以显著提高插入、更新、删除操作的性能。

示例:

// 使用 BATCH 执行器 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 批量插入用户 for (int i = 0; i < 1000; i++) { User user = new User(); user.setUsername("user" + i); user.setEmail("user" + i + "@example.com"); userMapper.insertUser(user); } // 提交事务 sqlSession.commit(); }

注意: 使用 BATCH 执行器时,需要手动调用 commit() 方法提交事务,否则数据不会被写入数据库。

1.4.9 SqlSession 的线程安全性

SqlSession 本身不是线程安全的。因此,不要在多个线程之间共享同一个 SqlSession 实例。最佳实践是在每个线程中创建一个新的 SqlSession 实例,并在线程结束时关闭它。

1.4.10 总结

SqlSession 是 MyBatis 中最重要的接口,它代表了与数据库的一次会话。通过 SqlSession,你可以执行 SQL 语句、获取 Mapper 接口实例、管理事务等。理解 SqlSession 的作用、生命周期、常用方法以及注意事项,对于编写高效、可靠的 MyBatis 应用程序至关重要。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U