Spring Boot作为一个现代Java开发框架,通过其简化的配置和丰富的功能,极大地提升了开发效率。在数据访问层,MyBatis作为一个优秀的ORM框架,因其灵活性和易用性得到了广泛应用。本文将详细介绍如何在Spring Boot项目中集成MyBatis,涵盖基本配置、动态SQL、多数据源、分页、缓存等多个方面,旨在帮助开发者全面掌握Spring Boot与MyBatis的集成方法。

1. Spring Boot与MyBatis简介

1.1 Spring Boot简介

Spring Boot是Spring生态系统中的一部分,通过简化Spring应用程序的搭建和配置,提升了开发效率。Spring Boot提供了一系列开箱即用的默认配置,支持多种第三方库的快速集成。

1.2 MyBatis简介

MyBatis是一个优秀的持久层框架,它通过XML或注解将SQL语句与Java对象进行映射,提供了比JPA更加灵活的数据库操作方式。MyBatis支持动态SQL、缓存和插件等功能,适用于各种复杂的数据访问场景。

2. Spring Boot集成MyBatis的基本配置

2.1 创建Spring Boot项目

首先,使用Spring Initializr或其他方式创建一个Spring Boot项目,并引入必要的依赖。

  1. <!-- pom.xml -->
  2. <dependencies>
  3. <!-- Spring Boot Starter -->
  4. <dependency>
  5. <groupId>org.springframework.boot</groupId>
  6. <artifactId>spring-boot-starter</artifactId>
  7. </dependency>
  8. <!-- Spring Boot Starter MyBatis -->
  9. <dependency>
  10. <groupId>org.mybatis.spring.boot</groupId>
  11. <artifactId>mybatis-spring-boot-starter</artifactId>
  12. <version>2.1.4</version>
  13. </dependency>
  14. <!-- Spring Boot Starter DataSource -->
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter-jdbc</artifactId>
  18. </dependency>
  19. <!-- MySQL Connector -->
  20. <dependency>
  21. <groupId>mysql</groupId>
  22. <artifactId>mysql-connector-java</artifactId>
  23. <scope>runtime</scope>
  24. </dependency>
  25. <!-- Test dependencies -->
  26. <dependency>
  27. <groupId>org.springframework.boot</groupId>
  28. <artifactId>spring-boot-starter-test</artifactId>
  29. <scope>test</scope>
  30. </dependency>
  31. </dependencies>

2.2 配置数据源

application.properties文件中配置数据源信息。

  1. # application.properties
  2. spring.datasource.url=jdbc:mysql://localhost:3306/mydb
  3. spring.datasource.username=root
  4. spring.datasource.password=secret
  5. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

2.3 配置MyBatis

application.properties文件中配置MyBatis相关参数。

  1. # MyBatis configuration
  2. mybatis.mapper-locations=classpath:mapper/*.xml
  3. mybatis.type-aliases-package=com.example.model

2.4 创建数据库表

在MySQL数据库中创建一个示例表。

  1. CREATE TABLE user (
  2. id BIGINT AUTO_INCREMENT PRIMARY KEY,
  3. name VARCHAR(50) NOT NULL,
  4. email VARCHAR(50) NOT NULL
  5. );

2.5 创建实体类

创建一个与数据库表对应的实体类。

  1. package com.example.model;
  2. public class User {
  3. private Long id;
  4. private String name;
  5. private String email;
  6. // Getters and setters
  7. }

2.6 创建Mapper接口和XML映射文件

创建一个Mapper接口,并在mapper目录下创建对应的XML映射文件。

  1. package com.example.mapper;
  2. import java.util.List;
  3. import com.example.model.User;
  4. import org.apache.ibatis.annotations.*;
  5. public interface UserMapper {
  6. @Select("SELECT * FROM user WHERE id = #{id}")
  7. User getUserById(Long id);
  8. @Select("SELECT * FROM user")
  9. List<User> getAllUsers();
  10. @Insert("INSERT INTO user(name, email) VALUES(#{name}, #{email})")
  11. @Options(useGeneratedKeys = true, keyProperty = "id")
  12. void insertUser(User user);
  13. @Update("UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}")
  14. void updateUser(User user);
  15. @Delete("DELETE FROM user WHERE id = #{id}")
  16. void deleteUser(Long id);
  17. }

创建XML映射文件UserMapper.xml

  1. <!-- mapper/UserMapper.xml -->
  2. <?xml version="1.0" encoding="UTF-8" ?>
  3. <!DOCTYPE mapper
  4. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  5. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  6. <mapper namespace="com.example.mapper.UserMapper">
  7. <resultMap id="UserResultMap" type="com.example.model.User">
  8. <id column="id" property="id" />
  9. <result column="name" property="name" />
  10. <result column="email" property="email" />
  11. </resultMap>
  12. <select id="getUserById" resultMap="UserResultMap">
  13. SELECT * FROM user WHERE id = #{id}
  14. </select>
  15. <select id="getAllUsers" resultMap="UserResultMap">
  16. SELECT * FROM user
  17. </select>
  18. <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
  19. INSERT INTO user (name, email) VALUES (#{name}, #{email})
  20. </insert>
  21. <update id="updateUser">
  22. UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}
  23. </update>
  24. <delete id="deleteUser">
  25. DELETE FROM user WHERE id = #{id}
  26. </delete>
  27. </mapper>

2.7 创建Service类

创建一个Service类,用于处理业务逻辑。

  1. package com.example.service;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import com.example.mapper.UserMapper;
  6. import com.example.model.User;
  7. @Service
  8. public class UserService {
  9. @Autowired
  10. private UserMapper userMapper;
  11. public User getUserById(Long id) {
  12. return userMapper.getUserById(id);
  13. }
  14. public List<User> getAllUsers() {
  15. return userMapper.getAllUsers();
  16. }
  17. public void createUser(User user) {
  18. userMapper.insertUser(user);
  19. }
  20. public void updateUser(User user) {
  21. userMapper.updateUser(user);
  22. }
  23. public void deleteUser(Long id) {
  24. userMapper.deleteUser(id);
  25. }
  26. }

2.8 创建Controller类

创建一个Controller类,用于处理HTTP请求。

  1. package com.example.controller;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.*;
  5. import com.example.model.User;
  6. import com.example.service.UserService;
  7. @RestController
  8. @RequestMapping("/users")
  9. public class UserController {
  10. @Autowired
  11. private UserService userService;
  12. @GetMapping("/{id}")
  13. public User getUserById(@PathVariable Long id) {
  14. return userService.getUserById(id);
  15. }
  16. @GetMapping
  17. public List<User> getAllUsers() {
  18. return userService.getAllUsers();
  19. }
  20. @PostMapping
  21. public void createUser(@RequestBody User user) {
  22. userService.createUser(user);
  23. }
  24. @PutMapping
  25. public void updateUser(@RequestBody User user) {
  26. userService.updateUser(user);
  27. }
  28. @DeleteMapping("/{id}")
  29. public void deleteUser(@PathVariable Long id) {
  30. userService.deleteUser(id);
  31. }
  32. }

3. MyBatis动态SQL

MyBatis支持使用动态SQL来构建灵活的查询语句。动态SQL可以通过XML映射文件中的<if><choose><when><otherwise>等标签来实现。

3.1 使用动态SQL

UserMapper.xml中添加一个动态SQL查询示例。

  1. <!-- mapper/UserMapper.xml -->
  2. <mapper namespace="com.example.mapper.UserMapper">
  3. <resultMap id="UserResultMap" type="com.example.model.User">
  4. <id column="id" property="id" />
  5. <result column="name" property="name" />
  6. <result column="email" property="email" />
  7. </resultMap>
  8. <select id="getUserById" resultMap="UserResultMap">
  9. SELECT * FROM user WHERE id = #{id}
  10. </select>
  11. <select id="getAllUsers" resultMap="UserResultMap">
  12. SELECT * FROM user
  13. </select>
  14. <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
  15. INSERT INTO user (name, email) VALUES (#{name}, #{email})
  16. </insert>
  17. <update id="updateUser">
  18. UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}
  19. </update>
  20. <delete id="deleteUser">
  21. DELETE FROM user WHERE id = #{id}
  22. </delete>
  23. <!-- 动态SQL示例 -->
  24. <select id="findUsersByNameAndEmail" resultMap="UserResultMap">
  25. SELECT * FROM user
  26. <where>
  27. <if test="name
  28. != null">
  29. AND name = #{name}
  30. </if>
  31. <if test="email != null">
  32. AND email = #{email}
  33. </if>
  34. </where>
  35. </select>
  36. </mapper>

3.2 修改Mapper接口

UserMapper接口中添加对应的方法。

  1. package com.example.mapper;
  2. import java.util.List;
  3. import com.example.model.User;
  4. import org.apache.ibatis.annotations.*;
  5. public interface UserMapper {
  6. @Select("SELECT * FROM user WHERE id = #{id}")
  7. User getUserById(Long id);
  8. @Select("SELECT * FROM user")
  9. List<User> getAllUsers();
  10. @Insert("INSERT INTO user(name, email) VALUES(#{name}, #{email})")
  11. @Options(useGeneratedKeys = true, keyProperty = "id")
  12. void insertUser(User user);
  13. @Update("UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}")
  14. void updateUser(User user);
  15. @Delete("DELETE FROM user WHERE id = #{id}")
  16. void deleteUser(Long id);
  17. // 动态SQL方法
  18. List<User> findUsersByNameAndEmail(@Param("name") String name, @Param("email") String email);
  19. }

4. MyBatis分页插件

在实际应用中,分页查询是一个常见的需求。MyBatis支持通过分页插件来实现分页功能。

4.1 添加分页插件依赖

pom.xml中添加分页插件的依赖。

  1. <!-- pom.xml -->
  2. <dependency>
  3. <groupId>com.github.pagehelper</groupId>
  4. <artifactId>pagehelper-spring-boot-starter</artifactId>
  5. <version>1.2.12</version>
  6. </dependency>

4.2 配置分页插件

application.properties中配置分页插件参数。

  1. # application.properties
  2. pagehelper.helper-dialect=mysql
  3. pagehelper.reasonable=true
  4. pagehelper.support-methods-arguments=true
  5. pagehelper.params=count=countSql

4.3 使用分页插件

在Service类中使用分页插件进行分页查询。

  1. package com.example.service;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import com.github.pagehelper.PageHelper;
  6. import com.github.pagehelper.PageInfo;
  7. import com.example.mapper.UserMapper;
  8. import com.example.model.User;
  9. @Service
  10. public class UserService {
  11. @Autowired
  12. private UserMapper userMapper;
  13. public User getUserById(Long id) {
  14. return userMapper.getUserById(id);
  15. }
  16. public List<User> getAllUsers() {
  17. return userMapper.getAllUsers();
  18. }
  19. public void createUser(User user) {
  20. userMapper.insertUser(user);
  21. }
  22. public void updateUser(User user) {
  23. userMapper.updateUser(user);
  24. }
  25. public void deleteUser(Long id) {
  26. userMapper.deleteUser(id);
  27. }
  28. // 分页查询
  29. public PageInfo<User> getUsersByPage(int pageNum, int pageSize) {
  30. PageHelper.startPage(pageNum, pageSize);
  31. List<User> users = userMapper.getAllUsers();
  32. return new PageInfo<>(users);
  33. }
  34. }

5. MyBatis多数据源配置

在一些复杂的应用中,可能需要访问多个数据源。Spring Boot和MyBatis支持多数据源配置,下面我们将介绍如何配置和使用多数据源。

5.1 添加多数据源配置

application.properties中配置多个数据源。

  1. # application.properties
  2. # 数据源1
  3. spring.datasource.primary.url=jdbc:mysql://localhost:3306/primarydb
  4. spring.datasource.primary.username=root
  5. spring.datasource.primary.password=secret
  6. spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
  7. # 数据源2
  8. spring.datasource.secondary.url=jdbc:mysql://localhost:3306/secondarydb
  9. spring.datasource.secondary.username=root
  10. spring.datasource.secondary.password=secret
  11. spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

5.2 创建数据源配置类

创建一个数据源配置类,配置多个数据源。

  1. package com.example.config;
  2. import javax.sql.DataSource;
  3. import org.apache.ibatis.session.SqlSessionFactory;
  4. import org.mybatis.spring.SqlSessionFactoryBean;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.boot.context.properties.ConfigurationProperties;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.context.annotation.Configuration;
  10. import org.springframework.context.annotation.Primary;
  11. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  12. import org.springframework.boot.jdbc.DataSourceBuilder;
  13. @Configuration
  14. @MapperScan(basePackages = "com.example.mapper.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
  15. public class PrimaryDataSourceConfig {
  16. @Primary
  17. @Bean(name = "primaryDataSource")
  18. @ConfigurationProperties(prefix = "spring.datasource.primary")
  19. public DataSource primaryDataSource() {
  20. return DataSourceBuilder.create().build();
  21. }
  22. @Primary
  23. @Bean(name = "primarySqlSessionFactory")
  24. public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
  25. SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
  26. sessionFactoryBean.setDataSource(dataSource);
  27. return sessionFactoryBean.getObject();
  28. }
  29. @Primary
  30. @Bean(name = "primaryTransactionManager")
  31. public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {
  32. return new DataSourceTransactionManager(dataSource);
  33. }
  34. }
  1. package com.example.config;
  2. import javax.sql.DataSource;
  3. import org.apache.ibatis.session.SqlSessionFactory;
  4. import org.mybatis.spring.SqlSessionFactoryBean;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.boot.context.properties.ConfigurationProperties;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.context.annotation.Configuration;
  10. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  11. import org.springframework.boot.jdbc.DataSourceBuilder;
  12. @Configuration
  13. @MapperScan(basePackages = "com.example.mapper.secondary", sqlSessionFactoryRef = "secondarySqlSessionFactory")
  14. public class SecondaryDataSourceConfig {
  15. @Bean(name = "secondaryDataSource")
  16. @ConfigurationProperties(prefix = "spring.datasource.secondary")
  17. public DataSource secondaryDataSource() {
  18. return DataSourceBuilder.create().build();
  19. }
  20. @Bean(name = "secondarySqlSessionFactory")
  21. public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {
  22. SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
  23. sessionFactoryBean.setDataSource(dataSource);
  24. return sessionFactoryBean.getObject();
  25. }
  26. @Bean(name = "secondaryTransactionManager")
  27. public DataSourceTransactionManager secondaryTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {
  28. return new DataSourceTransactionManager(dataSource);
  29. }
  30. }

5.3 创建Mapper接口

com.example.mapper.primarycom.example.mapper.secondary包中创建Mapper接口。

  1. package com.example.mapper.primary;
  2. import java.util.List;
  3. import com.example.model.User;
  4. import org.apache.ibatis.annotations.*;
  5. public interface PrimaryUserMapper {
  6. @Select("SELECT * FROM user WHERE id = #{id}")
  7. User getUserById(Long id);
  8. @Select("SELECT * FROM user")
  9. List<User> getAllUsers();
  10. @Insert("INSERT INTO user(name, email) VALUES(#{name}, #{email})")
  11. @Options(useGeneratedKeys = true, keyProperty = "id")
  12. void insertUser(User user);
  13. @Update("UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}")
  14. void updateUser(User user);
  15. @Delete("DELETE FROM user WHERE id = #{id}")
  16. void deleteUser(Long id);
  17. }
  1. package com.example.mapper.secondary;
  2. import java.util.List;
  3. import com.example.model.Product;
  4. import org.apache.ibatis.annotations.*;
  5. public interface SecondaryProductMapper {
  6. @Select("SELECT * FROM product WHERE id = #{id}")
  7. Product getProductById(Long id);
  8. @Select("SELECT * FROM product")
  9. List<Product> getAllProducts();
  10. @Insert("INSERT INTO product(name, price) VALUES(#{name}, #{price})")
  11. @Options(useGeneratedKeys = true, keyProperty = "id")
  12. void insertProduct(Product product);
  13. @Update("UPDATE product SET name = #{name}, price = #{price} WHERE id = #{id}")
  14. void updateProduct(Product product);
  15. @Delete("DELETE FROM product WHERE id = #{id}")
  16. void deleteProduct(Long id);
  17. }

5.4 创建Service类

创建Service类,分别调用不同数据源的Mapper接口。

  1. package com.example.service;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import com.example.mapper.primary.PrimaryUserMapper;
  6. import com.example.mapper.secondary.SecondaryProductMapper;
  7. import com.example.model.User;
  8. import com.example.model.Product;
  9. @Service
  10. public class DataService {
  11. @Autowired
  12. private PrimaryUserMapper primaryUserMapper;
  13. @Autowired
  14. private SecondaryProductMapper secondaryProductMapper;
  15. // User methods
  16. public User getUserById(Long id) {
  17. return primaryUserMapper.getUserById(id);
  18. }
  19. public List<User> getAllUsers() {
  20. return primaryUserMapper.getAllUsers();
  21. }
  22. public void createUser(User user) {
  23. primaryUserMapper.insertUser(user);
  24. }
  25. public void updateUser(User user) {
  26. primaryUserMapper.updateUser(user);
  27. }
  28. public void deleteUser(Long id) {
  29. primaryUserMapper.deleteUser(id);
  30. }
  31. // Product methods
  32. public Product getProductById(Long id) {
  33. return secondaryProductMapper.getProductById(id);
  34. }
  35. public List<Product> getAllProducts() {
  36. return secondaryProductMapper.getAllProducts();
  37. }
  38. public void createProduct(Product product) {
  39. secondaryProductMapper.insertProduct(product);
  40. }
  41. public void updateProduct(Product product) {
  42. secondaryProductMapper.updateProduct(product);
  43. }
  44. public void deleteProduct(Long id) {
  45. secondaryProductMapper.deleteProduct(id);
  46. }
  47. }

5.5 创建Controller类

创建一个Controller类,调用Service方法处理HTTP请求。

  1. package com.example.controller;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.*;
  5. import com.example.model.User;
  6. import com.example.model.Product;
  7. import com.example.service.DataService;
  8. @RestController
  9. @RequestMapping("/data")
  10. public class DataController {
  11. @Autowired
  12. private DataService dataService;
  13. // User endpoints
  14. @GetMapping("/users/{id}")
  15. public User getUserById(@PathVariable Long id) {
  16. return dataService.getUserById(id);
  17. }
  18. @GetMapping("/users")
  19. public List<User> getAllUsers() {
  20. return dataService.getAllUsers();
  21. }
  22. @PostMapping("/users")
  23. public void createUser(@RequestBody User user) {
  24. dataService.createUser(user);
  25. }
  26. @PutMapping("/users")
  27. public void updateUser(@RequestBody User user) {
  28. dataService.updateUser(user);
  29. }
  30. @DeleteMapping("/users/{id}")
  31. public void deleteUser(@PathVariable Long id) {
  32. dataService.deleteUser(id);
  33. }
  34. // Product endpoints
  35. @GetMapping("/products/{id}")
  36. public Product getProductById(@PathVariable Long id) {
  37. return dataService.getProductById(id);
  38. }
  39. @GetMapping("/products")
  40. public List<Product> getAllProducts() {
  41. return dataService.getAllProducts();
  42. }
  43. @PostMapping("/products")
  44. public void createProduct(@RequestBody Product product) {
  45. dataService.createProduct(product);
  46. }
  47. @PutMapping("/products")
  48. public void updateProduct(@RequestBody Product product) {
  49. dataService.updateProduct(product);
  50. }
  51. @DeleteMapping("/products/{id}")
  52. public void deleteProduct(@PathVariable Long id) {
  53. dataService.deleteProduct(id);
  54. }
  55. }

6. MyBatis缓存

MyBatis支持一级缓存和二级缓存,通过配置缓存可以提高数据访问的性能。

6.1 一级缓存

MyBatis的一级缓存是SqlSession级别的缓存,默认情况下是开启的。每个SqlSession在操作过程中会缓存查询结果,直到SqlSession被关闭或清理。

6.2 二级缓存

MyBatis的二级缓存是Mapper级别的缓存,需要在Mapper映射文件中配置。

  1. <!-- mapper/UserMapper.xml -->
  2. <mapper namespace="com.example.mapper.UserMapper">
  3. <cache/>
  4. <resultMap id="UserResultMap" type="com.example.model.User">
  5. <id column="id" property="id" />
  6. <result column="name" property="name" />
  7. <result column="email" property="email" />
  8. </resultMap>
  9. <select id="getUserById" resultMap="UserResultMap">
  10. SELECT * FROM user WHERE id = #{id}
  11. </select>
  12. <select id="getAllUsers" resultMap="UserResultMap">
  13. SELECT * FROM user
  14. </select>
  15. <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
  16. INSERT INTO user (name, email) VALUES (#{name}, #{email})
  17. </insert>
  18. <update id="updateUser">
  19. UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}
  20. </update>
  21. <delete id="deleteUser">
  22. DELETE FROM user WHERE id = #{id}
  23. </delete>
  24. </mapper>

7. 单元测试和集成测试

为了确保MyBatis与Spring Boot集成的代码质量和可靠性,开发者应编写单元测试和集成测试。

7.1 单元测试

使用JUnit和Mockito编写Mapper接口的单元测试。

  1. package com.example.mapper;
  2. import static org.mockito.Mockito.*;
  3. import static org.junit.jupiter.api.Assertions.*;
  4. import org.junit.jupiter.api.BeforeEach;
  5. import org.junit.jupiter.api.Test;
  6. import org.mockito.InjectMocks;
  7. import org.mockito.Mock;
  8. import org.mockito.MockitoAnnotations;
  9. import com.example.model.User;
  10. public class UserMapperTest {
  11. @InjectMocks
  12. private UserMapper userMapper;
  13. @Mock
  14. private SqlSession sqlSession;
  15. @BeforeEach
  16. public void setUp() {
  17. MockitoAnnotations.openMocks(this);
  18. }
  19. @Test
  20. public void testGetUserById() {
  21. User user = new User();
  22. user.setId(1L);
  23. user.setName("John Doe");
  24. user.setEmail("john.doe@example.com");
  25. when(sqlSession.selectOne("com.example.mapper.UserMapper.getUserById", 1L)).thenReturn(user);
  26. User foundUser = userMapper.getUserById(1L);
  27. assertEquals("John Doe", foundUser.getName());
  28. verify(sqlSession, times(1)).selectOne("com.example.mapper.UserMapper.getUserById", 1L);
  29. }
  30. }

7.2 集成测试

使用Spring Boot的@SpringBootTest注解编写集成测试。

  1. package com.example.service;
  2. import static org.junit.jupiter.api.Assertions.*;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import com.example.model.User;
  7. @SpringBootTest
  8. public class UserServiceIntegrationTest {
  9. @Autowired
  10. private UserService userService;
  11. @Test
  12. public void testCreateUser() {
  13. User user = new User();
  14. user.setName("Jane Doe");
  15. user.setEmail("jane.doe@example.com");
  16. userService.createUser(user);
  17. User createdUser = userService.getUserById(user.getId());
  18. assertNotNull(createdUser);
  19. assertEquals("Jane Doe", createdUser.getName());
  20. }
  21. }

8. 总结

通过本文的介绍,我们详细了解了如何在Spring Boot项目中集成MyBatis,涵盖了基本配置、动态SQL、多数据源、分页、缓存以及单元测试和集成测试等多个方面。Spring Boot与MyBatis的结合,使得我们能够灵活高效地进行数据访问和处理,提升了开发效率和代码质量。