当前位置: 首页 > article >正文

7. MyBatis中的SqlSession是什么?如何管理SqlSession的生命周期?

SqlSession 是 MyBatis 的核心接口之一,用于执行与数据库的交互操作。它提供了执行 SQL 语句的所有方法,包括插入、更新、删除和查询,还可以管理事务、获取映射器(Mapper)接口的实例等。

SqlSession 的主要功能包括:

  1. 执行SQL操作:如 insertupdatedeleteselect 等方法,用于执行对应的 SQL 语句。

  2. 事务管理:通过 commit()rollback() 方法进行事务的提交与回滚。

  3. 获取Mapper:通过 getMapper(Class<T> type) 方法获取映射器接口的实例,从而使用接口调用来执行 SQL。

  4. 缓存管理SqlSession 还负责管理一级缓存,它会自动缓存相同会话中的查询结果,减少对数据库的访问。

如何管理SqlSession的生命周期?

SqlSession 不是线程安全的,它的生命周期应由使用者自己管理。正确地管理 SqlSession 的生命周期对于避免资源泄漏和确保应用程序的可靠性至关重要。以下是管理 SqlSession 生命周期的常用方法:

1. 手动管理 SqlSession

当你在没有使用 Spring 的场景下,可以手动管理 SqlSession 的生命周期。通常,在执行数据库操作时,手动打开 SqlSession,执行操作后立即关闭它。

示例代码

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
​
public class MyBatisExample {
​
    private SqlSessionFactory sqlSessionFactory;
​
    public MyBatisExample(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }
​
    public void performDatabaseOperation() {
        SqlSession session = null;
        try {
            session = sqlSessionFactory.openSession(); // 打开 SqlSession
            UserMapper mapper = session.getMapper(UserMapper.class); // 获取 Mapper
            User user = mapper.selectUserById(1); // 执行 SQL 查询
            System.out.println(user);
​
            session.commit(); // 提交事务
        } catch (Exception e) {
            if (session != null) {
                session.rollback(); // 发生异常时回滚事务
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close(); // 关闭 SqlSession
            }
        }
    }
}

在这个例子中:

  • openSession() 方法用于打开一个 SqlSession

  • 在 try 块中执行数据库操作并调用 commit() 提交事务。

  • 如果发生异常,在 catch 块中调用 rollback() 回滚事务。

  • 最后在 finally 块中确保 SqlSession 被关闭,以释放资源。

2. 使用 Spring 管理 SqlSession 的生命周期

在 Spring 环境中,通常不需要手动管理 SqlSession 的生命周期。Spring 整合 MyBatis 后,通过 SqlSessionTemplate 来管理 SqlSession 的生命周期,开发者只需关注业务逻辑,Spring 会自动管理事务和资源的关闭。

使用 Spring 的 MyBatis 整合

  1. 配置 SqlSessionFactorySqlSessionTemplate

    在 Spring 的配置类或 XML 中配置 SqlSessionFactorySqlSessionTemplate

    @Configuration
    @MapperScan("com.example.mapper")
    public class MyBatisConfig {
    ​
        @Bean
        public DataSource dataSource() {
            // 配置数据源
        }
    ​
        @Bean
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource);
            return factoryBean.getObject();
        }
    ​
        @Bean
        public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }

  2. 在 Mapper 接口中使用

    在 Spring 中使用 MyBatis 时,只需定义 Mapper 接口,无需显式管理 SqlSession

    @Repository
    public interface UserMapper {
        User selectUserById(int id);
    }

    然后在服务类中自动注入 Mapper 接口,直接调用方法执行数据库操作:

    @Service
    public class UserService {
    ​
        @Autowired
        private UserMapper userMapper;
    ​
        public User getUserById(int id) {
            return userMapper.selectUserById(id);
        }
    }

    在这种模式下,SqlSession 的生命周期完全由 Spring 管理,SqlSessionTemplate 会自动打开和关闭 SqlSession,并管理事务。

3. 正确的事务管理

  • 手动管理事务:在手动管理 SqlSession 时,事务控制需要通过 commit()rollback() 来完成。

  • Spring 管理事务:通过 Spring 配置事务管理器,使用 @Transactional 注解来管理事务,无需显式调用 commit()rollback(),Spring 会在方法成功执行后自动提交事务,或在发生异常时自动回滚事务。

4. 避免 SqlSession 泄漏

无论是在手动管理还是使用 Spring 管理 SqlSession,都要确保 SqlSession 在使用后能够正确关闭,以避免数据库连接泄漏。对于手动管理的情况,使用 try-finally 结构确保关闭 SqlSession。对于 Spring 管理的情况,依赖 Spring 自动处理。

总结

  • SqlSession 是 MyBatis 与数据库交互的核心接口,提供了执行 SQL 语句、事务管理和获取 Mapper 的功能。

  • 手动管理 SqlSession,必须在使用后及时关闭,以避免资源泄漏。使用 try-finally 结构是推荐的方式。

  • 在 Spring 环境中,通常通过 SqlSessionTemplate 来管理 SqlSession,开发者不需要手动处理 SqlSession 的打开和关闭,Spring 会自动管理事务和资源。

  • 正确的事务管理 是确保数据一致性和避免资源泄漏的关键,在手动管理和 Spring 管理模式下有不同的实现方式。


http://www.kler.cn/a/301522.html

相关文章:

  • Nature Communications 基于触觉手套的深度学习驱动视触觉动态重建方案
  • C++析构函数详解
  • mybatis 动态SQL语句
  • python机器人Agent编程——多Agent框架的底层逻辑(上)
  • Linux从0——1之shell编程4
  • mybatis-plus: mapper-locations: “classpath*:/mapper/**/*.xml“配置!!!解释
  • uniapp写移动端常见问题汇总
  • 反序列化漏洞练习2
  • python 实现判断IP4地址是否有效算法
  • MongoDB延迟查询
  • chapter14-集合——(List-Map)——day18
  • ctfshow-文件包含
  • JavaEE:多线程进阶(线程安全的集合类)
  • Python实现Paillier同态加密算法
  • JavaWeb开发中为什么Controller里面的方法是@RequestMapping?
  • 张力控制器的原理
  • 【2023年】云计算金砖牛刀小试3
  • 《C++枚举类型的进化:从传统到现代的飞跃》
  • SAP B1 学习笔记 - 易混淆字段名(持续更新中)
  • 【c/c++】类型转换:隐式类型转换、强制类型转换
  • Vue - 关于Router路由跳转时显示的animate.css动画
  • ffmpeg使用安装使用教程(命令行-Python)
  • 后端Web之SpringBoot原理
  • Ubuntu 22.04 系统中 ROS2安装
  • 复仇时刻 华为的狙击还没结束
  • JAVA 使用POI实现单元格行合并生成