目录
- 引言
- Spring Boot 基础回顾
- MyBatis 核心概念解析
- Spring Boot 整合 MyBatis
- MyBatis 高级特性
- Spring Boot + MyBatis 最佳实践
- 性能优化与扩展
- 实战案例:电商系统开发
- 常见问题与解决方案
- 总结与展望
1. 引言
1.1 技术背景与现状
在现代企业级应用开发中,数据持久化是一个核心需求。随着Java生态系统的不断发展,出现了多种ORM框架,如Hibernate、MyBatis、JPA等。其中,MyBatis因其灵活性、高性能和易用性,在企业级应用中占据了重要地位。
Spring Boot作为Spring框架的"约定优于配置"实现,极大地简化了Spring应用的初始搭建和开发过程。将Spring Boot与MyBatis结合,可以充分发挥两者的优势,构建高效、可维护的数据访问层。
1.2 为什么选择Spring Boot + MyBatis
- 开发效率高:Spring Boot的自动配置和起步依赖大大减少了样板代码
- 灵活性好:MyBatis允许开发者直接编写SQL,保持了对SQL的完全控制
- 性能优异:MyBatis避免了Hibernate等框架可能产生的复杂查询问题
- 易于集成:Spring Boot对MyBatis有良好的官方支持
- 生态丰富:两者都有庞大的社区和丰富的插件支持
1.3 本文内容概览
本文将全面介绍Spring Boot与MyBatis的整合与实践,从基础配置到高级特性,再到性能优化和实战案例,为开发者提供一站式解决方案。
2. Spring Boot 基础回顾
2.1 Spring Boot 核心特性
Spring Boot的核心设计理念是"约定优于配置",其主要特性包括:
- 自动配置:根据classpath中的jar包自动配置Spring应用
- 起步依赖:简化Maven/Gradle配置,一键式添加功能模块
- Actuator:提供生产级监控和管理端点
- 嵌入式容器:内置Tomcat、Jetty等Servlet容器
- 外部化配置:支持多种格式的配置文件和环境变量
2.2 Spring Boot 项目结构
标准的Spring Boot项目结构如下:
src/
├── main/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── demo/
│ │ ├── DemoApplication.java # 启动类
│ │ ├── config/ # 配置类
│ │ ├── controller/ # 控制器
│ │ ├── service/ # 服务层
│ │ ├── dao/ # 数据访问层
│ │ └── model/ # 实体类
│ └── resources/
│ ├── static/ # 静态资源
│ ├── templates/ # 模板文件
│ ├── application.yml # 主配置文件
│ └── mapper/ # MyBatis映射文件
└── test/ # 测试代码
2.3 Spring Boot 自动配置原理
Spring Boot的自动配置是通过@EnableAutoConfiguration注解实现的,其核心机制包括:
- 条件注解:如
@ConditionalOnClass、@ConditionalOnMissingBean等 - 自动配置类:位于
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports - 配置属性:通过
@ConfigurationProperties绑定外部配置
示例:查看自动配置报告
# 启用debug日志查看自动配置报告
logging.level.root=debug
或者在启动时添加--debug参数:
java -jar myapp.jar --debug
3. MyBatis 核心概念解析
3.1 MyBatis 架构概述
MyBatis的整体架构分为三层:
- 基础支撑层:事务管理、连接池、缓存、日志等基础设施
- 核心处理层:配置解析、参数映射、SQL解析、SQL执行、结果集映射
- 接口层:SqlSession API、Mapper接口
3.2 核心组件详解
3.2.1 SqlSessionFactory
SqlSessionFactory是MyBatis的核心对象,用于创建SqlSession。通常一个应用只需要一个SqlSessionFactory实例。
构建方式:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
3.2.2 SqlSession
SqlSession代表一次数据库会话,线程不安全,每次使用后应该关闭。主要方法包括:
selectOne():查询单个对象selectList():查询对象列表insert():插入数据update():更新数据delete():删除数据commit():提交事务rollback():回滚事务
3.2.3 Mapper 接口
Mapper接口是MyBatis的核心概念之一,通过动态代理技术将接口方法与SQL语句绑定。示例:
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User selectUser(int id);
}
3.3 XML 映射文件
MyBatis的XML映射文件包含以下主要元素:
<select>:查询语句<insert>:插入语句<update>:更新语句<delete>:删除语句<sql>:可重用的SQL片段<resultMap>:结果集映射
示例:
<mapper namespace="com.example.mapper.UserMapper">
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="email" column="email"/>
</resultMap>
<select id="selectUser" resultMap="userResultMap">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
3.4 动态SQL
MyBatis提供了强大的动态SQL功能,主要元素包括:
<if>:条件判断<choose>/<when>/<otherwise>:多条件选择<trim>/<where>/<set>:辅助处理SQL片段<foreach>:循环遍历集合
示例:
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="username != null">
AND username like #{username}
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
</select>
4. Spring Boot 整合 MyBatis
4.1 项目初始化
4.1.1 使用Spring Initializr创建项目
可以通过https://start.spring.io或IDE插件创建Spring Boot项目,添加以下依赖:
- Spring Web
- MyBatis Framework
- MySQL Driver (或其他数据库驱动)
- Lombok (可选,简化代码)
4.1.2 Maven依赖配置
<dependencies>
<!-- Spring Boot Starter -->
<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.3</version>
</dependency>
<!-- MySQL Connector -->
<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>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
4.2 基础配置
4.2.1 数据源配置
在application.yml中配置数据源:
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
pool-name: HikariCP
maximum-pool-size: 20
minimum-idle: 10
idle-timeout: 30000
max-lifetime: 60000
connection-timeout: 30000
4.2.2 MyBatis 基本配置
mybatis:
mapper-locations: classpath:mapper/*.xml # XML映射文件位置
type-aliases-package: com.example.model # 实体类包名
configuration:
map-underscore-to-camel-case: true # 自动驼峰命名转换
default-fetch-size: 100 # 默认获取数量
default-statement-timeout: 30 # 超时时间(秒)
4.3 基础CRUD实现
4.3.1 实体类定义
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String username;
private String password;
private String email;
private Date createTime;
private Date updateTime;
}
4.3.2 Mapper接口定义
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(Long id);
@Insert("INSERT INTO users(username, password, email, create_time, update_time) " +
"VALUES(#{username}, #{password}, #{email}, now(), now())")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("UPDATE users SET username=#{username}, email=#{email}, update_time=now() WHERE id=#{id}")
int update(User user);
@Delete("DELETE FROM users WHERE id=#{id}")
int delete(Long id);
@Select("SELECT * FROM users")
List<User> findAll();
}
4.3.3 Service层实现
@Service
@RequiredArgsConstructor
public class UserService {
private final UserMapper userMapper;
public User getUserById(Long id) {
return userMapper.findById(id);
}
public List<User> getAllUsers() {
return userMapper.findAll();
}
public int createUser(User user) {
return userMapper.insert(user);
}
public int updateUser(User user) {
return userMapper.update(user);
}
public int deleteUser(Long id) {
return userMapper.delete(id);
}
}
4.3.4 Controller层实现
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
@PostMapping
public ResponseEntity<Void> createUser(@RequestBody User user) {
userService.createUser(user);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
@PutMapping("/{id}")
public ResponseEntity<Void> updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
return ResponseEntity.ok().build();
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
4.4 XML映射方式实现
4.4.1 创建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.mapper.UserMapper">
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="email" column="email"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="findById" resultMap="userResultMap">
SELECT * FROM users WHERE id = #{id}
</select>
<insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users(username, password, email, create_time, update_time)
VALUES(#{username}, #{password}, #{email}, now(), now())
</insert>
<update id="update" parameterType="User">
UPDATE users
SET username=#{username}, email=#{email}, update_time=now()
WHERE id=#{id}
</update>
<delete id="delete">
DELETE FROM users WHERE id=#{id}
</delete>
<select id="findAll" resultMap="userResultMap">
SELECT * FROM users
</select>
</mapper>
4.4.2 修改Mapper接口
@Mapper
public interface UserMapper {
User findById(Long id);
int insert(User user);
int update(User user);
int delete(Long id);
List<User> findAll();
}
4.5 分页查询实现
4.5.1 添加分页依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
4.5.2 配置分页插件
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
4.5.3 实现分页查询
@Service
@RequiredArgsConstructor
public class UserService {
private final UserMapper userMapper;
public PageInfo<User> getUsersByPage(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.findAll();
return new PageInfo<>(users);
}
}
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/page")
public ResponseEntity<PageInfo<User>> getUsersByPage(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
PageInfo<User> pageInfo = userService.getUsersByPage(pageNum, pageSize);
return ResponseEntity.ok(pageInfo);
}
}
5. MyBatis 高级特性
5.1 动态SQL高级用法
5.1.1 <choose>/<when>/<otherwise>示例
<select id="findActiveUser" resultType="User">
SELECT * FROM users
WHERE state = 'ACTIVE'
<

最低0.47元/天 解锁文章
4249

被折叠的 条评论
为什么被折叠?



