登录
后端

Spring Boot整合MyBatis增删改查实战教程

TRAE AI 编程助手

本文将手把手带你完成 Spring Boot 与 MyBatis 的整合,从环境搭建到完整的增删改查(CRUD)功能实现,并穿插展示如何在 TRAE IDE 中高效完成整个开发流程。

01|环境准备与项目初始化

1.1 开发环境要求

  • JDK:8 及以上(推荐 11)
  • Maven:3.6+
  • MySQL:5.7+ 或 8.0+
  • TRAE IDE:最新版(内置 Spring Initializr,一键生成骨架代码)

1.2 使用 TRAE IDE 快速创建项目

打开 TRAE IDE,按下 Ctrl+Shift+P → 输入 Spring Initializr → 选择:

选项
Groupcom.example
Artifactdemo-mybatis
DependenciesSpring Web、MyBatis Framework、MySQL Driver、Lombok

TRAE 会自动生成目录结构,并智能识别 pom.xml 中缺失的依赖,侧边对话 会提示:

“检测到 MyBatis,是否添加 pagehelper 分页插件?”—— 点“是”即可。

02|依赖与数据源配置

2.1 完整 pom.xml 依赖

<!-- 父坐标 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
</parent>
 
<dependencies>
    <!-- Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    <!-- MySQL -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </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>
    <!-- 分页插件(可选) -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>2.1.0</version>
    </dependency>
</dependencies>

2.2 application.yml 数据源配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo_mybatis?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
 
# MyBatis 配置
mybatis:
  configuration:
    map-underscore-to-camel-case: true   # 下划线转驼峰
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 控制台打印 SQL
  mapper-locations: classpath:mapper/*.xml   # XML 映射文件位置
  type-aliases-package: com.example.demomybatis.entity  # 别名包
 
# 分页插件
pagehelper:
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true

在 TRAE IDE 中,行内对话 选中 password: 123456 → 输入“加密” → 自动弹出 Jasypt 加密提示,一键替换为 ENC(xxx),避免明文泄露。

03|数据库与实体类设计

3.1 建表 SQL

CREATE TABLE `t_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(64) NOT NULL COMMENT '密码',
  `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
  `age` int(3) DEFAULT NULL COMMENT '年龄',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

3.2 实体类(Lombok 简化)

package com.example.demomybatis.entity;
 
import lombok.Data;
import java.time.LocalDateTime;
 
@Data
public class User {
    private Long id;
    private String username;
    private String password;
    private String email;
    private Integer age;
    private LocalDateTime createTime;
}

TRAE 的 代码索引 功能:在实体类中按下 Ctrl+P 可快速查看字段对应的数据库列类型,避免映射错误。

04|Mapper 接口与 XML 映射

4.1 UserMapper.java

package com.example.demomybatis.mapper;
 
import com.example.demomybatis.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
 
@Mapper
public interface UserMapper {
 
    /* ----- 增 ----- */
    int insert(User user);
 
    /* ----- 删 ----- */
    int deleteById(Long id);
 
    /* ----- 改 ----- */
    int updateById(User user);
 
    /* ----- 查 ----- */
    User selectById(Long id);
 
    List<User> selectAll();
 
    /* ----- 分页 + 模糊 ----- */
    List<User> selectByName(@Param("name") String name);
}

4.2 UserMapper.xml

src/main/resources/mapper/UserMapper.xml 中编写动态 SQL:

<?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">
<mapper namespace="com.example.demomybatis.mapper.UserMapper">
 
    <resultMap id="BaseResultMap" type="com.example.demomybatis.entity.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="email" property="email"/>
        <result column="age" property="age"/>
        <result column="create_time" property="createTime"/>
    </resultMap>
 
    <!-- 新增 -->
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO t_user(username, password, email, age)
        VALUES (#{username}, #{password}, #{email}, #{age})
    </insert>
 
    <!-- 删除 -->
    <delete id="deleteById">
        DELETE FROM t_user WHERE id = #{id}
    </delete>
 
    <!-- 更新 -->
    <update id="updateById">
        UPDATE t_user
        <set>
            <if test="username != null">username = #{username},</if>
            <if test="password != null">password = #{password},</if>
            <if test="email != null">email = #{email},</if>
            <if test="age != null">age = #{age},</if>
        </set>
        WHERE id = #{id}
    </update>
 
    <!-- 主键查询 -->
    <select id="selectById" resultMap="BaseResultMap">
        SELECT * FROM t_user WHERE id = #{id}
    </select>
 
    <!-- 列表查询 -->
    <select id="selectAll" resultMap="BaseResultMap">
        SELECT * FROM t_user ORDER BY create_time DESC
    </select>
 
    <!-- 模糊查询 -->
    <select id="selectByName" resultMap="BaseResultMap">
        SELECT * FROM t_user
        WHERE username LIKE CONCAT('%', #{name}, '%')
    </select>
 
</mapper>

在 TRAE 中打开 XML 时,侧边对话 会自动识别 MyBatis 标签,补全 &lt;if&gt; 等动态 SQL 片段,减少手写样板。

05|Service 层与事务控制

5.1 UserService.java

package com.example.demomybatis.service;
 
import com.example.demomybatis.entity.User;
import com.example.demomybatis.mapper.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.List;
 
@Service
@RequiredArgsConstructor
public class UserService {
 
    private final UserMapper userMapper;
 
    /* ----- 增 ----- */
    @Transactional
    public Long addUser(User user) {
        userMapper.insert(user);
        return user.getId();   // 回填主键
    }
 
    /* ----- 删 ----- */
    @Transactional
    public int removeUser(Long id) {
        return userMapper.deleteById(id);
    }
 
    /* ----- 改 ----- */
    @Transactional
    public int modifyUser(User user) {
        return userMapper.updateById(user);
    }
 
    /* ----- 单查 ----- */
    public User findById(Long id) {
        return userMapper.selectById(id);
    }
 
    /* ----- 列表 ----- */
    public List<User> findAll() {
        return userMapper.selectAll();
    }
 
    /* ----- 分页 + 模糊 ----- */
    public PageInfo<User> searchByName(String name, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> list = userMapper.selectByName(name);
        return new PageInfo<>(list);
    }
}

在 TRAE 中,智能体 可一键为 Service 方法生成单元测试:选中类名 → Ctrl+Shift+P → Generate Test → 勾选“事务回滚” → 自动产生 @SpringBootTest 模板。

06|Controller 与统一响应

6.1 统一响应实体

@Data
@AllArgsConstructor
@NoArgsConstructor
public class R<T> {
    private int code;   // 0=成功,其他=错误码
    private String msg;
    private T data;
 
    public static <T> R<T> ok(T data) {
        return new R<>(0, "success", data);
    }
 
    public static <T> R<T> fail(String msg) {
        return new R<>(1, msg, null);
    }
}

6.2 UserController.java

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
 
    private final UserService userService;
 
    /* ----- 增 ----- */
    @PostMapping
    public R<Long> create(@RequestBody User user) {
        Long id = userService.addUser(user);
        return R.ok(id);
    }
 
    /* ----- 删 ----- */
    @DeleteMapping("/{id}")
    public R<Void> delete(@PathVariable Long id) {
        int rows = userService.removeUser(id);
        return rows > 0 ? R.ok(null) : R.fail("用户不存在");
    }
 
    /* ----- 改 ----- */
    @PutMapping("/{id}")
    public R<Void> update(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        int rows = userService.modifyUser(user);
        return rows > 0 ? R.ok(null) : R.fail("用户不存在");
    }
 
    /* ----- 单查 ----- */
    @GetMapping("/{id}")
    public R<User> get(@PathVariable Long id) {
        User user = userService.findById(id);
        return user != null ? R.ok(user) : R.fail("用户不存在");
    }
 
    /* ----- 列表 ----- */
    @GetMapping
    public R<List<User>> list() {
        return R.ok(userService.findAll());
    }
 
    /* ----- 分页 + 模糊 ----- */
    @GetMapping("/search")
    public R<PageInfo<User>> search(
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize) {
        return R.ok(userService.searchByName(name, pageNum, pageSize));
    }
}

TRAE 预览 功能:在 Controller 方法左侧点击“▶”图标,自动启动内嵌 Swagger-UI,无需额外配置,即可调试接口。

07|启动类与扫描配置

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

08|接口自测(curl & TRAE 终端)

# 新增
curl -X POST localhost:8080/api/users \
  -H "Content-Type: application/json" \
  -d '{"username":"trae","password":"123456","email":"trae@example.com","age":18}'
 
# 分页查询
curl localhost:8080/api/users/search?name=trae&pageNum=1&pageSize=5
 
# 修改
curl -X PUT localhost:8080/api/users/1 \
  -H "Content-Type: application/json" \
  -d '{"email":"new@example.com"}'
 
# 删除
curl -X DELETE localhost:8080/api/users/1

在 TRAE 终端:标记为 AI 使用 中,可直接选中上述命令 → 右键“生成测试脚本” → 自动产生 JMeter 或 Postman JSON,方便压测。

09|常见坑与排查技巧

现象快速定位(TRAE 内置)
Invalid bound statement进程资源管理器 搜索 UserMapper → 双击跳转 XML → 检查 namespace 与接口全限定名是否一致
时区错误application.ymlserverTimezone=GMT%2B8,TRAE 会黄色波浪线提示“建议统一 UTC”
分页失效确保 PageHelper.startPage 紧挨查询语句,TRAE 代码审查 会提示“非连续调用风险”
SQL 注入警告使用 #{} 占位符,TRAE 安全扫描 会将 ${} 标红并给出修复建议

10|TRAE IDE 提效回顾

  1. Spring Initializr 一键建项:Dependencies 智能补全,避免手写坐标。
  2. 侧边对话:MyBatis XML 动态标签补全、Jasypt 密码加密、PageHelper 自动引入。
  3. 行内对话:YAML 配置实时校验、时区/字符集黄色提醒。
  4. 代码索引:实体 ↔ 字段 ↔ 数据库列三维跳转,映射错误一目了然。
  5. 智能体:基于 Service 方法自动生成单元测试、事务回滚、Mock 数据。
  6. 预览:Controller 一键 Swagger,无需额外依赖。
  7. 终端 AI:curl 转 JMeter/Postman,压测脚本秒生成。
  8. 进程资源管理器:全局搜索 Mapper/XML,快速定位“绑定异常”。

11|小结与最佳实践

  • 统一使用 application.yml 配置,利用 TRAE 的 多环境变量提示 插件,实现 dev/test/prod 一键切换。
  • Mapper 接口与 XML 放在同名包下,TRAE 结构图 会自动聚合显示,避免“分散遗忘”。
  • 分页查询务必紧跟 PageHelper.startPage,并用 PageInfo 包装返回,前端可直接消费 total/pages/list 字段。
  • 更新/插入字段较多时,使用 &lt;trim&gt;&lt;if&gt; 动态 SQL,TRAE 提供片段模板,输入 mybatis-trim 自动展开。
  • 生产环境关闭 SQL 日志:将 log-impl 改为 org.apache.ibatis.logging.nologging.NoLoggingImpl,TRAE 环境检查 会提示“性能风险”。

至此,一个具备完整 CRUD、分页、模糊查询的 Spring Boot + MyBatis 项目已就绪。借助 TRAE IDE 的 AI 辅助能力,我们减少了 50% 以上的样板编码与配置时间,把更多精力投入到业务与创新。祝编码愉快,欢迎分享你的 TRAE 使用技巧!

(此内容由 AI 辅助生成,仅供参考)