Java Boot整合MyBatis案例实操
本文将演示如何使用Spring Boot整合MyBatis框架,实现完整的CRUD操作。

环境准备
1 技术版本
- JDK 1.8+
- Spring Boot 2.3.x
- MyBatis 3.5.x
- MySQL 5.7+
- Maven 3.6+
创建项目
1 使用Spring Initializr创建项目
通过 https://start.spring.io/ 或IDE创建项目,选择以下依赖:
- Spring Web
- MyBatis Framework
- MySQL Driver
2 完整pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>mybatis-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis-demo</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Spring Boot 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>2.1.4</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
数据库准备
1 创建数据库和表
CREATE DATABASE IF NOT EXISTS mybatis_demo DEFAULT CHARACTER SET utf8mb4;
USE mybatis_demo;
CREATE TABLE t_user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
email VARCHAR(100),
phone VARCHAR(20),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入测试数据
INSERT INTO t_user (username, password, email, phone) VALUES
('admin', '123456', 'admin@example.com', '13800138000'),
('zhangsan', 'abc123', 'zhangsan@example.com', '13900139000'),
('lisi', 'def456', 'lisi@example.com', '13700137000');
项目配置
1 application.yml配置
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
hikari:
minimum-idle: 5
maximum-pool-size: 20
idle-timeout: 30000
max-lifetime: 1800000
connection-timeout: 30000
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.mybatisdemo.entity
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 分页配置
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
代码实现
1 实体类
package com.example.mybatisdemo.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class User {
private Integer id;
private String username;
private String password;
private String email;
private String phone;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
2 Mapper接口
package com.example.mybatisdemo.mapper;
import com.example.mybatisdemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
// 根据ID查询
User findById(Integer id);
// 查询所有用户
List<User> findAll();
// 根据用户名模糊查询
List<User> findByUsername(String username);
// 新增用户
int insert(User user);
// 更新用户
int update(User user);
// 删除用户
int deleteById(Integer id);
// 批量插入
int batchInsert(List<User> users);
// 统计总数
long count();
}
3 Mapper XML文件
创建 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">
<mapper namespace="com.example.mybatisdemo.mapper.UserMapper">
<resultMap id="BaseResultMap" type="User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phone" property="phone"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<sql id="Base_Column_List">
id, username, password, email, phone, create_time, update_time
</sql>
<!-- 根据ID查询 -->
<select id="findById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM t_user
WHERE id = #{id}
</select>
<!-- 查询所有 -->
<select id="findAll" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM t_user
ORDER BY id DESC
</select>
<!-- 根据用户名模糊查询 -->
<select id="findByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM t_user
WHERE username LIKE CONCAT('%', #{username}, '%')
</select>
<!-- 新增用户 -->
<insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_user (username, password, email, phone)
VALUES (#{username}, #{password}, #{email}, #{phone})
</insert>
<!-- 更新用户 -->
<update id="update" parameterType="User">
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="phone != null">phone = #{phone}</if>
</set>
WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteById" parameterType="java.lang.Integer">
DELETE FROM t_user WHERE id = #{id}
</delete>
<!-- 批量插入 -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO t_user (username, password, email, phone)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.username}, #{item.password}, #{item.email}, #{item.phone})
</foreach>
</insert>
<!-- 统计总数 -->
<select id="count" resultType="java.lang.Long">
SELECT COUNT(*) FROM t_user
</select>
</mapper>
4 Service层
package com.example.mybatisdemo.service;
import com.example.mybatisdemo.entity.User;
import com.example.mybatisdemo.mapper.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User findById(Integer id) {
return userMapper.findById(id);
}
public List<User> findAll() {
return userMapper.findAll();
}
// 分页查询
public PageInfo<User> findByPage(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.findAll();
return new PageInfo<>(users);
}
public List<User> findByUsername(String username) {
return userMapper.findByUsername(username);
}
@Transactional
public int insert(User user) {
return userMapper.insert(user);
}
@Transactional
public int update(User user) {
return userMapper.update(user);
}
@Transactional
public int deleteById(Integer id) {
return userMapper.deleteById(id);
}
@Transactional
public int batchInsert(List<User> users) {
return userMapper.batchInsert(users);
}
public long count() {
return userMapper.count();
}
}
5 Controller层
package com.example.mybatisdemo.controller;
import com.example.mybatisdemo.entity.User;
import com.example.mybatisdemo.service.UserService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
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 ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.findAll();
return ResponseEntity.ok(users);
}
// 分页查询
@GetMapping("/page")
public ResponseEntity<PageInfo<User>> getUsersByPage(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
PageInfo<User> pageInfo = userService.findByPage(pageNum, pageSize);
return ResponseEntity.ok(pageInfo);
}
// 根据ID查询
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Integer id) {
User user = userService.findById(id);
if (user == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(user);
}
// 根据用户名搜索
@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(@RequestParam String username) {
List<User> users = userService.findByUsername(username);
return ResponseEntity.ok(users);
}
// 新增用户
@PostMapping
public ResponseEntity<Map<String, Object>> createUser(@RequestBody User user) {
int result = userService.insert(user);
Map<String, Object> response = new HashMap<>();
response.put("success", result > 0);
response.put("id", user.getId());
response.put("message", result > 0 ? "创建成功" : "创建失败");
return ResponseEntity.ok(response);
}
// 更新用户
@PutMapping("/{id}")
public ResponseEntity<Map<String, Object>> updateUser(
@PathVariable Integer id, @RequestBody User user) {
user.setId(id);
int result = userService.update(user);
Map<String, Object> response = new HashMap<>();
response.put("success", result > 0);
response.put("message", result > 0 ? "更新成功" : "更新失败");
return ResponseEntity.ok(response);
}
// 删除用户
@DeleteMapping("/{id}")
public ResponseEntity<Map<String, Object>> deleteUser(@PathVariable Integer id) {
int result = userService.deleteById(id);
Map<String, Object> response = new HashMap<>();
response.put("success", result > 0);
response.put("message", result > 0 ? "删除成功" : "删除失败");
return ResponseEntity.ok(response);
}
// 批量插入
@PostMapping("/batch")
public ResponseEntity<Map<String, Object>> batchInsert(@RequestBody List<User> users) {
int result = userService.batchInsert(users);
Map<String, Object> response = new HashMap<>();
response.put("success", result > 0);
response.put("count", result);
response.put("message", result > 0 ? "批量插入成功" : "批量插入失败");
return ResponseEntity.ok(response);
}
// 统计用户总数
@GetMapping("/count")
public ResponseEntity<Map<String, Object>> getUserCount() {
long count = userService.count();
Map<String, Object> response = new HashMap<>();
response.put("count", count);
return ResponseEntity.ok(response);
}
}
6 启动类
package com.example.mybatisdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MybatisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisDemoApplication.class, args);
}
}
API测试
1 使用curl测试
# 获取所有用户
curl http://localhost:8080/api/users
# 分页查询
curl "http://localhost:8080/api/users/page?pageNum=1&pageSize=5"
# 根据ID查询
curl http://localhost:8080/api/users/1
# 搜索用户
curl "http://localhost:8080/api/users/search?username=admin"
# 新增用户
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"username":"wangwu","password":"654321","email":"wangwu@example.com","phone":"13600136000"}'
# 更新用户
curl -X PUT http://localhost:8080/api/users/1 \
-H "Content-Type: application/json" \
-d '{"username":"admin_new","email":"admin_new@example.com"}'
# 删除用户
curl -X DELETE http://localhost:8080/api/users/3
# 批量插入
curl -X POST http://localhost:8080/api/users/batch \
-H "Content-Type: application/json" \
-d '[
{"username":"user1","password":"123","email":"user1@test.com"},
{"username":"user2","password":"456","email":"user2@test.com"}
]'
# 统计用户总数
curl http://localhost:8080/api/users/count
2 使用Postman测试
- 打开Postman
- 导入上述API接口
- 逐个测试CRUD操作
常见问题解决
1 数据库连接问题
错误:Communications link failure
解决:检查MySQL服务是否启动,连接配置是否正确
2 Mapper找不到
错误:Invalid bound statement (not found)
解决:检查application.yml中mapper-locations路径是否正确
确保Mapper接口有@Mapper注解
3 事务问题
如果批量操作出现不一致,检查:
@Service注解是否添加
@Transactional注解是否配置正确
本文通过完整的案例演示了Spring Boot整合MyBatis的实现过程:
- 配置整合:通过starter简化配置
- 实体映射:使用MyBatis注解和XML双方式
- 数据操作:实现完整CRUD
- 分页查询:集成PageHelper插件
- 事务管理:使用声明式事务
这种整合方案在实际项目中应用广泛,具有:
- 开发效率高
- 性能优异
- 维护方便
- 社区活跃
建议在实际开发中结合代码生成工具(如MyBatis Generator)进一步提高开发效率。