Mybatis-Plus
简介
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
个人认为是一个比较好的工具,里面封装了很多增删改查的方法,为开发提高了效率
接下来我将用一个官网给的一个实例来使用MP,来看看它的功能
我使用的是mySQL5.7版本
下面是user表的创建语句,为了之后的操作,我根据官网改动了一下
其对应的数据库建表和初始化数据的sql如下:
DROP TABLE
IF
EXISTS USER;
CREATE TABLE `user` (
`id` BIGINT ( 20 ) NOT NULL COMMENT '主键ID',
`name` VARCHAR ( 30 ) DEFAULT NULL COMMENT '姓名',
`age` INT ( 11 ) DEFAULT NULL COMMENT '年龄',
`email` VARCHAR ( 50 ) DEFAULT NULL COMMENT '邮箱',
`create_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`version` INT ( 255 ) DEFAULT NULL,
`deleted` INT ( 255 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8;
DELETE
FROM
USER;
INSERT INTO `user` ( id, NAME, age, email, create_time, update_time, `version`, `deleted` )
VALUES
( 1, 'Jone', 18, 'test1@baomidou.com', SYSDATE(), NULL, 1, 0 ),
( 2, 'Jack', 20, 'test2@baomidou.com', SYSDATE(), NULL, 1, 0 ),
( 3, 'Tom', 28, 'test3@baomidou.com', SYSDATE(), NULL, 1, 0 ),
( 4, 'Sandy', 21, 'test4@baomidou.com', SYSDATE(), NULL, 1, 0 ),
( 5, 'Billie', 24, 'test5@baomidou.com', SYSDATE(), NULL, 1, 0 );
建表后结果如下
现在是代码部分
首先可以使用 Spring Initializer (opens new window)快速初始化一个 Spring Boot 工程
pom依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</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-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在application.yml中添加下面配置,控制台可以看出查询语句log日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
User实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
/**
* 用户id
* 分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法 nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 邮箱
*/
private String email;
/**
* 创建时间
* 插入时填充字段
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新时间
* 插入和更新时填充字段
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 版本
* Version乐观锁注解
*/
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
/**
* 逻辑删除的标志 0表示未删除 1表示已删除
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
}
编写Mapper类 UserMapper.java
package com.itheima.mybatisplusdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mybatisplusdemo.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
正常可以测试了,但是在测试之前我要添加一些功能
MpConfig
package com.itheima.mybatisplusdemo.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.xxx.mybatisplusdemo.mapper") // 扫描mapper包
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页查询
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//乐观锁
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
MyMetaObjectHandler
package com.itheima.mybatisplusdemo.Handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* mp执行添加操作,这个方法执行 添加时候添加默认值
*/
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",new Date(),metaObject);
//版本号,更新时候版本号会增加
this.setFieldValByName("version",1,metaObject);
//逻辑删除 0表示未删除
this.setFieldValByName("deleted",0,metaObject);
}
/**
* mp执行更新操作,这个方法执行 添加时候更新默认值
*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
测试(CRUD)
添加
@Test
public void testAdd() {
User user = new User();
user.setName("Mike");
user.setAge(26);
user.setEmail("Mike@163.com");
int insert = userMapper.insert(user);
System.out.println(insert);
}
结果
可以看到新增加的Mike id是用的雪花算法生成的 创建时间是当前系统时间 version版本号是1
逻辑删除那里是0代表未删除
更新(乐观锁)
由于我们之前写了乐观锁的相关配置,于是更新时候会产生效果
@Test
public void TestOptimisticLockerUpdate(){
//根据id来查出用户
User user = userMapper.selectById(1410421805360873473L);
user.setName("Durant");
user.setEmail("Durant@nba.com");
user.setAge(18);
//更新用户
userMapper.updateById(user);
}
结果
可以看出update_time有内容了,并且version由原来的1改为了2
查询
根据条件查看一条数据
我经常使用的是QueryWrapper构造器,里面封装了很多方法,例如下面这个例子,查询名字含有Durant,年龄等于18的人
@Test
public void testSelect() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name","Durant").eq("age",18);
User user = userMapper.selectOne(queryWrapper);
System.out.println(user);
}
查询结果
查询集合
有特殊条件时,例如查询年龄为18岁的
@Test
public void testSelect() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("age",18);
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
查询结果
无特殊条件
@Test
public void testSelect() {
//查询全部
//如果没有特殊条件queryWrapper可以是null
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
查询结果
可以看到 查询语句时候后面有 where deleted = 0 这是由于我们之前写了关于逻辑删除的注解和配置,接下来演示一下这个逻辑删除
逻辑删除
即假删除,数据库中还有数据
/**
* 逻辑删除(假删除,数据库中还有数据)
*/
@Test
public void TestDelete() {
userMapper.deleteById(1406599038421217282L);
}
执行完成后我们看下控制台
可以看出用的不是delete语句而是update语句
再看下数据
可以看到deleted由原来的0更新成为了1,这样我们就做到了逻辑删除,我们再去查询数据
可以发现刚刚被我们逻辑删除的数据查询不到了,但是数据库依然有这个数据,这样即使在项目实际使用中误删了数据依然可以去数据库中将deleted这一字段改为0就可以恢复数据了
分页查询
使用selectPage即可,也可根据需求使用QueryWrapper构造器来限制内容
@Test
public void TestSelectPage() {
//第一个参数表示当前页数,第二个参数表示一页有几条数据
Page<User> page = new Page<>(2, 3);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
Page<User> userPage = userMapper.selectPage(page, queryWrapper);
//总页数
System.out.println(userPage.getPages());
//当前页
System.out.println(userPage.getCurrent());
//查询数据集合
System.out.println(userPage.getRecords());
//总记录数
System.out.println(userPage.getTotal());
//是否有下一页
System.out.println(userPage.hasNext());
//是否有上一页
System.out.println(userPage.hasPrevious());
}
以上就是我个人经常使用的关于Mybatis-Plus的方法,如果有很重要的方法我不知道的,或者哪里写的不够好欢迎大家来指点,一起进步!
更新
MyMetaObjectHandler
根据官网我发现,3.3.3以后 自动填充功能可以使用lambda
package com.itheima.mybatisplusdemo.Handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* mp执行添加操作,这个方法执行 添加时候添加默认值
*/
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class); // 起始版本 3.3.3(推荐)
//版本号,更新时候版本号会增加
this.strictInsertFill(metaObject, "version", () -> 1, Integer.class);
//逻辑删除 0表示未删除
this.strictInsertFill(metaObject, "deleted", () -> 0, Integer.class);
}
/**
* mp执行更新操作,这个方法执行 添加时候更新默认值
*/
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); // 起始版本 3.3.3(推荐)
}
}
还有,之前都是基于mapper的,接下来我要进行Service的
UserService
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.entity.User;
import java.util.List;
public interface UserService extends IService<User> {
}
UserServiceImpl
package com.itheima.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.entity.User;
import com.itheima.mapper.UserMapper;
import com.itheima.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
接下来就是针对Service上的操作了 基于lambda
其中里面参数是前端传来,根据自己的实际情况进行改动即可
- 查询全部
this.list();
- 根据条件查询单个()
return this.lambdaQuery().eq(StringUtils.isNotBlank(name),User::getName,name).one();
- 根据条件查询list
return this.lambdaQuery().eq(StringUtils.isNotBlank(name),User::getName,name).list();
- update
注意:这种方法乐观锁不生效,官网上说必须查出来再更新才行,所以如果对乐观锁有需求就不能用这个方法
//user是前端传来的。根据id直接将新的user对象更新到数据库中
this.lambdaUpdate().eq(User::getId,user.getId()).update(user);
5.删除
this.lambdaUpdate().eq(User::getId,user.getId()).remove();
- 分页查询
//current:当前第几页 size:这页有几条数据
Page<User> page = new Page<>(current, size);
Page<User> userPage = this.lambdaQuery().page(page);
//总页数
System.out.println(userPage.getPages());
//当前页
System.out.println(userPage.getCurrent());
//查询数据集合
System.out.println(userPage.getRecords());
//总记录数
System.out.println(userPage.getTotal());
//是否有下一页
System.out.println(userPage.hasNext());
//是否有上一页
System.out.println(userPage.hasPrevious());