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):
<mapper namespace="com.demo.mapper.UserMapper">
<!-- 插入操作 -->
<insert id="insert" parameterType="User"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO users(username, email)
VALUES(#{username}, #{email})
</insert>
<!-- 更新操作 -->
<update id="updateEmail">
UPDATE users
SET email = #{email}
WHERE id = #{id}
</update>
</mapper>
核心要点:
- 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导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cjh</groupId>
<artifactId>mybaitis_quickLearning</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybaitis_quickLearning</name>
<description>mybaitis_quickLearning</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<!--mybatis spring boot starter依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!--mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
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
<?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>
<!--指定当前xml文件读取的属性配置文件信息-->
<properties resource="db.properties" />
<settings>
<!-- 启用日志 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 懒加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启驼峰映射 ,为自定义的SQL语句服务-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.cjh.pojo"/>
</typeAliases>
<!--环境配置-->
<environments default="development">
<!--当前使用的开发环境使用的数据源配置信息-->
<environment id="development">
<!--事务管理器 MyBatis不处理事务 表示由JDBC来控制事务-->
<transactionManager type="JDBC"/>
<!--数据源 使用MyBatis内置的连接池技术-->
<dataSource type="POOLED">
<property name="driver" value="${DRIVER}"/>
<property name="url" value="${URL}"/>
<property name="username" value="${USERNAME}"/>
<property name="password" value="${PASSWORD}"/>
</dataSource>
</environment>
</environments>
<!--映射器配置 指定MyBatis的Mapper接口位置-->
<mappers>
<!--配置包扫描 会自动扫描该包下的所有Mapper接口-->
<package name="com.cjh.mapper"/>
</mappers>
</configuration>
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<User> getUser(@PathVariable Integer id) {
User user = userService.getUserById(id);
return user != null ?
ResponseEntity.ok(user) :
ResponseEntity.notFound().build();
}
// 更新邮箱
@PatchMapping("/{id}/email")
public ResponseEntity<String> 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,延迟加载,高级映射,增删改查,面试题在这里由于篇幅问题我放在下篇博客集中讲解,如果觉得写的不错还请一键三联加关注,你们的支持是我坚持创作的最大动力!!