MyBatis 详细教程
目录
- 简介
- 环境搭建
- 基本配置
- CRUD 操作
- 动态 SQL
- 缓存机制
- 分页插件
- 多表查询
- 高级映射
- 事务管理
- 性能优化
- 最佳实践
1. 简介
MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数及获取结果集。通过 XML 或注解的方式将接口和 SQL 映射成对象。
优点:
- 简化数据库操作:通过 XML 或注解的方式,将 SQL 和 Java 对象进行映射。
- 灵活性高:支持动态 SQL,可以根据条件生成不同的 SQL 语句。
- 轻量级:不依赖于任何第三方框架,易于集成到各种项目中。
- 支持多种数据库:兼容 MySQL、Oracle、SQL Server 等主流数据库。
2. 环境搭建
2.1 添加依赖
在 Maven 项目中添加 MyBatis 依赖:
org.mybatismybatis3.5.11
org.mybatis.spring.bootmybatis-spring-boot-starter2.2.0
mysqlmysql-connector-java8.0.26
org.springframework.bootspring-boot-starter-web
2.2 配置数据库连接
在 application.properties 中配置数据库连接信息:
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3. 基本配置
3.1 创建实体类
假设我们有一个 User 表,对应的实体类如下:
public class User {
private Integer id;
private String name;
private String email;
// Getters and Setters
}
3.2 创建 Mapper 接口
创建一个 UserMapper 接口,用于定义与数据库交互的方法:
public interface UserMapper {
List getAllUsers();
User getUserById(Integer id);
void insertUser(User user);
void updateUser(User user);
void deleteUser(Integer id);
}
3.3 编写 Mapper XML 文件
在 resources/mapper 目录下创建 UserMapper.xml 文件,定义 SQL 语句:
SELECT * FROM users
SELECT * FROM users WHERE id = #{id}
INSERT INTO users (name, email) VALUES (#{name}, #{email})
UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}
DELETE FROM users WHERE id = #{id}
3.4 配置 MyBatis
在 application.properties 中配置 MyBatis:
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.model
4. CRUD 操作
4.1 查询所有用户
@Autowired private UserMapper userMapper;
@GetMapping("/users")
public List getAllUsers() {
return userMapper.getAllUsers();
}
4.2 根据 ID 查询用户
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Integer id) {
return userMapper.getUserById(id);
}
4.3 插入用户
@PostMapping("/users")
public void insertUser(@RequestBody User user) { userMapper.insertUser(user);
}
4.4 更新用户
@PutMapping("/users/{id}")
public void updateUser(@PathVariable Integer id, @RequestBody User user) {
user.setId(id);
userMapper.updateUser(user);
}
4.5 删除用户
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable Integer id) { userMapper.deleteUser(id);
}
5. 动态 SQL
MyBatis 提供了强大的动态 SQL 功能,可以根据不同的条件生成不同的 SQL 语句。
5.1 使用 标签
5.2 使用 标签
类似于 Java 的 switch 语句:
6. 缓存机制
MyBatis 提供了两级缓存机制:一级缓存(SqlSession 级别)和二级缓存(Mapper 级别)。
6.1 一级缓存
一级缓存是默认开启的,作用范围是同一个 SqlSession 内。在同一个 SqlSession 中,如果执行了相同的查询语句,MyBatis 会从缓存中直接返回结果,而不会再次查询数据库。
6.2 二级缓存
二级缓存是跨 SqlSession 的,可以在多个 SqlSession 之间共享。需要手动开启:
在 MyBatis 中,二级缓存(也称为全局缓存或应用程序级别的缓存)是跨会话的缓存机制。它可以在多个 SqlSession 之间共享缓存数据,从而提高性能。要开启 MyBatis 的二级缓存,你需要按照以下步骤进行配置:
1. 在 MyBatis 配置文件中启用二级缓存
首先,在 MyBatis 的主配置文件(通常是 mybatis-config.xml)中,确保启用了二级缓存支持。你可以在
2. 在 Mapper XML 文件中配置缓存
接下来,在每个需要使用二级缓存的 Mapper XML 文件中,添加
SELECT * FROM users WHERE id = #{id}
- eviction:指定缓存回收策略,默认是 LRU(Least Recently Used),其他选项包括 FIFO、SOFT 和 WEAK。
- flushInterval:指定每隔多久刷新一次缓存(毫秒)。如果不设置,则不会自动刷新。
- size:指定缓存的最大条目数。
- readOnly:如果为 true,则表示该缓存只读,MyBatis 不会尝试更新缓存中的对象。
3. 确保实体类实现序列化接口
为了使缓存能够正常工作,你的实体类(如 User 类)必须实现 Serializable 接口。因为缓存的数据会被序列化存储。
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
// 属性和方法
}
4. 管理缓存刷新
MyBatis 会在某些操作(如插入、更新或删除)后自动刷新缓存。如果你不想在某些情况下刷新缓存,可以在 SQL 语句上使用 flushCache 属性来控制。
例如:
SELECT * FROM users WHERE id = #{id}
INSERT INTO users (name, email) VALUES (#{name}, #{email})
5. 使用自定义缓存实现(可选)
如果你想使用自定义的缓存实现(例如 Ehcache 或 Caffeine),可以在
6.3 清除缓存
可以通过 clearCache() 方法清除当前 SqlSession 的一级缓存:
sqlSession.clearCache();
7. 分页插件
MyBatis 自身没有提供分页功能,但可以通过插件来实现。常用的分页插件有 PageHelper。
7.1 添加依赖
com.github.pagehelper
pagehelper-spring-boot-starter 1.4.2
7.2 使用分页
@Autowired private UserMapper userMapper;
@GetMapping("/users/page")
public Page getUsersByPage(@RequestParam int pageNum, @RequestParam int pageSize) {
PageHelper.startPage(pageNum, pageSize);
return userMapper.getAllUsers();
}
8. 多表查询
8.1 关联查询
假设我们有两个表:users 和 orders,可以通过关联查询获取用户的订单信息。
SELECT u.*, o.order_id, o.amount FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.id = #{id}
9. 高级映射
9.1 关联映射
MyBatis 支持一对多、多对一、多对多等复杂关系的映射。
一对多映射
多对多映射
10. 事务管理
MyBatis 可以与 Spring 集成,使用 Spring 的事务管理功能。
10.1 使用 @Transactional注解
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public void addUserAndOrder(User user, Order order) { userMapper.insertUser(user); userMapper.insertOrder(order);
}
}
11. 性能优化
11.1 批量插入
对于大量数据插入,可以使用批量插入来提高性能:
INSERT INTO users (name, email) VALUES
(#{user.name}, #{user.email})
11.2 使用延迟加载
延迟加载可以减少不必要的查询,提升性能:
xml
12. 最佳实践
12.1 使用注解代替 XML
对于简单的 CRUD 操作,可以直接使用注解来替代 XML 文件:
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(Integer id);
12.2 统一异常处理
使用全局异常处理器来捕获并处理 MyBatis 抛出的异常:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MyBatisSystemException.class)
public ResponseEntity handleMyBatisException(MyBatisSystemException ex{ return ResponseEntity.status(HttpStatus.INTERNAL\_SERVER\_ERROR).body(ex.getMessage());
}
}
总结
通过本教程,你已经掌握了 MyBatis 的基本用法,并了解了一些高级特性,如动态 SQL、缓存、分页、多表查询等。希望这些内容能够帮助你在实际项目中更好地使用 MyBatis。