Spring Boot 整合 MyBatis

Spring Boot 整合 MyBatis 是 Java 后端开发中非常经典的组合,能够快速实现数据访问层的开发。以下是详细的整合步骤和核心知识点:

一、环境准备

1. 依赖引入(Maven)

在 pom.xml 中添加核心依赖:

<!-- Spring Boot 父工程 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version> <!-- 版本可根据需求选择 -->
</parent>

<dependencies>
    <!-- Spring Boot Web 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- MyBatis 整合 Spring Boot  Starter -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
    
    <!-- 数据库驱动(以 MySQL 为例) -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
    <!-- 数据库连接池(HikariCP,Spring Boot 默认) -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
    </dependency>
    
    <!-- Lombok(简化实体类代码) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
    <!-- 单元测试 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
2. 数据库配置

在 application.yml(或 application.properties)中配置数据库连接信息:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver  # MySQL 8+ 驱动
    url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    hikari:
      maximum-pool-size: 10  # 连接池最大连接数
      minimum-idle: 5        # 最小空闲连接数
      idle-timeout: 300000   # 空闲连接超时时间(毫秒)

# MyBatis 配置
mybatis:
  mapper-locations: classpath:mapper/*.xml  # Mapper XML 文件路径
  type-aliases-package: com.example.entity  # 实体类包路径(简化 XML 中的类名)
  configuration:
    map-underscore-to-camel-case: true  # 开启下划线转驼峰(如数据库字段 user_name → 实体类 userName)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印 SQL 日志(开发环境用)

二、核心组件开发

1. 实体类(Entity)

对应数据库表结构,使用 Lombok 简化代码:

package com.example.entity;

import lombok.Data;

@Data  // 自动生成 getter/setter/toString 等方法
public class User {
    private Long id;
    private String username;  // 对应数据库 user_name 字段(下划线转驼峰生效)
    private Integer age;
    private String email;
}
2. Mapper 接口(数据访问层)

定义数据库操作方法,通过注解或 XML 编写 SQL:

package com.example.mapper;

import com.example.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper  // 标记为 MyBatis Mapper 接口(或在启动类用 @MapperScan 批量扫描)
public interface UserMapper {

    // 1. 注解方式编写 SQL
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getById(Long id);

    @Insert("INSERT INTO user(username, age, email) VALUES(#{username}, #{age}, #{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id")  // 自动返回自增主键
    int insert(User user);

    // 2. XML 方式编写 SQL(推荐复杂 SQL 使用)
    List<User> findAll();  // 对应 UserMapper.xml 中的 findAll 方法
    
    @Update("UPDATE user SET username = #{username}, age = #{age} WHERE id = #{id}")
    int update(User user);
    
    @Delete("DELETE FROM user WHERE id = #{id}")
    int delete(Long id);
}
3. Mapper XML 文件(可选)

复杂 SQL 建议写在 XML 中,路径对应 application.yml 中的 mapper-locations

创建 src/main/resources/mapper/UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- namespace 对应 Mapper 接口全路径 -->
<mapper namespace="com.example.mapper.UserMapper">

    <!-- 结果集映射(可选,字段名与实体类一致时可省略) -->
    <resultMap id="BaseResultMap" type="User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="age" property="age"/>
        <result column="email" property="email"/>
    </resultMap>

    <!-- 对应 UserMapper 接口的 findAll 方法 -->
    <select id="findAll" resultMap="BaseResultMap">
        SELECT * FROM user ORDER BY id DESC
    </select>

    <!-- 复杂查询示例(条件查询) -->
    <select id="findByCondition" parameterType="User" resultMap="BaseResultMap">
        SELECT * FROM user
        <where>
            <if test="username != null and username != ''">
                AND username LIKE CONCAT('%', #{username}, '%')
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>
</mapper>
4. 服务层(Service)

封装业务逻辑,调用 Mapper 接口:

package com.example.service;

import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class UserService {

    @Resource  // 注入 Mapper(或用 @Autowired)
    private UserMapper userMapper;

    public User getById(Long id) {
        return userMapper.getById(id);
    }

    public List<User> findAll() {
        return userMapper.findAll();
    }

    public int addUser(User user) {
        return userMapper.insert(user);
    }

    public int updateUser(User user) {
        return userMapper.update(user);
    }

    public int deleteUser(Long id) {
        return userMapper.delete(id);
    }
}
5. 控制层(Controller)

提供 API 接口,调用 Service 层:

package com.example.controller;

import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/{id}")
    public User getById(@PathVariable Long id) {
        return userService.getById(id);
    }

    @GetMapping("/all")
    public List<User> findAll() {
        return userService.findAll();
    }

    @PostMapping
    public int add(@RequestBody User user) {
        return userService.addUser(user);
    }

    @PutMapping
    public int update(@RequestBody User user) {
        return userService.updateUser(user);
    }

    @DeleteMapping("/{id}")
    public int delete(@PathVariable Long id) {
        return userService.deleteUser(id);
    }
}
6. 启动类

添加 @MapperScan 扫描 Mapper 接口(替代每个接口加 @Mapper):

package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mapper")  // 扫描 Mapper 接口所在包
public class MyBatisApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyBatisApplication.class, args);
    }
}

三、关键配置与优化

1. 批量操作

通过 XML 实现批量插入 / 更新:

<!-- 批量插入 -->
<insert id="batchInsert" parameterType="java.util.List">
    INSERT INTO user(username, age, email)
    VALUES
    <foreach collection="list" item="item" separator=",">
        (#{item.username}, #{item.age}, #{item.email})
    </foreach>
</insert>
2. 分页查询

集成 pagehelper 插件实现分页:

<!-- 添加依赖 -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.2</version>
</dependency>

使用方式:

// Service 层
public PageInfo<User> findByPage(int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);  // 开启分页
    List<User> list = userMapper.findAll();
    return new PageInfo<>(list);  // 封装分页结果
}
3. 事务管理

在 Service 层添加 @Transactional 注解开启事务:

@Service
public class UserService {
    @Transactional  // 方法内的数据库操作具有事务性
    public void batchOperation() {
        userMapper.insert(new User("A", 20, "a@test.com"));
        int i = 1 / 0;  // 模拟异常,事务会回滚
        userMapper.insert(new User("B", 21, "b@test.com"));
    }
}

四、常见问题与解决方案

  1. Mapper 接口注入失败

    • 确保 @Mapper 注解或 @MapperScan 配置正确。
    • 检查 Mapper 接口与 XML 文件的 namespace 是否一致。
  2. 字段映射问题

    • 开启 map-underscore-to-camel-case: true 解决下划线与驼峰命名冲突。
    • 复杂映射使用 <resultMap> 手动指定。
  3. SQL 日志不打印

    • 配置 mybatis.configuration.log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  4. 分页插件不生效

    • 确保 PageHelper.startPage() 放在查询方法之前,且紧跟查询逻辑。

五、总结

Spring Boot 整合 MyBatis 的核心步骤:

  1. 引入依赖(MyBatis Starter + 数据库驱动)。
  2. 配置数据库连接和 MyBatis 基础参数。
  3. 开发实体类、Mapper 接口(注解 / XML 写 SQL)、Service、Controller。
  4. 通过 @Mapper 或 @MapperScan 注册 Mapper 接口。

这种整合方式兼顾了 MyBatis 的灵活性(SQL 可控)和 Spring Boot 的便捷性(自动配置),适合大多数企业级应用开发。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值