Spring Boot 集成 MyBatis 全面讲解
MyBatis 是一款良好的持久层框架,与 Spring Boot 集成后可以大大简化开发流程。本文将全面讲解如何在 Spring Boot 中集成 MyBatis,包括情况配置、基础利用、高级功能和最佳实践。
一、MyBatis 简介
1. SqlSession
SqlSession 是 MyBatis 的核心接口,负责执行 SQL 语句、获取映射器实例以及管理事务。
1.1 SqlSession 的创建
SqlSession 通常通过 SqlSessionFactory 获取。以下是创建 SqlSessionFactory 的典范代码:
- InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- try (SqlSession session = sqlSessionFactory.openSession()) {
- // 使用 session 进行数据库操作
- }
复制代码 注意:在 Spring 集成中,SqlSessionFactory 和 SqlSession 的创建由框架管理,我们只必要通过依赖注入获取即可。
1.2 SqlSession 的常用方法
SqlSession 提供了多种方法,用于执行数据库利用:
- 查询利用:
- // 单条记录查询
- User user = session.selectOne("namespace.statementId", parameter);
- // 多条记录查询
- List<User> users = session.selectList("namespace.statementId", parameter);
复制代码 - 插入利用:
- int rows = session.insert("namespace.statementId", parameter);
复制代码 - 更新利用:
- int rows = session.update("namespace.statementId", parameter);
复制代码 - 删除利用:
- int rows = session.delete("namespace.statementId", parameter);
复制代码 - 事务控制:
- session.commit(); // 提交事务
- session.rollback(); // 回滚事务
复制代码 2. Mapper 映射器
Mapper 映射器是 MyBatis 的核心功能,用于实现 SQL 和 Java 方法之间的映射。它可以通过注解或 XML 配置。
2.1 基于注解的 Mapper
注解方式直接将 SQL 写在 Mapper 接口中,简单高效,恰当简单场景。
示例代码:
- @Mapper
- public interface UserMapper {
- @Select("SELECT * FROM user WHERE id = #{id}")
- User selectById(Long id);
- @Insert("INSERT INTO user (username, email) VALUES (#{username}, #{email})")
- int insertUser(User user);
- @Update("UPDATE user SET email = #{email} WHERE id = #{id}")
- int updateUser(User user);
- @Delete("DELETE FROM user WHERE id = #{id}")
- int deleteUser(Long id);
- }
复制代码 2.2 基于 XML 的 Mapper
XML 配置更加灵活,恰当复杂查询场景。Mapper XML 文件通常位于 resources/mapper 目录。
Mapper 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">
- <!-- 查询 -->
- <select id="selectById" parameterType="long" resultType="com.example.entity.User">
- SELECT * FROM user WHERE id = #{id}
- </select>
- <!-- 插入 -->
- <insert id="insertUser" parameterType="com.example.entity.User">
- INSERT INTO user (username, email)
- VALUES (#{username}, #{email})
- </insert>
- <!-- 更新 -->
- <update id="updateUser" parameterType="com.example.entity.User">
- UPDATE user SET email = #{email} WHERE id = #{id}
- </update>
- <!-- 删除 -->
- <delete id="deleteUser" parameterType="long">
- DELETE FROM user WHERE id = #{id}
- </delete>
- </mapper>
复制代码 2.3 Mapper 映射器的工作机制
Mapper 接口的方法名和参数必要与 XML 中的 id 和 parameterType 对应。MyBatis 会通过动态代理为 Mapper 接口生成实现类,并调用对应的 SQL。
3. 配置文件
MyBatis 的配置文件包括全局配置文件(mybatis-config.xml)和映射文件(mapper.xml)。
3.1 全局配置文件
mybatis-config.xml 界说了数据库连接、日志设置、别名等全局配置。
典范配置示例:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <!-- 环境配置 -->
- <environments default="development">
- <environment id="development">
- <transactionManager type="JDBC"/>
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo"/>
- <property name="username" value="root"/>
- <property name="password" value="root"/>
- </dataSource>
- </environment>
- </environments>
- <!-- 别名配置 -->
- <typeAliases>
- <typeAlias type="com.example.entity.User" alias="User"/>
- </typeAliases>
- <!-- Mapper 映射文件 -->
- <mappers>
- <mapper resource="mapper/UserMapper.xml"/>
- </mappers>
- </configuration>
复制代码 3.2 映射文件配置
映射文件界说了详细的 SQL 和 Java 对象之间的关系。以 UserMapper.xml 为例:
- <mapper namespace="com.example.mapper.UserMapper">
- <select id="selectAll" resultType="User">
- SELECT * FROM user
- </select>
- <resultMap id="UserResultMap" type="User">
- <id column="id" property="id"/>
- <result column="username" property="username"/>
- <result column="email" property="email"/>
- </resultMap>
- </mapper>
复制代码 4. ResultMap
ResultMap 是 MyBatis 的强大特性之一,用于处置惩罚复杂查询效果与 Java 对象的映射关系。
4.1 什么是 ResultMap?
ResultMap 用于自界说数据库字段与 Java 对象属性的映射。它支持嵌套映射、别名和字段处置惩罚,恰当复杂的对象映射场景。
4.2 ResultMap 配置示例
以下是一个带嵌套对象的 ResultMap 配置:
数据库表:
- CREATE TABLE user (
- id BIGINT PRIMARY KEY,
- username VARCHAR(50),
- email VARCHAR(100)
- );
- CREATE TABLE address (
- id BIGINT PRIMARY KEY,
- user_id BIGINT,
- city VARCHAR(50),
- FOREIGN KEY (user_id) REFERENCES user(id)
- );
复制代码 Java 对象:
- @Data
- public class User {
- private Long id;
- private String username;
- private String email;
- private Address address;
- }
- @Data
- public class Address {
- private Long id;
- private String city;
- }
复制代码 ResultMap 配置:
- <resultMap id="UserWithAddress" type="User">
- <id column="id" property="id"/>
- <result column="username" property="username"/>
- <result column="email" property="email"/>
- <association property="address" javaType="Address">
- <id column="address_id" property="id"/>
- <result column="city" property="city"/>
- </association>
- </resultMap>
复制代码 查询语句:
- <select id="getUserWithAddress" resultMap="UserWithAddress">
- SELECT u.id, u.username, u.email, a.id AS address_id, a.city
- FROM user u
- LEFT JOIN address a ON u.id = a.user_id
- WHERE u.id = #{id}
- </select>
复制代码 4.3 嵌套集合映射
对于一对多的嵌套关系,可以使用 <collection>:
- <resultMap id="UserWithPosts" type="User">
- <id column="id" property="id"/>
- <result column="username" property="username"/>
- <collection property="posts" ofType="Post">
- <id column="post_id" property="id"/>
- <result column="title" property="title"/>
- </collection>
- </resultMap>
复制代码 总结
SqlSession、Mapper、配置文件 和 ResultMap 是 MyBatis 的核心概念。通过灵活的配置和映射,MyBatis 可以高效地处置惩罚各种复杂的数据库利用需求。熟练掌握这些特性可以让开发者在项目中更高效地处置惩罚数据访问逻辑。
三、Spring Boot 集成 MyBatis
MyBatis 是一种轻量级的持久层框架,与 Spring Boot 集成后可以极大地提拔开发效率。以下是集成的完备步调,包括项目配置、数据库设计和根本利用。
1. 创建 Spring Boot 项目
在创建项目时,可以使用 Spring Initializr 快速生成骨架项目。以下依赖是集成 MyBatis 所必需的:
- Spring Web:用于创建 REST API。
- MyBatis Framework:MyBatis 的核心依赖。
- MySQL Driver:连接 MySQL 数据库。
- Lombok:简化实体类的开发,镌汰样板代码。
2. 配置 pom.xml
以下是必要在 pom.xml 中添加的 Maven 依赖:
- <dependencies>
- <!-- Spring Boot Starter -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
- <!-- MyBatis Starter -->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>3.0.0</version>
- </dependency>
- <!-- MySQL Driver -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-j</artifactId>
- </dependency>
- <!-- Lombok -->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- </dependencies>
复制代码 这些依赖包括 Spring Boot 核心、MyBatis 框架、MySQL 数据库驱动和 Lombok。版本号可以根据项目需求进行调解。
3. 配置数据库连接
在 src/main/resources 目录下创建 application.yml 文件,用于配置项目的数据库连接。
application.yml 示例
- spring:
- datasource:
- url: jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=UTC
- username: root
- password: root
- driver-class-name: com.mysql.cj.jdbc.Driver
- mybatis:
- mapper-locations: classpath:mapper/*.xml
- type-aliases-package: com.example.demo.entity
复制代码 阐明:
- url:数据库连接地址。
- username 和 password:数据库的用户名和密码。
- mapper-locations:指定 MyBatis 的 XML 映射文件路径。
- type-aliases-package:指定实体类地点的包,用于启用简化的类名映射。
4. 创建数据库表
使用以下 SQL 语句创建一个简单的用户表:
SQL 示例
- CREATE DATABASE IF NOT EXISTS mybatis_demo;
- USE mybatis_demo;
- CREATE TABLE user (
- id BIGINT PRIMARY KEY AUTO_INCREMENT,
- username VARCHAR(50) NOT NULL,
- password VARCHAR(50) NOT NULL,
- email VARCHAR(100) NOT NULL,
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- );
复制代码 此 SQL 创建了一个名为 user 的表,用于存储用户信息。字段包括用户 ID、用户名、密码、电子邮件以及创建时间。
5. 编写实体类
创建与数据库表对应的 Java 实体类。
User.java
- package com.example.demo.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 LocalDateTime createdAt;
- }
复制代码 阐明:
- 使用了 Lombok 的 @Data 注解,自动生成 getter、setter、toString 等方法。
- 字段名称与数据库表的列名保持一致,便于自动映射。
6. 创建 Mapper 接口
MyBatis 的 Mapper 接口用于界说数据库利用。可以选择使用注解方式或者 XML 配置方式编写 SQL。
注解方式 Mapper
以下是一个基于注解的 Mapper 接口示例:
- package com.example.demo.mapper;
- import com.example.demo.entity.User;
- import org.apache.ibatis.annotations.*;
- import java.util.List;
- @Mapper
- public interface UserMapper {
- @Insert("INSERT INTO user (username, password, email) VALUES (#{username}, #{password}, #{email})")
- int insertUser(User user);
- @Select("SELECT * FROM user WHERE id = #{id}")
- User selectById(Long id);
- @Select("SELECT * FROM user")
- List<User> selectAllUsers();
- @Update("UPDATE user SET username = #{username}, password = #{password}, email = #{email} WHERE id = #{id}")
- int updateUser(User user);
- @Delete("DELETE FROM user WHERE id = #{id}")
- int deleteUser(Long id);
- }
复制代码 XML 配置方式 Mapper
XML 配置方式更灵活,恰当复杂查询场景。以下是对应的 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.demo.mapper.UserMapper">
- <insert id="insertUser" parameterType="com.example.demo.entity.User">
- INSERT INTO user (username, password, email)
- VALUES (#{username}, #{password}, #{email})
- </insert>
- <select id="selectById" parameterType="long" resultType="com.example.demo.entity.User">
- SELECT * FROM user WHERE id = #{id}
- </select>
- <select id="selectAllUsers" resultType="com.example.demo.entity.User">
- SELECT * FROM user
- </select>
- <update id="updateUser" parameterType="com.example.demo.entity.User">
- UPDATE user SET username = #{username}, password = #{password}, email = #{email} WHERE id = #{id}
- </update>
- <delete id="deleteUser" parameterType="long">
- DELETE FROM user WHERE id = #{id}
- </delete>
- </mapper>
复制代码 在 Spring Boot 中,MyBatis 会自动扫描 mapper 文件夹下的 XML 文件。
7. 创建 Service 层
为了更好地分离业务逻辑,发起将 Mapper 利用封装到 Service 层中。
UserService.java
- package com.example.demo.service;
- import com.example.demo.entity.User;
- import com.example.demo.mapper.UserMapper;
- import org.springframework.stereotype.Service;
- import java.util.List;
- @Service
- public class UserService {
- private final UserMapper userMapper;
- public UserService(UserMapper userMapper) {
- this.userMapper = userMapper;
- }
- public int createUser(User user) {
- return userMapper.insertUser(user);
- }
- public User getUserById(Long id) {
- return userMapper.selectById(id);
- }
- public List<User> getAllUsers() {
- return userMapper.selectAllUsers();
- }
- public int updateUser(User user) {
- return userMapper.updateUser(user);
- }
- public int deleteUser(Long id) {
- return userMapper.deleteUser(id);
- }
- }
复制代码 8. 创建 Controller 层
末了,为了提供对外接口,创建 Controller。
UserController.java
- package com.example.demo.controller;
- import com.example.demo.entity.User;
- import com.example.demo.service.UserService;
- import org.springframework.web.bind.annotation.*;
- import java.util.List;
- @RestController
- @RequestMapping("/api/users")
- public class UserController {
- private final UserService userService;
- public UserController(UserService userService) {
- this.userService = userService;
- }
- @PostMapping
- public String createUser(@RequestBody User user) {
- userService.createUser(user);
- return "User created successfully!";
- }
- @GetMapping("/{id}")
- public User getUserById(@PathVariable Long id) {
- return userService.getUserById(id);
- }
- @GetMapping
- public List<User> getAllUsers() {
- return userService.getAllUsers();
- }
- @PutMapping
- public String updateUser(@RequestBody User user) {
- userService.updateUser(user);
- return "User updated successfully!";
- }
- @DeleteMapping("/{id}")
- public String deleteUser(@PathVariable Long id) {
- userService.deleteUser(id);
- return "User deleted successfully!";
- }
- }
复制代码 9. 启动应用
创建项目主类 MyBatisDemoApplication.java:
- package com.example.demo;
- 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);
- }
- }
复制代码 启动项目,使用工具(如 Postman 或 CURL)测试接口。
四、MyBatis 基础利用详解
以下将详细讲解 MyBatis 的基础利用,包括如何创建实体类、Mapper 接口、XML 映射文件,以及如何通过 Service 和 Controller 层完成基础的增删改查功能。
1. 创建实体类
实体类用于表示数据库中的表记录,在 MyBatis 中,实体类字段与数据库表的列进行逐一对应。
示例代码:User.java
- package com.example.demo.entity;
- import lombok.Data;
- import java.time.LocalDateTime;
- @Data
- public class User {
- private Long id; // 用户ID
- private String username; // 用户名
- private String password; // 密码
- private String email; // 邮箱
- private LocalDateTime createdAt; // 创建时间
- }
复制代码 阐明:
- 使用 @Data 注解自动生成 getter、setter、toString 等方法。
- 字段名称与数据库表的列名保持一致,便于 MyBatis 自动映射。
2. 创建 Mapper 接口
Mapper 接口界说了对数据库表的利用。MyBatis 支持两种方式:基于注解和基于 XML 映射文件。
基于注解的 Mapper 接口
以下是使用注解界说的基础增删改查利用:
- package com.example.demo.mapper;
- import com.example.demo.entity.User;
- import org.apache.ibatis.annotations.*;
- import java.util.List;
- @Mapper
- public interface UserMapper {
- // 插入用户
- @Insert("INSERT INTO user (username, password, email) VALUES (#{username}, #{password}, #{email})")
- int insertUser(User user);
- // 查询所有用户
- @Select("SELECT * FROM user")
- List<User> getAllUsers();
- // 根据 ID 查询用户
- @Select("SELECT * FROM user WHERE id = #{id}")
- User getUserById(Long id);
- // 更新用户
- @Update("UPDATE user SET username = #{username}, password = #{password}, email = #{email} WHERE id = #{id}")
- int updateUser(User user);
- // 删除用户
- @Delete("DELETE FROM user WHERE id = #{id}")
- int deleteUser(Long id);
- }
复制代码 注意:
- 使用 @Mapper 注解让 Spring 容器自动扫描 Mapper 接口。
- 注解方式恰当简单的 SQL 语句,对于复杂查询发起使用 XML。
3. 配置 XML 映射文件
在复杂查询场景中,XML 配置文件更加灵活。
文件位置
- src/main/resources/mapper/UserMapper.xml
复制代码 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.demo.mapper.UserMapper">
- <!-- 定义字段与属性的映射 -->
- <resultMap id="UserResultMap" type="com.example.demo.entity.User">
- <id column="id" property="id" />
- <result column="username" property="username" />
- <result column="password" property="password" />
- <result column="email" property="email" />
- <result column="created_at" property="createdAt" />
- </resultMap>
- <!-- 查询所有用户 -->
- <select id="getAllUsers" resultMap="UserResultMap">
- SELECT * FROM user
- </select>
- <!-- 插入用户 -->
- <insert id="insertUser" parameterType="com.example.demo.entity.User">
- INSERT INTO user (username, password, email)
- VALUES (#{username}, #{password}, #{email})
- </insert>
- <!-- 更新用户 -->
- <update id="updateUser" parameterType="com.example.demo.entity.User">
- UPDATE user
- SET username = #{username}, password = #{password}, email = #{email}
- WHERE id = #{id}
- </update>
- <!-- 删除用户 -->
- <delete id="deleteUser" parameterType="long">
- DELETE FROM user WHERE id = #{id}
- </delete>
- </mapper>
复制代码 注意:
- namespace 必须与 Mapper 接口的全路径名称一致。
- <resultMap> 界说了表字段与实体类属性之间的映射关系。
- #{} 用于参数占位,MyBatis 会根据参数范例自动替换。
4. 创建 Service 层
为了实现业务逻辑与数据访问的分离,发起通过 Service 层封装 Mapper 的利用。
示例代码:UserService.java
- package com.example.demo.service;
- import com.example.demo.entity.User;
- import com.example.demo.mapper.UserMapper;
- import org.springframework.stereotype.Service;
- import java.util.List;
- @Service
- public class UserService {
- private final UserMapper userMapper;
- public UserService(UserMapper userMapper) {
- this.userMapper = userMapper;
- }
- // 添加用户
- public int addUser(User user) {
- return userMapper.insertUser(user);
- }
- // 获取所有用户
- public List<User> getAllUsers() {
- return userMapper.getAllUsers();
- }
- // 根据 ID 查询用户
- public User getUserById(Long id) {
- return userMapper.getUserById(id);
- }
- // 更新用户
- public int updateUser(User user) {
- return userMapper.updateUser(user);
- }
- // 删除用户
- public int deleteUser(Long id) {
- return userMapper.deleteUser(id);
- }
- }
复制代码 阐明:
- 通过依赖注入的方式引入 UserMapper。
- 将所有的数据库利用封装为独立的方法,便于管理和复用。
5. 创建 Controller 层
Controller 层提供 RESTful API 接口,供外部访问 Service 方法。
示例代码:UserController.java
- package com.example.demo.controller;
- import com.example.demo.entity.User;
- import com.example.demo.service.UserService;
- import org.springframework.web.bind.annotation.*;
- import java.util.List;
- @RestController
- @RequestMapping("/api/users")
- public class UserController {
- private final UserService userService;
- public UserController(UserService userService) {
- this.userService = userService;
- }
- // 创建用户
- @PostMapping
- public String createUser(@RequestBody User user) {
- userService.addUser(user);
- return "User created successfully!";
- }
- // 获取所有用户
- @GetMapping
- public List<User> getAllUsers() {
- return userService.getAllUsers();
- }
- // 根据 ID 获取用户
- @GetMapping("/{id}")
- public User getUserById(@PathVariable Long id) {
- return userService.getUserById(id);
- }
- // 更新用户
- @PutMapping
- public String updateUser(@RequestBody User user) {
- userService.updateUser(user);
- return "User updated successfully!";
- }
- // 删除用户
- @DeleteMapping("/{id}")
- public String deleteUser(@PathVariable Long id) {
- userService.deleteUser(id);
- return "User deleted successfully!";
- }
- }
复制代码 阐明:
- 使用 @RestController 标注类,返回 JSON 数据。
- 通过 @RequestBody 接收前端传递的 JSON 数据。
- 通过 @PathVariable 获取 URL 中的动态参数。
五、高级功能
1. 动态 SQL
动态 SQL 是 MyBatis 的强大功能之一,可以根据输入条件动态生成 SQL 语句。相比手动拼接 SQL,这种方式更加安全、高效且可维护。
1.1 动态 SQL 标签
MyBatis 提供了以下动态 SQL 标签:
- <if>:用于条件判断。
- <choose>:雷同于 Java 的 switch-case。
- <where>:自动添加 WHERE 关键字并处置惩罚多个条件。
- <set>:动态生成 SET 子句,常用于更新语句。
- <foreach>:用于迭代生成 SQL(如 IN 子句或批量插入)。
- <trim>:自界说 SQL 前后缀(如添加括号、处置惩罚多余逗号等)。
1.2 动态 SQL 示例
(1)条件查询:根据用户输入动态生成查询条件
XML 配置文件:
- <select id="searchUsers" resultMap="UserResultMap">
- SELECT * FROM user
- <where>
- <if test="username != null">
- AND username = #{username}
- </if>
- <if test="email != null">
- AND email = #{email}
- </if>
- </where>
- </select>
复制代码 注意:<where> 标签会自动处置惩罚条件的拼接,并在至少有一个条件建立时自动添加 WHERE 关键字。
Java 调用代码:
- Map<String, Object> params = new HashMap<>();
- params.put("username", "John");
- params.put("email", null);
- List<User> users = userMapper.searchUsers(params);
复制代码 (2)动态更新:根据非空字段更新用户信息
在实际场景中,每每必要对部分字段进行更新,MyBatis 的动态 SQL 可以轻松实现。
XML 配置文件:
- <update id="updateUser" parameterType="User">
- UPDATE user
- <set>
- <if test="username != null">
- username = #{username},
- </if>
- <if test="password != null">
- password = #{password},
- </if>
- <if test="email != null">
- email = #{email},
- </if>
- </set>
- WHERE id = #{id}
- </update>
复制代码 注意:
- <set> 标签会自动处置惩罚逗号,确保生成的 SQL 语句语法准确。
- null 值的字段会被忽略,克制误更新。
Java 调用代码:
- User user = new User();
- user.setId(1L);
- user.setUsername("NewName");
- int rows = userMapper.updateUser(user);
复制代码 (3)批量查询:使用 <foreach> 生成 IN 子句
XML 配置文件:
- <select id="findUsersByIds" resultMap="UserResultMap">
- SELECT * FROM user
- WHERE id IN
- <foreach collection="idList" item="id" open="(" separator="," close=")">
- #{id}
- </foreach>
- </select>
复制代码 阐明:
- collection 指定输入参数(一样平常为 List 或数组)。
- item 是每次迭代的变量。
- open、separator 和 close 分别界说 SQL 子句的开头、分隔符和结尾。
Java 调用代码:
- List<Long> idList = Arrays.asList(1L, 2L, 3L);
- List<User> users = userMapper.findUsersByIds(idList);
复制代码 生成的 SQL:
- SELECT * FROM user WHERE id IN (1, 2, 3);
复制代码 2. 分页查询
分页查询是 Web 应用中最常见的功能之一。在 MyBatis 中,可以借助 PageHelper 插件实现高效分页。
2.1 使用 PageHelper 插件
(1)引入依赖
在 pom.xml 中添加以下依赖:
- <dependency>
- <groupId>com.github.pagehelper</groupId>
- <artifactId>pagehelper-spring-boot-starter</artifactId>
- <version>1.4.0</version>
- </dependency>
复制代码 (2)分页查询示例
在 Service 层调用分页方法:
- import com.github.pagehelper.PageHelper;
- import com.github.pagehelper.PageInfo;
- public List<User> getUsersByPage(int pageNum, int pageSize) {
- // 启用分页
- PageHelper.startPage(pageNum, pageSize);
- List<User> users = userMapper.getAllUsers();
- // 封装分页结果
- return new PageInfo<>(users).getList();
- }
复制代码 (3)自界说分页
如果不想引入插件,也可以通过手动拼接分页 SQL:
XML 配置文件:
- <select id="getUsersByPage" resultMap="UserResultMap">
- SELECT * FROM user
- LIMIT #{offset}, #{pageSize}
- </select>
复制代码 Mapper 接口:
- List<User> getUsersByPage(@Param("offset") int offset, @Param("pageSize") int pageSize);
复制代码 Java 调用代码:
- int offset = (pageNum - 1) * pageSize;
- List<User> users = userMapper.getUsersByPage(offset, pageSize);
复制代码 3. 复杂对象映射
3.1 一对多映射
场景:一个用户有多个订单。
数据库表设计:
- CREATE TABLE orders (
- id BIGINT PRIMARY KEY,
- user_id BIGINT,
- order_name VARCHAR(255),
- FOREIGN KEY (user_id) REFERENCES user(id)
- );
复制代码 XML 配置文件:
- <resultMap id="UserWithOrders" type="User">
- <id column="id" property="id"/>
- <result column="username" property="username"/>
- <collection property="orders" ofType="Order">
- <id column="order_id" property="id"/>
- <result column="order_name" property="orderName"/>
- </collection>
- </resultMap>
- <select id="getUserWithOrders" resultMap="UserWithOrders">
- SELECT u.id, u.username, o.id AS order_id, o.order_name
- FROM user u
- LEFT JOIN orders o ON u.id = o.user_id
- WHERE u.id = #{id}
- </select>
复制代码 3.2 嵌套查询
对于复杂的多表查询,可以使用嵌套查询实现。
XML 配置:
- <resultMap id="OrderResultMap" type="Order">
- <id column="id" property="id"/>
- <result column="order_name" property="orderName"/>
- </resultMap>
- <resultMap id="UserWithOrders" type="User">
- <id column="id" property="id"/>
- <result column="username" property="username"/>
- <collection property="orders" resultMap="OrderResultMap" column="id"/>
- </resultMap>
- <select id="getUserWithOrders" resultMap="UserWithOrders">
- SELECT * FROM user WHERE id = #{id};
- </select>
复制代码 六、最佳实践
1. 分层设计
- Controller 层:负责接收哀求和返回相应。
- Service 层:封装业务逻辑。
- Mapper 层:专注于数据库交互。
2. 克制 N+1 查询
一对多、多对多场景中,优先使用联合查询或嵌套查询,克制多个 SQL 执行。
3. 启用日志
在 application.yml 中启用 MyBatis 日志:
- mybatis:
- configuration:
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
复制代码 4. 动态 SQL
- 使用 <foreach> 实现批量利用。
- 使用 <if> 结合 <set> 实现动态更新。
总结
MyBatis 的高级功能如动态 SQL、分页查询和复杂对象映射,为开发者提供了极大的灵活性。在项目中,结合实际场景选择合适的实现方式,可以显著提高开发效率并降低维护成本。如果有任何疑问,欢迎在评论区留言讨论!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |