Mybatis 手撸专栏|第20章:整合Spring

2023-11-14 09:41:42 浏览数 (1)

Mybatis 手撸专栏

第20章:整合Spring

引言

在前几篇文章中,我们详细介绍了 Mybatis 的基本使用和高级特性,以及二级缓存的原理和优化策略。然而,对于实际的项目开发而言,仅仅使用 Mybatis 本身可能还不够。通常,我们需要将 Mybatis 与其他框架进行整合,以便更好地应对复杂的业务场景和需求。而其中最常见的整合方式莫过于 Mybatis 和 Spring 的组合。

本章我们将深入探讨如何整合 Mybatis 和 Spring,以及如何利用 Spring 的优势来简化我们的开发流程。我们将从配置 Spring 和 Mybatis,到实现事务管理和依赖注入,一步步地带领大家完成整合的过程。

配置 Spring 和 Mybatis

添加 Maven 依赖

首先,我们需要在项目的 pom.xml 文件中添加 Mybatis 和 Spring 的 Maven 依赖。请确保您已经正确配置了 Maven 环境。

代码语言:html复制
<!-- Mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.3</version>
</dependency>

<!-- Spring Core -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.9</version>
</dependency>

<!-- Spring Context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.9</version>
</dependency>

<!-- Spring JDBC -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.9</version>
</dependency>

<!-- 数据库驱动,根据实际使用的数据库选择 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>

配置 Spring 和 Mybatis

接下来,我们需要配置 Spring 和 Mybatis 的相关配置文件。

1. applicationContext.xml

首先,创建一个 applicationContext.xml 的配置文件,并将其放置在项目的 resources 目录下。在这个文件中,我们可以配置 Spring 的核心功能,以及与 Mybatis 相关的配置。

代码语言:html复制
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启组件自动扫描 -->
    <context:component-scan base-package="com.example" />

    <!-- 数据源配置,根据实际情况修改 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydatabase?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
    </bean>

    <!-- Mybatis SqlSessionFactory 配置 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath*:com/example/mapper/*.xml"/>
        <property name="typeAliasesPackage" value="com.example.model"/>
    </bean>

    <!-- Mybatis Mapper 接口扫描 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.example.mapper"/>
    </bean>

    <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 开启注解式事务 -->
    <tx:annotation-driven/>

</beans>

在上述配置中,我们使用了 Spring 的 DriverManagerDataSource 类作为数据源,根据实际情况修改相关配置。同时,我们配置了 Mybatis 的 SqlSessionFactory,指定了 Mapper 接口和映射文件的位置,以及实体类的包名。

2. web.xml

如果您使用的是基于 Servlet 的 Web 应用程序,还需要在 web.xml 文件中添加如下配置:

代码语言:html复制
<!-- Spring 配置 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

这样,当应用程序启动时,Spring 将会加载 applicationContext.xml 文件并初始化 Spring 容器。

使用 Spring 进行事务管理

在项目开发过程中,事务管理是非常重要的一个方面。Spring 提供了强大的事务管理功能,可以简化我们的代码,并确保事务的一致性和完整性。

配置事务管理器

我们已经在 applicationContext.xml 文件中配置了事务管理器 DataSourceTransactionManager。现在,我们需要使用 @EnableTransactionManagement 注解来启用 Spring 的事务管理功能。

首先,在 Spring 的配置类上添加 @EnableTransactionManagement 注解:

代码语言:java复制
@Configuration
@EnableTransactionManagement
public class AppConfig {
    // ...
}

接下来,我们可以在需要进行事务管理的方法上添加 @Transactional 注解:

代码语言:java复制
@Transactional
public void addUser(User user) {
    // 添加用户的业务逻辑
    userDao.addUser(user);
}

在上述代码中,我们使用 @Transactional 注解标识了一个添加用户的方法。当该方法被调用时,Spring 将自动创建并管理事务。如果方法执行成功,则事务将被提交;如果方法执行出现异常,则事务将被回滚。

事务传播行为

在实际的业务场景中,我们经常会遇到多个方法相互调用的情况。而在事务管理中,就在事务管理中,我们需要考虑方法之间的事务传播行为,以确保事务的一致性和正确性。

Spring 提供了几种事务传播行为的选项,我们可以根据实际需求来选择合适的选项。

  1. PROPAGATION_REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务。这是最常用的传播行为,适用于大多数的业务场景。
  2. PROPAGATION_REQUIRES_NEW:创建一个新事务,并挂起当前的事务(如果存在)。这意味着无论外部事务是否存在,该方法都将在自己的独立事务中执行。
  3. PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。该传播行为适用于不需要强制事务的读取操作。
  4. PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起该事务。适用于不需要事务支持的操作,例如只读查询等。

通过使用不同的事务传播行为,我们可以根据具体情况灵活地控制事务的行为。

代码语言:java复制
@Transactional(propagation = Propagation.REQUIRED)
public void processOrder(Order order) {
    // 处理订单的业务逻辑
    // 调用其他事务方法
    userService.updateUserPoints(order.getUserId(), order.getPoints());
    inventoryService.reduceStock(order.getProductId(), order.getQuantity());
}

在上述代码中,我们使用了 @Transactional 注解,并在方法上设置了事务的传播行为为 Propagation.REQUIRED。这表示在处理订单的过程中,将会自动创建一个新的事务,并且如果 userService.updateUserPointsinventoryService.reduceStock 方法中存在事务,则会加入当前的事务。

利用 Spring 的依赖注入

一直以来,依赖注入(Dependency Injection)都是 Spring 框架的明星特性之一。通过依赖注入,我们可以将对象之间的依赖关系交给 Spring 容器来管理,以实现松耦合的设计。

在整合 Mybatis 和 Spring 的过程中,我们可以充分利用 Spring 的依赖注入功能,提高代码的可维护性和可测试性。

配置文件中的 Bean 声明

applicationContext.xml 配置文件中,我们可以使用 <bean> 元素来声明需要被 Spring 管理的 Bean。

代码语言:html复制
<bean id="userService" class="com.example.service.UserService">
    <property name="userDao" ref="userDao" />
</bean>

<bean id="userDao" class="com.example.dao.UserDaoImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

在上述代码中,我们通过 <bean> 元素配置了一个名为 userService 的 Bean,它的类型是 com.example.service.UserService。同时,我们使用 <property> 元素来注入 userService 的依赖,即 userDao

通过注解进行依赖注入

除了在配置文件中声明 Bean 和依赖关系外,我们还可以使用注解方式来进行依赖注入。

@Autowired 注解

@Autowired 是 Spring 框架提供的基础注解之一,用于自动注入依赖。

我们可以在需要注入依赖的地方使用 @Autowired 注解,Spring 将会根据类型自动查找并注入相应的 Bean。

代码语言:java复制
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserDao userDao;
    
    // ...
}

在上述代码中,我们使用 @Autowired 注解将 userDao 成员变量注入到 UserServiceImpl 类中。

@Resource 注解

@Resource 注解是 JavaEE 规范中定义的注解,也可以用于依赖注入。

@Autowired 注解不同,@Resource 注解可以根据名称或类型来进行依赖查找和注入。

代码语言:java复制
@Controller
public class UserController {
    
    @Resource
    private UserService userService;
    
    // ...
}

在上述代码中,我们使用 @Resource 注解将 userService 成员变量注入到 UserController 类中。

构造函数注入

除了使用属性注入外,我们还可以使用构造函数注入来满足对象之间的依赖关系。

在 Spring 的配置文件中,我们可以使用 <constructor-arg> 元素来配置构造函数注入的参数。

代码语言:html复制
<bean id="userService" class="com.example.service.UserServiceImpl">
    <constructor-arg ref="userDao" />
</bean>

在上述配置中,我们使用 <constructor-arg> 元素注入了一个类型为 com.example.dao.UserDao 的 Bean。

在相应的类中,我们可以定义一个带有参数的构造函数,Spring 将会根据配置自动进行构造函数注入。

代码语言:java复制
@Service
public class UserServiceImpl implements UserService {
    
    private final UserDao userDao;
    
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
    
    // ...
}

在上述代码中,我们定义了一个带有 UserDao 参数的构造函数,并将其赋值给了 userDao 成员变量。

通过构造函数注入,我们可以在对象创建时就完成依赖关系的注入,确保对象的一致性和稳定性。

总结

本文我们深入探讨了如何将 Mybatis 和 Spring 进行整合。通过配置 Spring 和 Mybatis,我们可以充分发挥两者的优势,简化开发流程,并确保事务的一致性和完整性。

同时,我们还介绍了如何利用 Spring 的依赖注入功能,实现对象之间的解耦和灵活管理。

希望本文对您理解整合 Mybatis 和 Spring 的过程有所帮助。如果您有任何问题或需要进一步的指导,请随时向我提问。谢谢阅读!

文章参考来源:Spring Framework Documentation MyBatis Documentation

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞