MyBatisPlus的简单使用
mybatisPlus
一,准备工作
1.创建数据库,创建user表
CREATE TABLE USER
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
2.插入数据
INSERT INTO USER (id, NAME, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
3.新建springboot项目
4.添加mybatisplus的依赖
<!-- mybatisPlus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
5.配置数据源
spring:
datasource:
url: jdbc:mysql://(主机ip):3306/mybatisplus?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
6.编写pojo,mapper层
6.1创建User类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
6.2创建UserMapper,并继承BaseMapper,此处的泛型是对应的pojo类。
public interface UserMapper extends BaseMapper<User> {
}
此时的UserMapper已经具有父类的所有方法了。如果没有需要的方法,就需要自己编写方法了。
6.3开启包扫描
在启动类上添加@MapperScan注解并指明要扫描的包。
如果不想在启动类上添加@MapperScan。可以在UserMapper接口上添加@Mapper注解(每一个***Mapper都需要添加@Mapper)
二,测试
新建测试类,查询所有数据
@Autowired
UserMapper userMapper;
@Test
void test1() {
List<User> userList = userMapper.selectList(null);
//selectList()
userList.forEach(System.out::println);
}
查询的数据
三,配置日志
在配置文件中添加
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
此时重新执行测试类中的方法,就会显示执行的sql语句
四,测试insert方法
写一个测试方法
@Test
void test() {
User user = new User();
user.setAge(18);
user.setEmail("15644556@qq.com");
user.setName("张三");
int result = userMapper.insert(user);
System.out.println(result);
System.out.println(user);
}
此时我们会发现,我们并没有指明id但是mybatisplus帮我们自动生成了一个id(雪花算法),并将这个id回填到user中。
五,主键策略
实体类字段上添加
@TableId(type = IdType.ID_WORKER)//默认
@TableId(type = IdType.AUTO)//自增,数据库需要设置主键自增
public enum IdType {
AUTO(0),//数据库id自增
NONE(1),//未设置主键
INPUT(2),//手动输入
ID_WORKER(3),//默认的全局唯一id
UUID(4),//全局的唯一id,uuid
ID_WORKER_STR(5);//ID_WORKER 字符串表示法
private int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
六,测试更新
@Test
void test2() {
User user = new User();
user.setAge(18);
user.setId(1L);
user.setEmail("15644556@qq.com");
user.setName("张三");
int result = userMapper.updateById(user);//根据id更新
System.out.println(result);
System.out.println(user);
}
七,自动填充
1.在user表中添加create_time,update_time
2.在user实体类上添加对应的属性
//value数据库的字段名,fill填充的方式
@TableField(value = "create_time",fill = FieldFill.INSERT)
private Date createTime;
@TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
public enum FieldFill {
DEFAULT,//默认无操作
INSERT,//插入时填充
UPDATE,//更新时填充
INSERT_UPDATE;//插入更新时填充
private FieldFill() {
}
}
3.编写对应的处理器
package com.scx.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component//添加到容器中
@Slf4j
public class MyBatisPlusHandler implements MetaObjectHandler {
//插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
//setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
log.info("insert 填充");
}
//更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
log.info("update 填充");
}
}
执行插入操作
@Test
void test() {
User user = new User();
user.setAge(28);
user.setEmail("27535742@qq.com");
user.setName("李四");
int result = userMapper.insert(user);
System.out.println(result);
System.out.println(user);
}
数据库中插入的数据
执行更新操作
@Test
void test2() {
User user = new User();
user.setAge(25);
user.setId(1L);
user.setName("张三111");
int result = userMapper.updateById(user);
System.out.println(result);
System.out.println(user);
}
八,乐观锁
乐观锁:顾名思义十分乐观,它总是认为不会出现问题,无论干什么都不会上锁。如果出现了问题,再次更新值测试。
悲观锁:顾名思义十分悲观,他总是认为出现问题,无论干什么都会上锁。再去操作。
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新操作时,set version = newVersion where version = oldVersion
如果version不对,就更新失败
1.给数据库添加version字段
2.给实体类添加对应的字段
@Version//乐观锁的注解
private Integer version;
3.注册组件
package com.scx.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@Configuration
public class MyBatisPlusConfig {
//注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
4.测试乐观锁成功
@Test
void test3() {
//1.查询
User user = userMapper.selectById(1L);
//2.修改
user.setName("小红");
//3.更新
userMapper.updateById(user);
}
5.测试乐观锁失败
@Test
void test4() {
//线程1
User user1 = userMapper.selectById(1L);
user1.setName("小红111");
//线程2,模拟插队操作
User user2 = userMapper.selectById(1L);
user2.setName("小红222");
userMapper.updateById(user2);
//自旋锁尝试多次提交
userMapper.updateById(user1);
}
“线程1”更新失败
九,查询操作
@Test
void select() {
User user = userMapper.selectById(1L);//通过id查询单个用户
List<User> userList = userMapper.selectBatchIds(Arrays.asList(1l, 2l));//通过id查询多个用户
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("name","Jack");
List<User> userList1 = userMapper.selectByMap(hashMap);//条件查询,通过map查询
System.out.println(user);
userList.forEach(System.out::println);
userList1.forEach(System.out::println);
}
十,分页插件
配置分页插件
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
@Test
void test5() {
//参数一,当前页码,参数二,每页的条数
Page<User> page = new Page<>(1, 5);
IPage<User> iPage = userMapper.selectPage(page, null);
List<User> userList = iPage.getRecords();
userList.forEach(System.out::println);
}
十一,删除操作
@Test
void test6() {
userMapper.deleteById(1l);//通过id删除
userMapper.deleteBatchIds(Arrays.asList(1l, 2L));//通过id集合删除
HashMap<String, Object> map = new HashMap<>();
map.put("name", "小红444");
userMapper.deleteByMap(map);//通过map删除
}
十二,逻辑删除
1.在表中添加一个字段,deleted
2.在对应的实体类中添加字段
@TableLogic//逻辑删除注解
private Integer deleted;
3.配置逻辑删除组件
//逻辑删除组件
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
4.在配置文件中配置
#被删除的值
mybatis-plus.global-config.db-config.logic-delete-value=1
#未被删除的值
mybatis-plus.global-config.db-config.logic-not-delete-value=0
@Test
void test7(){
userMapper.deleteById(1L);
}
查询这条记录
@Test
void test8(){
User user = userMapper.selectById(1L);
System.out.println(user);
}
十三,性能分析插件
1.配置插件
//性能分析插件
@Bean({"dev", "test"})//设置dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(1000);//设置sql执行的最大时间(毫秒)
performanceInterceptor.setFormat(true);//sql格式化
return performanceInterceptor;
}
2.设置开发环境
#设置开发环境
spring.profiles.active=dev
十四,条件构造器
@Test
void test1() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")//name不为空
.ge("age", 15)//age大于15
.eq("version", 1);//version等于1
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}
@Test
void test2() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age", 20, 30);//查询age在20至30的
Integer count = userMapper.selectCount(wrapper);//结果数
System.out.println(count);
}
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name","T");//模糊查询
List<User> userList = userMapper.selectList(wrapper);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.likeLeft("name","T");//%在T的左边 likeRight %在T的右边
List<User> userList = userMapper.selectList(wrapper);