2026/4/18 10:10:33
网站建设
项目流程
搭建论坛网站使用的系统,手工做环保衣的网站,网站设计合同范本,上海模板建站源码Spring Boot 集成 MyBatis 全面讲解
MyBatis 是一款优秀的持久层框架#xff0c;与 Spring Boot 集成后可以大大简化开发流程。本文将全面讲解如何在 Spring Boot 中集成 MyBatis#xff0c;包括环境配置、基础操作、高级功能和最佳实践。 一、MyBatis 简介
1. SqlSession …Spring Boot 集成 MyBatis 全面讲解MyBatis 是一款优秀的持久层框架与 Spring Boot 集成后可以大大简化开发流程。本文将全面讲解如何在 Spring Boot 中集成 MyBatis包括环境配置、基础操作、高级功能和最佳实践。一、MyBatis 简介1. SqlSessionSqlSession是 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); // 多条记录查询 ListUser 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 的 MapperXML 配置更加灵活适合复杂查询场景。Mapper XML 文件通常位于resources/mapper目录。Mapper XML 文件示例?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.example.mapper.UserMapper !-- 查询 -- select idselectById parameterTypelong resultTypecom.example.entity.User SELECT * FROM user WHERE id #{id} /select !-- 插入 -- insert idinsertUser parameterTypecom.example.entity.User INSERT INTO user (username, email) VALUES (#{username}, #{email}) /insert !-- 更新 -- update idupdateUser parameterTypecom.example.entity.User UPDATE user SET email #{email} WHERE id #{id} /update !-- 删除 -- delete iddeleteUser parameterTypelong DELETE FROM user WHERE id #{id} /delete /mapper2.3 Mapper 映射器的工作机制Mapper 接口的方法名和参数需要与 XML 中的id和parameterType对应。MyBatis 会通过动态代理为 Mapper 接口生成实现类并调用对应的 SQL。3. 配置文件MyBatis 的配置文件包括全局配置文件mybatis-config.xml和映射文件mapper.xml。3.1 全局配置文件mybatis-config.xml定义了数据库连接、日志设置、别名等全局配置。典型配置示例?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration !-- 环境配置 -- environments defaultdevelopment environment iddevelopment transactionManager typeJDBC/ dataSource typePOOLED property namedriver valuecom.mysql.cj.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/mybatis_demo/ property nameusername valueroot/ property namepassword valueroot/ /dataSource /environment /environments !-- 别名配置 -- typeAliases typeAlias typecom.example.entity.User aliasUser/ /typeAliases !-- Mapper 映射文件 -- mappers mapper resourcemapper/UserMapper.xml/ /mappers /configuration3.2 映射文件配置映射文件定义了具体的 SQL 和 Java 对象之间的关系。以UserMapper.xml为例mapper namespacecom.example.mapper.UserMapper select idselectAll resultTypeUser SELECT * FROM user /select resultMap idUserResultMap typeUser id columnid propertyid/ result columnusername propertyusername/ result columnemail propertyemail/ /resultMap /mapper4. ResultMapResultMap是 MyBatis 的强大特性之一用于处理复杂查询结果与 Java 对象的映射关系。4.1 什么是 ResultMapResultMap用于自定义数据库字段与 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 idUserWithAddress typeUser id columnid propertyid/ result columnusername propertyusername/ result columnemail propertyemail/ association propertyaddress javaTypeAddress id columnaddress_id propertyid/ result columncity propertycity/ /association /resultMap查询语句select idgetUserWithAddress resultMapUserWithAddress 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} /select4.3 嵌套集合映射对于一对多的嵌套关系可以使用collectionresultMap idUserWithPosts typeUser id columnid propertyid/ result columnusername propertyusername/ collection propertyposts ofTypePost id columnpost_id propertyid/ result columntitle propertytitle/ /collection /resultMap总结SqlSession、Mapper、配置文件和ResultMap是 MyBatis 的核心概念。通过灵活的配置和映射MyBatis 可以高效地处理各种复杂的数据库操作需求。熟练掌握这些特性可以让开发者在项目中更高效地处理数据访问逻辑。三、Spring Boot 集成 MyBatisMyBatis 是一种轻量级的持久层框架与 Spring Boot 集成后可以极大地提升开发效率。以下是集成的完整步骤包括项目配置、数据库设计和基本操作。1. 创建 Spring Boot 项目在创建项目时可以使用 Spring Initializr 快速生成骨架项目。以下依赖是集成 MyBatis 所必需的Spring Web用于创建 REST API。MyBatis FrameworkMyBatis 的核心依赖。MySQL Driver连接 MySQL 数据库。Lombok简化实体类的开发减少样板代码。2. 配置pom.xml以下是需要在pom.xml中添加的 Maven 依赖dependencies !-- Spring Boot Starter -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter/artifactId /dependency !-- MyBatis Starter -- dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version3.0.0/version /dependency !-- MySQL Driver -- dependency groupIdmysql/groupId artifactIdmysql-connector-j/artifactId /dependency !-- Lombok -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/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?useSSLfalseserverTimezoneUTC 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.javapackage 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) ListUser 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 配置方式 MapperXML 配置方式更灵活适合复杂查询场景。以下是对应的 XML 映射文件。文件位置src/main/resources/mapper/UserMapper.xml?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.example.demo.mapper.UserMapper insert idinsertUser parameterTypecom.example.demo.entity.User INSERT INTO user (username, password, email) VALUES (#{username}, #{password}, #{email}) /insert select idselectById parameterTypelong resultTypecom.example.demo.entity.User SELECT * FROM user WHERE id #{id} /select select idselectAllUsers resultTypecom.example.demo.entity.User SELECT * FROM user /select update idupdateUser parameterTypecom.example.demo.entity.User UPDATE user SET username #{username}, password #{password}, email #{email} WHERE id #{id} /update delete iddeleteUser parameterTypelong DELETE FROM user WHERE id #{id} /delete /mapper在 Spring Boot 中MyBatis 会自动扫描mapper文件夹下的 XML 文件。7. 创建 Service 层为了更好地分离业务逻辑建议将 Mapper 操作封装到 Service 层中。UserService.javapackage 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 ListUser 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.javapackage 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 ListUser 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.javapackage 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.javapackage 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) ListUser 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.xmlUserMapper.xml 示例?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.example.demo.mapper.UserMapper !-- 定义字段与属性的映射 -- resultMap idUserResultMap typecom.example.demo.entity.User id columnid propertyid / result columnusername propertyusername / result columnpassword propertypassword / result columnemail propertyemail / result columncreated_at propertycreatedAt / /resultMap !-- 查询所有用户 -- select idgetAllUsers resultMapUserResultMap SELECT * FROM user /select !-- 插入用户 -- insert idinsertUser parameterTypecom.example.demo.entity.User INSERT INTO user (username, password, email) VALUES (#{username}, #{password}, #{email}) /insert !-- 更新用户 -- update idupdateUser parameterTypecom.example.demo.entity.User UPDATE user SET username #{username}, password #{password}, email #{email} WHERE id #{id} /update !-- 删除用户 -- delete iddeleteUser parameterTypelong DELETE FROM user WHERE id #{id} /delete /mapper注意namespace必须与 Mapper 接口的全路径名称一致。resultMap定义了表字段与实体类属性之间的映射关系。#{}用于参数占位MyBatis 会根据参数类型自动替换。4. 创建 Service 层为了实现业务逻辑与数据访问的分离建议通过 Service 层封装 Mapper 的操作。示例代码UserService.javapackage 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 ListUser 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.javapackage 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 ListUser 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 idsearchUsers resultMapUserResultMap SELECT * FROM user where if testusername ! null AND username #{username} /if if testemail ! null AND email #{email} /if /where /select注意where标签会自动处理条件的拼接并在至少有一个条件成立时自动添加WHERE关键字。Java 调用代码MapString, Object params new HashMap(); params.put(username, John); params.put(email, null); ListUser users userMapper.searchUsers(params);2动态更新根据非空字段更新用户信息在实际场景中往往需要对部分字段进行更新MyBatis 的动态 SQL 可以轻松实现。XML 配置文件update idupdateUser parameterTypeUser UPDATE user set if testusername ! null username #{username}, /if if testpassword ! null password #{password}, /if if testemail ! 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 idfindUsersByIds resultMapUserResultMap SELECT * FROM user WHERE id IN foreach collectionidList itemid open( separator, close) #{id} /foreach /select说明collection指定输入参数一般为 List 或数组。item是每次迭代的变量。open、separator和close分别定义 SQL 子句的开头、分隔符和结尾。Java 调用代码ListLong idList Arrays.asList(1L, 2L, 3L); ListUser users userMapper.findUsersByIds(idList);生成的 SQLSELECT * FROM user WHERE id IN (1, 2, 3);2. 分页查询分页查询是 Web 应用中最常见的功能之一。在 MyBatis 中可以借助PageHelper插件实现高效分页。2.1 使用 PageHelper 插件1引入依赖在pom.xml中添加以下依赖dependency groupIdcom.github.pagehelper/groupId artifactIdpagehelper-spring-boot-starter/artifactId version1.4.0/version /dependency2分页查询示例在 Service 层调用分页方法import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; public ListUser getUsersByPage(int pageNum, int pageSize) { // 启用分页 PageHelper.startPage(pageNum, pageSize); ListUser users userMapper.getAllUsers(); // 封装分页结果 return new PageInfo(users).getList(); }3自定义分页如果不想引入插件也可以通过手动拼接分页 SQLXML 配置文件select idgetUsersByPage resultMapUserResultMap SELECT * FROM user LIMIT #{offset}, #{pageSize} /selectMapper 接口ListUser getUsersByPage(Param(offset) int offset, Param(pageSize) int pageSize);Java 调用代码int offset (pageNum - 1) * pageSize; ListUser 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 idUserWithOrders typeUser id columnid propertyid/ result columnusername propertyusername/ collection propertyorders ofTypeOrder id columnorder_id propertyid/ result columnorder_name propertyorderName/ /collection /resultMap select idgetUserWithOrders resultMapUserWithOrders 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} /select3.2 嵌套查询对于复杂的多表查询可以使用嵌套查询实现。XML 配置resultMap idOrderResultMap typeOrder id columnid propertyid/ result columnorder_name propertyorderName/ /resultMap resultMap idUserWithOrders typeUser id columnid propertyid/ result columnusername propertyusername/ collection propertyorders resultMapOrderResultMap columnid/ /resultMap select idgetUserWithOrders resultMapUserWithOrders SELECT * FROM user WHERE id #{id}; /select六、最佳实践1. 分层设计Controller 层负责接收请求和返回响应。Service 层封装业务逻辑。Mapper 层专注于数据库交互。2. 避免 N1 查询一对多、多对多场景中优先使用联合查询或嵌套查询避免多个 SQL 执行。3. 启用日志在application.yml中启用 MyBatis 日志mybatis: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl4. 动态 SQL使用foreach实现批量操作。使用if结合set实现动态更新。总结MyBatis 的高级功能如动态 SQL、分页查询和复杂对象映射为开发者提供了极大的灵活性。在项目中结合实际场景选择合适的实现方式可以显著提高开发效率并降低维护成本。如果有任何疑问欢迎在评论区留言讨论