【JAVAEE框架】MyBatis与Spring的整合(下)

举报
追zhui 发表于 2025/11/13 20:38:55 2025/11/13
【摘要】 >  哈喽~大家好呀,我们接着上篇的讲解。>>  >>  >>  🥇个人主页:[个人主页](https://blog.csdn.net/aasd23?spm=1000.2115.3001.5343)       >>  🥈 系列专栏:[【云原生系列】](https://blog.csdn.net/aasd23/category_11852592.html?spm=1001.2014.30...
>  哈喽~大家好呀,我们接着上篇的讲解。
>
>  
>
>  
>
>  🥇个人主页:[个人主页](https://blog.csdn.net/aasd23?spm=1000.2115.3001.5343)       
>
>  🥈 系列专栏:[【云原生系列】](https://blog.csdn.net/aasd23/category_11852592.html?spm=1001.2014.3001.5482)
>
>  🥉与这篇相关的文章:      
>
>  
>
>  |      |      |
>  | ---- | ---- |
>  |      |      |
>  |      |      |



一、前言

上篇当中我们使用 SqlSessionFactoryBean 来创建bean,以及使用了 SqlSessionTemplate。

在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的,而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来创建。要创建工厂 bean,将下面的代码放到 Spring 的 XML 配置文件中:

```XML
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
</bean>
```

![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)

SqlSessionTemplate 简介
 通俗地讲,SqlSessionTemplate是Mybatis—Spring的核心,是用来代替默认Mybatis实现的DefaultSqlSessionFactory,也可以说是DefaultSqlSessionFactory的优化版,主要负责管理Mybatis的SqlSession,调用Mybatis的sql方法,SqlSessionTemplate是线程安全的,通过TransactionSynchronizationManager中的ThreadLocal保存线程对应的SqlSession,可以被多个Dao共享使用。

二、采用映射方式

这里采用mapper的形式来创建dao的实现类, 编写user的dao层的mapper映射对象,这里可以直接使用factory为mapper对象赋值,也可以用 SqlSessionTemplate 为 mapper 赋值, 可以理解为 省去创建 SqlSessionTemplate 对象这一步

去掉 SqlSessionFactoryBean 与 sqlSessionTemplate 换上 MapperFactoryBean

![img](https://img-blog.csdnimg.cn/edd8e66297f64065a8901b6ba073eff7.png)

![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑



![img](https://img-blog.csdnimg.cn/a8db7d93fc084c438690fbb1581f926a.png)

![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑



测试类来测试一下

```java
    @Test
    public void test01(){

        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        IUserService userService = context.getBean(IUserService.class);

        UserCondition conn = new UserCondition();

        List<SmbmsUser> userList = userService.getUserListByCondition(conn);

        for (SmbmsUser user : userList) {
            System.out.println(user);
        }

    }
```

![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)

![img](https://img-blog.csdnimg.cn/e314f903f57e40209a7086c429c0e9d1.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

三、采用注解的方式

@Service的作用
    spring中有很多注解帮助我们开发,@Repository、@Service 、@Controller 和@Component注解在类上面即可以使spring自动向Bean容器中创建该类的Bean,而在我们需要用到该Bean来创建对象时,在变量声明上方添加@AutoWired或者@Qualifier即可。

@Autowired作用

Autowired 注解进行装配,只能是根据类型进行匹配。@Autowired 注解可以用于 Setter 方法、构造函数、字段,甚至普通方法,前提是方法必须有至少一个参数。@Autowired 可以用于数组和使用泛型的集合类型。然后 Spring 会将容器中所有类型符合的 Bean 注入进来。@Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key。

![img](https://img-blog.csdnimg.cn/1aec9699cb564b13baa2c54692f266f6.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

![img](https://img-blog.csdnimg.cn/6c998a6f6eaa469c934997789fef8dc8.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

 Service加上注解

![img](https://img-blog.csdnimg.cn/f8368c867d544bb88e4357d80972698a.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

 测试跑一下数据

```java
    @Test
    public void test01(){

        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        IUserService userService = context.getBean(IUserService.class);

        UserCondition conn = new UserCondition();

        List<SmbmsUser> userList = userService.getUserListByCondition(conn);

        for (SmbmsUser user : userList) {
            System.out.println(user);
        }

    }
```

![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)

![img](https://img-blog.csdnimg.cn/ec098d76072344d7a188d4a0df7efb72.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

四、业务层添加声明式事务

1、Spring事务(Transaction)

事务(Transaction)是基于关系型数据库(RDBMS)的企业应用的重要组成部分。在软件开发领域,事务扮演者十分重要的角色,用来确保应用程序数据的完整性和一致性。

事务具有 4 个特性:原子性、一致性、隔离性和持久性,简称为 ACID 特性。
 原子性(Atomicity):一个事务是一个不可分割的工作单位,事务中包括的动作要么都做要么都不做。
 一致性(Consistency):事务必须保证数据库从一个一致性状态变到另一个一致性状态,一致性和原子性是密切相关的。
 隔离性(Isolation):一个事务的执行不能被其它事务干扰,即一个事务内部的操作及使用的数据对并发的其它事务是隔离的,并发执行的各个事务之间不能互相打扰。
 持久性(Durability):持久性也称为永久性,指一个事务一旦提交,它对数据库中数据的改变就是永久性的,后面的其它操作和故障都不应该对其有任何影响。

事务允许我们将几个或一组操作组合成一个要么全部成功、要么全部失败的工作单元。如果事务中的所有的操作都执行成功,那自然万事大吉。但如果事务中的任何一个操作失败,那么事务中所有的操作都会被回滚,已经执行成功操作也会被完全清除干净,就好像什么事都没有发生一样。

在现实世界中,最常见的与事务相关的例子可能就是银行转账了。假设我们需要将 1000 元从 A 账户中转到 B 账户中,这个转账操作共涉及了以下两个操作。
 从 A 账户中扣除 1000 元;
 往 B 账户中存入 1000 元。

如果 A 账户成功地扣除了 1000 元,但向 B 账户存入时失败的话,那么我们将凭空损失 1000 元;如果 A 账户扣款时失败,但却成功地向 B 账户存入 1000 元的话,我们的账户就凭空多出了 1000 元,那么银行就会遭受损失。因此我们必须保证事务中的所有操作要么全部成功,要么全部失败,理解了这一点,我们也就抓住了事务的核心。

**配置步骤**   
 导入tx和aop命名空间
 定义事务管理器Bean,并为其注入数据源Bean
 通过<tx:advice>配置事务增强,绑定事务管理器并针对不同方法定义事务规则
 配置切面,将事务增强与方法切入点组合

```XML
<!-- 配置事务-->
<!-- 配置事务管理器 Bean,类似于切面 Bean -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置事务增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- isolation隔离级别,propagation 传播行为-->
<tx:method name="get*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="delete*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

<!-- 配置切面,将事务增强与方法切入点结合-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(public * com.itxzw.*.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
```

![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)

> propagation:事务传播机制
> REQUIRED(默认值)
> REQUIRES_NEW 、MANDATORY、NESTED
> SUPPORTS
> NOT_SUPPORTED、NEVER
> isolation:事务隔离等级
> DEFAULT(默认值)
> READ_COMMITTED
> READ_UNCOMMITTED
> REPEATABLE_READ
> SERIALIZABLE

注:REQUIRED能够满足大多数的事务需求可以作为首选的事务传播行为。

2、事务属性

> **timeout:**事务超时时间,允许事务运行的最长时间,以秒为单位。默认值为-1,表示不超时
> **read-only:**事务是否为只读,默认值为false
> **rollback-for:**设定能够触发回滚的异常类型
> Spring默认只在抛出runtime exception时才标识事务回滚
> 可以通过全限定类名指定需要回滚事务的异常,多个类名用逗号隔开
> **no-rollback-for:**设定不触发回滚的异常类型
> Spring默认checked Exception不会触发事务回滚
> 可以通过全限定类名指定不需回滚事务的异常,多个类名用英文逗号隔开

测试类跑一下

![img](https://img-blog.csdnimg.cn/e218f9f2cb4b44d8ab954884fad0f1de.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

 五、DataSourceTransactionManager

在使用spring进行web开发时,虽然spring提供的注解方式可以方便的处理很多原来需要手动提交或回滚的事务,但是注解方式有自己使用的局限,比如在类的内部调用方法时,注解方式处理的事务就无法被触发,此时可能需要手动处理相关数据库的事务。本文记录在spring开发时使用Spring提供的DataSourceTransactionManager进行事务提交或回滚处理。

![img](https://img-blog.csdnimg.cn/fad6ba4743bc4df7989f3960e92264bf.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

 测试类跑一下

![img](https://img-blog.csdnimg.cn/fbd2586f58ab4e909745884e49e7385e.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑

生成 log 文件

![img](https://img-blog.csdnimg.cn/f8509ea994be4ab19360cf7573805300.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑 总结一句话:手动处理相关数据库的事务

六、总结

![img](https://img-blog.csdnimg.cn/7f618ef5e63d44bd8bc615a15a1792b9.png)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑



> **不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!**
>
>
> ![img](https://img-blog.csdnimg.cn/02bed6ae9d27419b804c4605db6cee66.gif)![点击并拖拽以移动](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)编辑
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。