目录
一、MyBatis-Plus介绍
二、基础使用
2.1 准备工作
2.2 编码
2.3 CRUD单元测试
三、MyBatis-Plus复杂操作
3.1 打印日志
3.2 常见注解
3.2.1 @TableName
3.2.2 @TableField
3.2.3 @TableId
3.3 条件构造器
3.3.1 QueryWrapper
3.3.2 UpdateWrapper
3.3.3 LambdaQueryWrapper 和 LambdaUpdateWrapper
一、MyBatis-Plus介绍
二、基础使用
Mybatis-Plus操作数据库的步骤:
- 准备工作(数据准备, 项目准备, 引入依赖, 配置数据库连接信息)
- 编码(数据库表对应的实体类, 以及数据操作的Mapper文件)
- 测试
以下使用具体的例子体现 MyBatis-Plus 是如何操作数据库的。
2.1 准备工作
-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`username` VARCHAR ( 127 ) NOT NULL,
`password` VARCHAR ( 127 ) NOT NULL,
`age` TINYINT ( 4 ) NOT NULL,
`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
`phone` VARCHAR ( 15 ) DEFAULT NULL,
`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
-- 添加⽤⼾信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>
Spring Boot3
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
MySQL
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
配置数据库:
application.yml文件格式:
# 数据库连接配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?
characterEncoding=utf8&useSSL=false
#连接数据库的⽤⼾名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=root
2.2 编码
创建实体类UserInfo
import lombok.Data;
import java.util.Date;
@Data
public class UserInfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}
也可以在启动类上添加 @MapperScan , 扫描Mapper文件夹, ⼆选一即可。
2.3 CRUD单元测试
@SpringBootTest
class MybatisPlusDemoApplicationTests {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void testInsert() {
UserInfo user = new UserInfo();
user.setUsername("bite");
user.setPassword("123456");
user.setAge(11);
user.setGender(0);
user.setPhone("18610001234");
userInfoMapper.insert(user);
}
@Test
void testSelectById() {
UserInfo user = userInfoMapper.selectById(1L);
System.out.println("user: " + user);
}
@Test
void testSelectByIds() {
List<UserInfo> users = userInfoMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));
users.forEach(System.out::println);
}
@Test
void testUpdateById() {
UserInfo user = new UserInfo();
user.setId(1);
user.setPassword("4444444");
userInfoMapper.updateById(user);
}
@Test
void testDelete() {
userInfoMapper.deleteById(5L);
}
}
结果如下,执行成功:
三、MyBatis-Plus复杂操作
3.1 打印日志
mybatis-plus:
configuration: # 配置打印 MyBatis⽇志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.2 常见注解
- 表名: 实体类的驼峰表示法转换成蛇形表示法(下划线分割), 作为表名。比如UserInfo -> user_info
- 字段: 根据实体类的属性名转换为蛇形表示法作为字段名。比如deleteFlag -> delete_flag
-
主键: 默认为id
3.2.1 @TableName
@Data
@TableName("user_info")
public class Userinfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
3.2.2 @TableField
@Data
@TableName("user_info")
public class Userinfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
@TableField("delete_flag")
private Integer deleteflag;
private Date createTime;
private Date updateTime;
}
3.2.3 @TableId
@Data
@TableName("user_info")
public class Userinfo {
@TableId("id")
private Integer userId;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
@TableField("delete_flag")
private Integer deleteflag;
private Date createTime;
private Date updateTime;
}
3.3 条件构造器
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL注入的风险。
- AbstractWrapper:这是⼀个抽象基类, 提供了所有 Wrapper 类共有的方法和属性。
- QueryWrapper:用于构造查询条件, 在AbstractWrapper的基础上拓展了一个select方法, 允许指定查询字段。
- UpdateWrapper: 用于构造更新条件, 可以在更新数据时指定条件。
- LambdaQueryWrapper:基于 Lambda 表达式的查询条件构造器, 它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名。
- LambdaUpdateWrapper: 基于 Lambda 表达式的更新条件构造器, 它允许你使用 Lambda 表达 式来指定更新字段和条件,同样避免了硬编码字段名的问题。
3.3.1 QueryWrapper
查询:
@Test
void testQueryWrapper(){
QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>()
.select("id","username","password","age")
.eq("age",18)
.like("username", "min");
List<UserInfo> userInfos = userInfoMapper.selectList(userInfoQueryWrapper);
userInfos.forEach(System.out::println);
}
更新:
@Test
void testUpdateByQueryWrapper(){
QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>()
.lt("age", 20);
UserInfo userInfo = new UserInfo();
userInfo.setDeleteFlag(1);
userInfoMapper.update(userInfo, userInfoQueryWrapper);
}
• lt : "less than" 的缩写,表示小于;• le : "less than or equal to"的缩写,表示小于等于;• ge : "greater than or equal to" 的缩写,表示大于等于;• gt : "greater than" 的缩写,表示大于;• eq : "equals" 的缩写,表示等于;• ne : "not equals" 的缩写,表示不等于;
删除:
@Test
void testDeleteByQueryWrapper(){
QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>()
.eq("age",18);
userInfoMapper.delete(userInfoQueryWrapper);
3.3.2 UpdateWrapper
- 基础更新:
UPDATE user_info SET delete_flag=0, age=5 WHERE id IN (1,2,3)
测试代码:
@Test
void testUpdateByUpdateWrapper(){
UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>()
.set("delete_flag",0)
.set("age", 5)
.in("id", List.of(1,2,3));
userInfoMapper.update(updateWrapper);
}
- 基于SQL更新:
UPDATE user_info SET age = age+10 WHERE id IN (1,2,3)
测试代码:
@Test
void testUpdateBySQLUpdateWrapper(){
UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>()
.setSql("age = age+10")
.in("id", List.of(1,2,3));
userInfoMapper.update(updateWrapper);
}
3.3.3 LambdaQueryWrapper 和 LambdaUpdateWrapper
QueryWrapper 和 UpdateWrapper存在一个问题,就是需要写死字段名,如果字段名发生变更, 可能会因为测试不到位酿成事故。MyBatis-Plus 给我们提供了一种基于Lambda表达式的条件构造器, 它通过 Lambda 表达式来引用实体类的属性,从而避免了硬编码字段名,,也提高了代码的可读性和可维护性。
LambdaQueryWrapper 和 LambdaUpdateWrapper 分别对应上述的 QueryWrapper 和 UpdateWrapper。
用法:
@Test
void testLambdaQueryWrapper(){
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>();
queryWrapper.lambda()
.select(UserInfo::getUsername, UserInfo::getPassword,UserInfo::getAge)
.eq(UserInfo::getUserId, 1);
userInfoMapper.selectList(queryWrapper).forEach(System.out::println);
}
@Test
void testLambdUpdateByUpdateWrapper(){
UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>();
updateWrapper.lambda()
.set(UserInfo::getDeleteFlag, 0)
.set(UserInfo::getAge, 5)
.in(UserInfo::getUserId, List.of(1,2,3));
userInfoMapper.update(updateWrapper);
}