MyBatis极速通关上篇:Spring Boot环境搭建+用户管理实战 - 教程
Mybatis简介
概念理解
Mybatis是一种ORM框架技术(Object Relation Mapping)
ORM也就是对象关系映射,简单理解就是将一个Java中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可以操作数据库中的表
Mybatis特性
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层,轻量级框架
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架
mybatis项目框架结构讲解
基于maven,mybatis,springboot的项目标准结构如下:
mybatis-demo/ # 项目根目录
├── src/
│ ├── main/
│ │ ├── java/ # Java 源代码
│ │ │ └── com/
│ │ │ └── cjh/
│ │ │ ├── pojo/ # 实体类(与数据库表对应)
│ │ │ ├── mapper/ # Mapper 接口(DAO层)
│ │ │ ├── service/ # 业务逻辑层
│ │ │ │ ├── impl/ # 服务实现类
│ │ │ │ └── UserService.java
│ │ │ └── MainApp.java # 主程序入口
│ │ └── resources/ # 资源文件│ │ │ └── com/
│ │ │ └── cjh/
│ │ └──mapper/ # MyBatis XML 映射文件
│ │ ├── mybatis-config.xml # MyBatis 主配置文件
│ │ └── jdbc.properties # 数据库连接配置
│ └── test/ # 测试代码(结构类似main)
├── target/ # 编译输出目录
└── pom.xml # Maven 配置文件
下面我将逐个讲解各个包层的职责:
pojo层
该层下的类都是实体类,负责映射数据库的各个表,一个实体类就负责映射一张表,实体类下的属性与表字段一 一对应,一般情况下为了直接映射方便实体类属性名与表字段名都一致。
举例现在有一张表建表语句如下:
CREATE TABLE `emp` (
`id` int NOT NULL AUTO_INCREMENT,
`account` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`sex` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`age` int NOT NULL,
PRIMARY KEY (`id`) USING BTREE
)
那他对应的实体类就是:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Emp {
private Integer id;
private String account;
private String name;
private String password;
private String sex;
private Integer age;
}
这是最基础的实体类属性映射表字段的写法,如果要同时映射不同表的字段那实体类还会封装更多属性,具体情况后面再说
Mapper 层(数据访问层)
数据访问接口,定义数据库操作方法,只定义接口方法不做具体实现,sql语句编写在MyBatis XML 映射文件也可以直接在接口方法通过注解直接写sql语句(适用于较简单的sql语句)。
package com.demo.mapper;
// 使用MyBatis注解标识接口
@Mapper
public interface UserMapper {
// 通过ID查询(注解方式)
@Select("SELECT * FROM users WHERE id = #{id}")
User selectById(int id);
// 插入用户(XML方式)
void insert(User user);
// 更新邮箱(参数名指定)
void updateEmail(@Param("id") int id,
@Param("email") String email);
}
映射文件(resources/mapper/UserMapper.xml):
INSERT INTO users(username, email)
VALUES(#{username}, #{email})
UPDATE users
SET email = #{email}
WHERE id = #{id}
核心要点:
- 1.接口方法名 ↔ XML SQL语句ID
- 2.参数传递:
- •单参数:直接使用
#{参数名}
- •多参数:用
@Param("name")
指定- 3.返回值处理:
- •单对象:返回实体类型
- •集合:List<Entity>
- 4.主键回填:
useGeneratedKeys="true" keyProperty="id"
service层
负责业务逻辑封装,是事务控制中心
定义接口和接口方法,例如UserService接口就负责定义有关用户表操作的所有接口方法,然后由具体实现类实现方法
package com.demo.service;
public interface UserService {
// 业务方法:用户注册
User registerUser(UserDTO userDTO) throws ServiceException;
// 业务方法:获取用户信息
UserInfoVO getUserInfo(int id);
}
package com.demo.service.impl;
@Service
public class UserServiceImpl implements UserService {
// 依赖Mapper接口(Spring注入)
@Autowired
private UserMapper userMapper;
@Autowired
private EmailService emailService;
@Override
@Transactional // 事务控制注解
public User registerUser(UserDTO userDTO) {
// 1. 参数校验
if(userMapper.existsByUsername(userDTO.getUsername())) {
throw new ServiceException("用户名已存在");
}
// 2. 数据转换
User user = convertToEntity(userDTO);
// 3. 核心业务操作
userMapper.insert(user);
emailService.sendWelcomeEmail(user);
// 4. 返回结果处理
return user;
}
private User convertToEntity(UserDTO dto) {
// 对象转换逻辑...
}
}
设计原则:
- 1.单一职责:每个方法完成单一业务功能
- 2.依赖倒置:通过接口提供服务
- 3.事务控制:使用
@Transactional
管理事务- 4.异常处理:抛出自定义业务异常
resource层
用来存放配置文件和一些静态资源
例如MyBatis 主配置(mybatis-config.xml)
SQL映射文件特征
Mybatis快速入门
讲解完基础知识后接下来我们通过一个小项目来快速入门一下Mybatis
示例项目:用户管理系统
实现功能:用户注册、查询用户信息
0.建库建表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL
);
1.创建springboot项目
2.搭建基础框架
3.pom.xml导入依赖
4.0.0
org.springframework.boot
spring-boot-starter-parent
3.5.4
com.cjh
mybaitis_quickLearning
0.0.1-SNAPSHOT
mybaitis_quickLearning
mybaitis_quickLearning
17
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
runtime
true
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
1.18.28
org.mybatis.spring.boot
mybatis-spring-boot-starter
3.0.3
mysql
mysql-connector-java
8.0.19
org.springframework.boot
spring-boot-maven-plugin
4.编写核心配置文件
4.1 application.properties
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/数据库名?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=数据库密码
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.mapper-locations=classpath*:mapper/com/cjh/mapper/*.xml
mybatis.type-aliases-package=com.cjh.pojo
4.2 mybatis-config.xml
5.创建实体类映射表
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
private Integer id;
private String username;
private String password;
private String email;
}
6.编写mapper层接口
@Mapper
public interface UserMapper {
// 用户注册
int insertUser(User user);
// 根据ID查询用户
User selectUserById(@Param("id") Integer id);
// 根据用户名查询用户
User selectByUsername(@Param("username") String username);
// 更新用户邮箱
int updateEmail(@Param("id") Integer id, @Param("email") String email);
}
7.编写服务层接口
public interface UserService {
User registerUser(User user) throws Exception;
User getUserById(Integer id);
void updateEmail(Integer id, String email);
}
8.编写服务层接口实现类
package com.cjh.service.impl;
import com.cjh.mapper.UserMapper;
import com.cjh.pojo.User;
import com.cjh.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User registerUser(User user) throws Exception {
// 检查用户名是否已存在
User existingUser = userMapper.selectByUsername(user.getUsername());
if (existingUser != null) {
throw new Exception("用户名已存在");
}
// 插入用户数据
userMapper.insertUser(user);
// 返回带有ID的用户对象
return userMapper.selectUserById(user.getId());
}
@Override
public User getUserById(Integer id) {
return userMapper.selectUserById(id);
}
@Override
public void updateEmail(Integer id, String email) {
// 这个方法在UserService接口中被注释掉了,如果需要可以取消注释并实现
userMapper.updateEmail(id, email);
}
}
9.controller层实现
package com.cjh.controller;
import com.cjh.pojo.User;
import com.cjh.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
// 用户注册
@PostMapping("/register")
public ResponseEntity register(@RequestBody User user) {
try {
User registeredUser = userService.registerUser(user);
return ResponseEntity.ok(registeredUser);
} catch (Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
// 查询用户
@GetMapping("/{id}")
public ResponseEntity getUser(@PathVariable Integer id) {
User user = userService.getUserById(id);
return user != null ?
ResponseEntity.ok(user) :
ResponseEntity.notFound().build();
}
// 更新邮箱
@PatchMapping("/{id}/email")
public ResponseEntity updateEmail(@PathVariable Integer id, @RequestBody String email) {
userService.updateEmail(id, email);
return ResponseEntity.ok("邮箱更新成功");
}
}
准备完成后的项目目录结构如图:
接下来我们启动MybaitisQuickLearningApplication启动类
测试:
使用Postman或者apifox测试
POST http://localhost:8080/api/users/register
Body: {
"username": "testUser",
"password": "123456",
"email": "test@example.com"
}
如果服务器返回是200,那么恭喜你完成了这个小项目
关于mybatis的动态sql,延迟加载,高级映射,增删改查,面试题在这里由于篇幅问题我放在下篇博客集中讲解,如果觉得写的不错还请一键三联加关注,你们的支持是我坚持创作的最大动力!!