当前位置: 首页 > news >正文

Spring Boot + MyBatis

Spring Boot + MyBatis

  • 一、MyBatis 注解
    • 1. MyBatis 是什么?
    • 2. 准备环境
    • 3. 创建数据库表
    • 4. 新建 Spring Boot 项目依赖
    • 5. 配置数据库与 MyBatis
    • 6. 创建实体类
    • 7. 编写 Mapper 接口
      • 7.1 `@Mapper`
      • 7.2 注解方式的 CRUD
      • 参数绑定
    • 8. 业务层 Service
    • 9. 控制层 Controller
    • 10. 总结
  • 二、MyBatis XML
    • 1. 为什么要用 XML 映射文件
    • 2. 数据库表结构
    • 3. Maven 依赖
    • 4. Spring Boot 配置
    • 5. 实体类
    • 6. Mapper 接口
    • 7. XML 映射文件
      • MyBatis XML 文件扫描方式说明
      • 方式一:通过 `mapper-locations` 配置(推荐)
      • 方式二:与 Mapper 接口同路径同名(自动匹配)
      • 注意事项
    • 8. Service 层
    • 9. Controller 层
    • 10. 总结

一、MyBatis 注解

1. MyBatis 是什么?

MyBatis 是一款优秀的 持久层框架,作用是:

  • 将 SQL 从 Java 代码中分离,写在 XML 或注解中,便于维护。
  • 自动将 SQL 查询结果映射为 Java 对象。
  • 支持动态 SQL、分页、缓存等功能。

相比 JPA(Hibernate),MyBatis 更灵活,SQL 可控性强,适合对性能和 SQL 结构有要求的项目。


2. 准备环境

技术栈:

  • JDK 17(JDK 8 以上均可)
  • Spring Boot 3.x
  • MyBatis-Spring-Boot-Starter
  • MySQL 8.x
  • Maven

3. 创建数据库表

user 表为例:

CREATE DATABASE mybatis_demo DEFAULT CHARSET utf8mb4;USE mybatis_demo;CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updataed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

注意:updataed_at 是保持与你的字段名一致,实际中推荐使用 updated_at


4. 新建 Spring Boot 项目依赖

pom.xml 添加如下依赖:

<dependencies><!-- MyBatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!-- MySQL 驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.3.0</version></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope></dependency>
</dependencies>

5. 配置数据库与 MyBatis

好的,帮你把简短的 URL 各部分说明加到你的配置说明里,整合如下:

spring:datasource:url: jdbc:mysql://localhost:3306/mybatis_demo?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: rootmybatis:type-aliases-package: com.example.demo.entityconfiguration:map-underscore-to-camel-case: true  # 开启驼峰映射
  • spring.datasource 配置数据库连接信息:

    • url:数据库地址和连接参数

      • jdbc:mysql://:使用 JDBC 协议连接 MySQL
      • localhost:数据库服务器地址(本机)
      • 3306:MySQL 默认端口号
      • mybatis_demo:连接的数据库名
      • characterEncoding=utf8:设置字符编码为 UTF-8,防止乱码
      • useSSL=false:关闭 SSL 连接
      • serverTimezone=Asia/Shanghai:设置时区为上海,避免时间偏差
    • username:数据库用户名

    • password:数据库密码

  • mybatis.type-aliases-package
    指定实体类所在包,MyBatis 自动为包内类生成别名,简化 SQL 映射配置。

  • mybatis.configuration.map-underscore-to-camel-case
    开启数据库字段下划线到 Java 驼峰命名的自动映射,如 created_at 自动映射为 createdAt,减少手动配置。

6. 创建实体类

@Data 来自 Lombok,自动生成 getter/setter、toString、equals、hashCode 等,减少样板代码。

package com.example.demo.entity;import lombok.Data;
import java.time.LocalDateTime;@Data
public class User {private Integer id;private String username;private LocalDateTime createdAt;private LocalDateTime updataedAt; // 保持与数据库字段名一致
}

7. 编写 Mapper 接口

7.1 @Mapper

标记接口为 MyBatis Mapper,Spring Boot 自动扫描并生成代理。

package com.example.demo.mapper;import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;@Mapper
public interface UserMapper {@Select("SELECT id, username FROM user")List<User> findAll();
}

7.2 注解方式的 CRUD

  • @Select:查询,返回实体或集合
  • @Insert:插入,参数为对象,返回受影响行数
  • @Update:更新,返回受影响行数
  • @Delete:删除,返回受影响行数

参数绑定

  • 使用 #{参数名} 绑定方法参数或对象属性
  • 基础类型参数直接绑定变量名,对象参数绑定属性名

示例:

@Mapper
public interface UserMapper {@Select("SELECT id, username FROM user")List<User> findAll();@Select("SELECT id, username FROM user WHERE id = #{id}")User findById(int id);@Insert("INSERT INTO user (username) VALUES (#{username})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);@Update("UPDATE user SET username=#{username} WHERE id=#{id}")int update(User user);@Delete("DELETE FROM user WHERE id = #{id}")int delete(int id);
}

@Options(useGeneratedKeys = true, keyProperty = "id") 会将数据库自动生成的主键回写到 User 实体的 id 字段。


8. 业务层 Service

封装调用 Mapper,方便扩展业务逻辑:

package com.example.demo.service;import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;@Service
public class UserService {@Resourceprivate UserMapper userMapper;public List<User> getAllUsers() {return userMapper.findAll();}public User getUserById(int id) {return userMapper.findById(id);}public int addUser(User user) {return userMapper.insert(user);}public int updateUser(User user) {return userMapper.update(user);}public int deleteUser(int id) {return userMapper.delete(id);}
}

9. 控制层 Controller

接收 HTTP 请求,调用 Service,返回 JSON 结果或操作提示。

package com.example.demo.controller;import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.List;@Slf4j
@RestController
@RequestMapping("/t")
public class TetsController {@Autowiredprivate UserService userService;@GetMapping("/getAllUsers")public List<User> getAllUsers() {log.info("请求获取所有用户");return userService.getAllUsers();}@GetMapping("/getUserById/{id}")public User getUserById(@PathVariable int id) {log.info("请求获取用户,id={}", id);return userService.getUserById(id);}@PostMapping("/addUser")public String addUser(@RequestBody User user) {log.info("请求添加用户: {}", user);int result = userService.addUser(user);return result > 0 ? "添加用户成功" : "添加用户失败";}@PutMapping("/updateUser")public String updateUser(@RequestBody User user) {log.info("请求更新用户: {}", user);int result = userService.updateUser(user);return result > 0 ? "更新用户成功" : "更新用户失败";}@DeleteMapping("/deleteUser/{id}")public String deleteUser(@PathVariable int id) {log.info("请求删除用户,id={}", id);int result = userService.deleteUser(id);return result > 0 ? "删除用户成功" : "删除用户失败";}
}

10. 总结

  • 使用 @Mapper 注解标记 Mapper 接口,简化开发流程。
  • 注解方式定义 SQL,免去 XML 配置,开发更快捷。
  • 通过 @Options 实现主键自动回写,方便获取插入记录的 ID。
  • 业务层封装 Mapper 操作,易于扩展。
  • 控制层处理 HTTP 请求,结合日志打印,便于调试和维护。

二、MyBatis XML

1. 为什么要用 XML 映射文件

虽然注解方式简单,但对于以下情况,XML 方式更适合:

  • SQL 较复杂(多表关联、动态 SQL、分页)。
  • 需要维护大量 SQL,集中管理更方便。
  • 便于 DBA 直接修改 SQL,不影响 Java 代码。

2. 数据库表结构

使用前面教程的 user 表:

CREATE DATABASE mybatis_demo DEFAULT CHARSET utf8mb4;USE mybatis_demo;CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

(这里我把 updataed_at 改成了 updated_at


3. Maven 依赖

pom.xml 跟注解版相同:

<dependencies><!-- MyBatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!-- MySQL 驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.3.0</version></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version><scope>provided</scope></dependency>
</dependencies>

4. Spring Boot 配置

application.yml

spring:datasource:url: jdbc:mysql://localhost:3306/mybatis_demo?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: rootmybatis:type-aliases-package: com.example.demo.entity  # 别名包mapper-locations: classpath:mapper/*.xml       # XML 文件位置configuration:map-underscore-to-camel-case: true           # 下划线转驼峰

5. 实体类

com/example/demo/entity/User.java

package com.example.demo.entity;import lombok.Data;
import java.time.LocalDateTime;@Data
public class User {private Integer id;private String username;private LocalDateTime createdAt;private LocalDateTime updatedAt;
}

6. Mapper 接口

com/example/demo/mapper/UserMapper.java

package com.example.demo.mapper;import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface UserMapper {List<User> findAll();User findById(int id);int insert(User user);int update(User user);int delete(int id);
}

7. XML 映射文件

MyBatis XML 文件扫描方式说明

MyBatis 在运行时需要加载 .xml 映射文件(Mapper XML),常用的两种方式如下:


方式一:通过 mapper-locations 配置(推荐)

application.ymlapplication.properties 中显式指定扫描路径:

mybatis:mapper-locations: classpath:mapper/*.xml
  • classpath: 表示 src/main/resources/ 下的路径。
  • mapper/*.xml 表示扫描 resources/mapper/ 目录下的所有 .xml 文件。
  • 优点:XML 文件集中管理在 mapper 目录,结构清晰。

路径结构示例:

src├─ main│   ├─ java│   │    └─ com/example/demo/mapper/UserMapper.java│   └─ resources│        └─ mapper/UserMapper.xml

方式二:与 Mapper 接口同路径同名(自动匹配)

  • .xml 文件放在与 Mapper 接口 相同的包路径下,并与接口同名。
  • MyBatis 会根据 Mapper 接口的全类名自动去匹配对应的 XML 文件。
  • 优点:不需要在 application.yml 里配置 mapper-locations

路径结构示例:

src├─ main│   ├─ java│   │    └─ com/example/demo/mapper/UserMapper.java│   └─ resources│        └─ com/example/demo/mapper/UserMapper.xml

注意事项

  1. namespace 必须与 Mapper 接口全类名一致
    例如:

    <mapper namespace="com.example.demo.mapper.UserMapper">
    
  2. SQL 标签 <select><insert><update><delete>id 必须和接口方法名一致。

  3. 如果不配置 mapper-locations,但路径又没和接口保持一致,MyBatis 就找不到 XML 文件,会报错:

    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    

这是 MyBatis Mapper XML 文件的 DOCTYPE声明,作用是告诉解析器这个 XML 文件遵循 MyBatis 3.0 的规范,帮助验证文件结构和语法正确性。

<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
  • mapper 是根元素名
  • 指定了官方托管的 DTD 文件地址
  • 有助于IDE校验和智能提示

src/main/resources/mapper/UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.demo.mapper.UserMapper"><!-- namespace 指定当前 XML 映射文件对应的 Mapper 接口的全限定名,MyBatis 根据它来绑定接口方法和 XML 语句 --><!-- 查询全部 --><select id="findAll" resultType="User"><!-- id 是方法名,MyBatis 会绑定接口 UserMapper 的 findAll() 方法调用此 SQL --><!-- resultType 指定返回的 Java 类型,这里返回 User 实体类 -->SELECT id, username, created_at, updated_atFROM user</select><!-- 根据 ID 查询 --><select id="findById" parameterType="int" resultType="User"><!-- parameterType 指定传入参数类型,这里是基本类型 int -->SELECT id, username, created_at, updated_atFROM userWHERE id = #{id}<!-- #{id} 是参数占位符,MyBatis 会将接口方法参数传入此处 --></select><!-- 插入用户 --><insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id"><!-- useGeneratedKeys = true 表示使用 JDBC 的 getGeneratedKeys 方法自动获取数据库生成的主键 --><!-- keyProperty = "id" 指定将主键回写到 User 对象的 id 属性 -->INSERT INTO user (username)VALUES (#{username})</insert><!-- 更新用户 --><update id="update" parameterType="User">UPDATE userSET username = #{username}WHERE id = #{id}</update><!-- 删除用户 --><delete id="delete" parameterType="int">DELETE FROM user WHERE id = #{id}</delete></mapper>

8. Service 层

跟注解版一致:

package com.example.demo.service;import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<User> getAllUsers() {return userMapper.findAll();}public User getUserById(int id) {return userMapper.findById(id);}public int addUser(User user) {return userMapper.insert(user);}public int updateUser(User user) {return userMapper.update(user);}public int deleteUser(int id) {return userMapper.delete(id);}
}

9. Controller 层

跟注解版一致:

package com.example.demo.controller;import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.List;@Slf4j
@RestController
@RequestMapping("/t")
public class TestController {@Autowiredprivate UserService userService;@GetMapping("/getAllUsers")public List<User> getAllUsers() {return userService.getAllUsers();}@GetMapping("/getUserById/{id}")public User getUserById(@PathVariable int id) {return userService.getUserById(id);}@PostMapping("/addUser")public String addUser(@RequestBody User user) {int result = userService.addUser(user);return result > 0 ? "添加用户成功" : "添加用户失败";}@PutMapping("/updateUser")public String updateUser(@RequestBody User user) {int result = userService.updateUser(user);return result > 0 ? "更新用户成功" : "更新用户失败";}@DeleteMapping("/deleteUser/{id}")public String deleteUser(@PathVariable int id) {int result = userService.deleteUser(id);return result > 0 ? "删除用户成功" : "删除用户失败";}
}

10. 总结

  • XML 文件方式更适合复杂的 SQL 管理和动态 SQL
  • 通过 mapper-locations 配置扫描 XML 文件更灵活,结构清晰
  • XML 中 namespace 和接口必须严格对应
  • SQL 语句写法标准,可复用性好,便于维护
  • 注解方式适合简单场景,XML 方式适合复杂业务
  • 配合 Spring Boot,MyBatis 代码简洁高效,开发友好
http://www.lryc.cn/news/619643.html

相关文章:

  • Python 元类基础:从理解到应用的深度解析
  • [CSCCTF 2019 Qual]FlaskLight
  • [AI React Web] 包与依赖管理 | `axios`库 | `framer-motion`库
  • Spring cloud集成ElastictJob分布式定时任务完整攻略(含snakeyaml报错处理方法)
  • 使用TexLive与VScode排版论文
  • 从0开始配置conda环境并在PyCharm中使用
  • Node.js浏览器引擎+Python大脑的智能爬虫系统
  • 低成本扩展方案:S7-200SMART作为S7-1500分布式IO从站的上位机配置指南
  • Linux网络性能调优终极指南:深度解析与实践
  • 初识c语言————排序方法
  • 【新手入门】Android Studio 项目结构拆解,快速理解文件作用!
  • 【Linux】常用命令(三)
  • 数据结构:用数组实现队列(Implementing Queue Using Array)
  • Python实现点云概率ICP(GICP)配准——精配准
  • 8.13打卡 DAY 41 简单CNN
  • 多模态RAG赛题实战之策略优化--Datawhale AI夏令营
  • 桌面运维如何深造
  • MySQL表约束
  • Spring Boot项目中线程池的全面教程
  • 中高级餐饮服务食品安全员考试核心知识点汇总
  • Spring Boot初级概念及自动配置原理
  • Spring Boot 3 连接池最大连接数设置建议
  • sample_kol里配置为 deep sleep mode,则系统进入 STR
  • Spring、Spring MVC、Spring Boot与Spring Cloud的扩展点全面梳理
  • Python【算法中心 03】Docker部署Django搭建的Python应用流程实例(Docker离线安装配置+Django项目Docker部署)
  • django name ‘QueryDict‘ is not defined
  • 更改webpack默认配置项
  • Git Bash
  • 导轨焊接机器人:重塑高效精准焊接的新标杆
  • VUE3中的内置 API