Spring Boot 整合 MyBatis 实现数据库增删改查(含分页)!手把手教你从零到一
上周,实习生小钱问我:
“马哥,我们之前直接用 JdbcTemplate 连数据库,现在项目要换 MyBatis,感觉好复杂啊……有没有一个完整例子,从配置到增删改查都讲一遍?”
我笑了:“MyBatis 真的不复杂,复杂的是你没找到正确的入门姿势。”
今天,我就用 一个完整的用户管理项目,手把手教你:Spring Boot 如何整合 MyBatis,包含增删改查 + 分页查询,复制粘贴就能跑通!
🛠️ 一、准备工作(只需 2 分钟)
你需要:
- MySQL(已按上篇文章配置好)
- JDK 17(或 8/11)
- IDEA
- 已创建
testdb数据库和user表(上篇文章已建)
💻 二、整合 MyBatis 的 5 个步骤(完整代码)
步骤 1:添加 MyBatis 依赖(pom.xml)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
💡 注意:
- 版本号
3.0.2适配 Spring Boot 3.x- 2.x 版本用
2.3.1(适配 Spring Boot 2.x)
步骤 2:配置 MyBatis(application.yml)
spring:
datasource:
url: jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml # 👈 指定 XML 映射文件位置
type-aliases-package: com.example.mybatisdemo.entity # 👈 实体类别名包
configuration:
map-underscore-to-camel-case: true # 👈 数据库下划线字段自动映射到 Java 驼峰属性
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 👈 开发时打印 SQL
🔍 关键配置解释:
mapper-locations:告诉 MyBatis 去哪找 SQL 映射文件type-aliases-package:简化 XML 中的类名书写map-underscore-to-camel-case:user_name→userName(重要!)log-impl:开发时能看到执行的 SQL,方便调试
步骤 3:创建实体类(entity/User.java)
package com.example.mybatisdemo.entity;
public class User {
private Long id;
private String name;
private String email;
// 构造函数(省略)
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
// getter / setter(IDEA 生成)
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
步骤 4:创建 Mapper 接口(mapper/UserMapper.java)
package com.example.mybatisdemo.mapper;
import com.example.mybatisdemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper // 👈 关键注解,让 Spring 管理这个接口
public interface UserMapper {
// 查询所有用户
List<User> findAll();
// 根据 ID 查询用户
User findById(@Param("id") Long id);
// 新增用户
int insert(User user);
// 更新用户
int update(User user);
// 删除用户
int deleteById(@Param("id") Long id);
// 分页查询(后面实现)
List<User> findByPage(@Param("offset") int offset, @Param("limit") int limit);
// 获取总记录数(分页用)
int countAll();
}
💡 @Param 注解:
当方法参数多于 1 个,或在 XML 中需要引用参数名时,必须加@Param
单个参数可不加(如insert(User user))
步骤 5:创建 XML 映射文件(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">
<mapper namespace="com.example.mybatisdemo.mapper.UserMapper">
<!-- 结果映射 -->
<resultMap id="UserResultMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="UserResultMap">
SELECT id, name, email FROM user
</select>
<!-- 根据 ID 查询 -->
<select id="findById" parameterType="java.lang.Long" resultMap="UserResultMap">
SELECT id, name, email FROM user WHERE id = #{id}
</select>
<!-- 新增 -->
<insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (name, email) VALUES (#{name}, #{email})
</insert>
<!-- 更新 -->
<update id="update" parameterType="User">
UPDATE user SET name = #{name}, email = #{email} WHERE id = #{id}
</update>
<!-- 删除 -->
<delete id="deleteById" parameterType="java.lang.Long">
DELETE FROM user WHERE id = #{id}
</delete>
<!-- 分页查询 -->
<select id="findByPage" resultMap="UserResultMap">
SELECT id, name, email FROM user LIMIT #{offset}, #{limit}
</select>
<!-- 总记录数 -->
<select id="countAll" resultType="java.lang.Integer">
SELECT COUNT(*) FROM user
</select>
</mapper>
🔍 XML 关键点:
namespace:必须是对应的 Mapper 接口全限定名#{}:参数占位符(防 SQL 注入)useGeneratedKeys="true":新增后返回自增主键LIMIT #{offset}, #{limit}:MySQL 分页语法
步骤 6:创建 Service(service/UserService.java)
package com.example.mybatisdemo.service;
import com.example.mybatisdemo.entity.User;
import com.example.mybatisdemo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<User> getAllUsers() {
return userMapper.findAll();
}
public User getUserById(Long id) {
return userMapper.findById(id);
}
public User createUser(User user) {
userMapper.insert(user);
return user;
}
public User updateUser(User user) {
userMapper.update(user);
return user;
}
public void deleteUser(Long id) {
userMapper.deleteById(id);
}
// 分页查询
public List<User> getUsersByPage(int page, int size) {
int offset = (page - 1) * size;
return userMapper.findByPage(offset, size);
}
public int getTotalCount() {
return userMapper.countAll();
}
}
步骤 7:创建 Controller(controller/UserController.java)
package com.example.mybatisdemo.controller;
import com.example.mybatisdemo.entity.User;
import com.example.mybatisdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.createUser(user);
}
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
return userService.updateUser(user);
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return "OK";
}
// 分页接口
@GetMapping("/page")
public Map<String, Object> getUsersByPage(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
List<User> users = userService.getUsersByPage(page, size);
int total = userService.getTotalCount();
Map<String, Object> result = new HashMap<>();
result.put("data", users);
result.put("total", total);
result.put("page", page);
result.put("size", size);
return result;
}
}
▶️ 三、运行验证(30 秒搞定)
1. 启动项目
确保 MySQL 连接配置正确,启动 MybatisDemoApplication
2. 用 Postman 测试
新增用户:
POST http://localhost:8080/api/users
Content-Type: application/json
{
"name": "张三",
"email": "zhangsan@example.com"
}
查询所有:
GET http://localhost:8080/api/users
分页查询:
GET http://localhost:8080/api/users/page?page=1&size=5
✅ 控制台会打印 SQL 语句,看到 SELECT、INSERT 等,说明成功!
四、Bonus:MyBatis 常见坑点
坑 1:Invalid bound statement
原因:XML 文件位置不对,或
namespace写错
解决:检查mapper-locations路径,确保 XML 在resources/mapper/下
坑 2:@Param 忘记加
原因:多参数方法在 XML 中引用不到
解决:加@Param("paramName")
坑 3:字段名不匹配
原因:数据库
user_namevs JavauserName
解决:配置map-underscore-to-camel-case: true
💬 六、写在最后
MyBatis 真的不难,难的是配置和参数映射的细节。
记住三句话:
- XML 文件必须在
resources/mapper/目录下- 多参数方法必须加
@Param- 下划线字段自动映射
map-underscore-to-camel-case
学会 MyBatis,你就掌握了 SQL 与 Java 对象之间的桥梁!
互动时间:
你用 MyBatis 遇到过什么奇怪的错误?是 XML 位置?还是参数映射?
欢迎评论区分享!点赞最高的送《MyBatis 实战速查手册》PDF!
下期预告:
《Spring Boot 整合 Redis 缓存用户登录信息(含过期时间)》
👉 关注我,少走弯路,快速进阶!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)