MyBatis SqlSession 的作用,以及怎样使用 SqlSession 执行 SQL 语句 ...

打印 上一主题 下一主题

主题 965|帖子 965|积分 2895

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

  • 执行 SQL 语句: SqlSession 提供了执行 SQL 语句的方法,包罗 select、insert、update 和 delete 操作。
  • 获取 Mapper 接口的实例: SqlSession 可以获取 Mapper 接口的署理对象,从而通过 Mapper 接口来执行 SQL 语句 (这是保举的方式)。
  • 管理事务: SqlSession 可以控制事务的提交(commit)和回滚(rollback)。
  • 维护数据库连接: SqlSession 内部持有数据库连接(Connection),并在会话竣事时负责关闭连接(除非使用了外部事务管理器,如 Spring 的事务管理)。
  • 缓存管理(一级缓存): SqlSession 拥有一个本地缓存(一级缓存),可以缓存查询效果,减少数据库访问次数(默认开启)。
怎样使用 SqlSession 执行 SQL 语句:
SqlSession 的使用通常遵循以下步骤:

  • 获取 SqlSessionFactory: SqlSessionFactory 是 SqlSession 的工厂,负责创建 SqlSession 对象。通常情况下,SqlSessionFactory 在应用步伐的生命周期内只必要创建一个实例(单例模式)。 SqlSessionFactory 可以通过 XML 设置文件或 Java 代码来创建。
  • 通过 SqlSessionFactory 打开 SqlSession: 使用 SqlSessionFactory 的 openSession() 方法打开一个新的 SqlSession。
  • 执行 SQL 语句:

    • 直接使用 SqlSession 的 API (不保举): 使用 SqlSession 的 selectOne()、selectList()、insert()、update()、delete() 等方法直接执行 SQL 语句。 这种方式必要传入 SQL 语句的 ID(在 XML 映射文件中定义)和参数。
    • 获取 Mapper 接口的署理对象 (保举): 使用 SqlSession 的 getMapper() 方法获取 Mapper 接口的署理对象,然后调用 Mapper 接口的方法来执行 SQL 语句。

  • 提交或回滚事务 (如果必要): 如果举行了数据库修改操作(insert、update、delete),必要手动提交事务(commit())或回滚事务(rollback())。 如果只举行了查询操作(select),则不必要。
  • 关闭 SqlSession: 使用 SqlSession 的 close() 方法关闭会话,开释资源。 务必在 finally 块中关闭 SqlSession,以确保资源被精确开释。
代码示例 (两种方式):
  1. import org.apache.ibatis.io.Resources;
  2. import org.apache.ibatis.session.SqlSession;
  3. import org.apache.ibatis.session.SqlSessionFactory;
  4. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  5. import com.example.mapper.UserMapper; // 假设的 Mapper 接口
  6. import com.example.model.User; // 假设的 User 实体类
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.util.List;
  10. public class MyBatisExample {
  11.     public static void main(String[] args) throws IOException {
  12.         // 1. 获取 SqlSessionFactory
  13.         String resource = "mybatis-config.xml"; // MyBatis 配置文件路径
  14.         InputStream inputStream = Resources.getResourceAsStream(resource);
  15.         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  16.         // 方式一:直接使用 SqlSession 的 API (不推荐)
  17.         SqlSession session1 = null;
  18.         try {
  19.             session1 = sqlSessionFactory.openSession();
  20.             // 执行查询
  21.             User user1 = session1.selectOne("com.example.mapper.UserMapper.selectUserById", 1); // namespace + id
  22.             System.out.println("方式一 (selectOne): " + user1);
  23.             // 执行插入
  24.             User newUser = new User("testuser", "testpassword");
  25.             int rowsAffected = session1.insert("com.example.mapper.UserMapper.insertUser", newUser);
  26.             System.out.println("方式一 (insert): 插入了 " + rowsAffected + " 行");
  27.             // 执行更新
  28.              newUser.setPassword("newpassword");
  29.             session1.update("com.example.mapper.UserMapper.updateUser", newUser);
  30.               //需要手动提交
  31.             session1.commit();
  32.         } finally {
  33.             if (session1 != null) {
  34.                 session1.close();
  35.             }
  36.         }
  37.         // 方式二:获取 Mapper 接口的代理对象 (推荐)
  38.         SqlSession session2 = null;
  39.         try {
  40.             session2 = sqlSessionFactory.openSession();
  41.             // 获取 Mapper 接口的实例
  42.             UserMapper userMapper = session2.getMapper(UserMapper.class);
  43.             // 执行查询
  44.             User user2 = userMapper.selectUserById(1);
  45.             System.out.println("方式二 (Mapper 接口): " + user2);
  46.              // 执行查询
  47.             List<User> users = userMapper.getUsersByName("%test%"); //假设定义了一个getUsersByName的方法
  48.             System.out.println("方式二 (Mapper 接口, List): " + users);
  49.             // 执行插入
  50.             User newUser2 = new User("testuser2", "testpassword2");
  51.             int rowsAffected2 = userMapper.insertUser(newUser2);
  52.             System.out.println("方式二 (Mapper 接口, insert): 插入了 " + rowsAffected2 + " 行, 新用户 ID: " + newUser2.getId());  //假设使用了自增主键
  53.             //执行删除
  54.             userMapper.deleteUserById(newUser2.getId());  //假设定义了一个deleteUserById方法
  55.             
  56.             // 提交事务
  57.             session2.commit();
  58.         } catch (Exception e){
  59.             //出现异常回滚
  60.             if(session2 != null){
  61.                 session2.rollback();
  62.             }
  63.             e.printStackTrace();
  64.         } finally {
  65.             if (session2 != null) {
  66.                 session2.close();
  67.             }
  68.         }
  69.     }
  70. }
复制代码
重要阐明:


  • 线程安全: SqlSession 对象不是线程安全的,每个线程应该拥有自己的 SqlSession 实例。 不要将 SqlSession 实例作为类的成员变量或静态变量,否则会导致并发标题。 应该在方法内部创建和使用 SqlSession。
  • 事务管理: openSession() 方法有多个重载版本:

    • openSession(): 默认不自动提交事务。
    • openSession(true): 自动提交事务(一般不保举,除非你确定每次操作都立即提交)。
    • openSession(ExecutorType executorType): 指定执行器范例(SIMPLE、REUSE、BATCH)。
    • openSession(Connection connection): 使用外部提供的数据库连接。
    • openSession(TransactionIsolationLevel level): 设置事务隔离级别。

  • 与 Spring 集成: 在 Spring 项目中,通常不必要手动创建和关闭 SqlSession,Spring 会通过 SqlSessionTemplate 或 MapperFactoryBean 来管理 SqlSession 的生命周期,并自动处理事务。
  • 一级缓存: 默认情况下,MyBatis 会为每个 SqlSession 开启一级缓存。在同一个 SqlSession 中,如果执行相同的 SQL 查询(相同的 SQL 语句和参数),MyBatis 会直接从缓存中获取效果,而不会再次访问数据库。 一级缓存的范围是 SqlSession 级别的。 可以通过 session.clearCache() 方法清除一级缓存。
总而言之,SqlSession 是 MyBatis 中执行 SQL 语句、管理事务和获取 Mapper 接口实例的焦点接口。保举使用 Mapper 接口的方式来执行 SQL 语句,这种方式更加简洁、范例安全,而且易于维护。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万有斥力

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表