1.3 代码编写
在com.star包下创建两个包,并创建User实体类和UserMapper接口,目录结构如下:
-
entity包:用来放实体类
-
mapper包:用来放持久层接口
这里还需要让springboot扫描到mapper接口,在MybatisplusdemoApplication类中添加注解@MapperScan(“com.star.mapper”)
@SpringBootApplication
@MapperScan(“com.star.mapper”) //扫描到mapper接口
public class MybatisplusdemoApplication {…}
1.3.1 编写User实体类
package com.star.entity;
import lombok.Data;
/**
-
@Description: User实体类
-
@Date: Created in 11:54 2020/7/28
-
@Author: ONESTAR
-
@QQ群: 530311074
-
@URL: https://onestar.newstar.net.cn/
*/
@Data //可以简化实体类
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
分析:
- @Data注解:用于简化实体类,可以不用写get、set等方法
- @TableId(type = IdType.AUTO)注解:这是主键策略注解
* AUTO:表示自动增长策略
* INPUT:表示需要自己设置ID,需要输入
* NONE:表示没有策略,需要输入
* UUID:随机生成唯一的值
* ID\_WORKER:mybatisplus自带策略,生成19位的值,数字类型使用该策略
* ID\_WORKER\_STR:mybatisplus自带策略,生成19位的值,字符串类型使用该策略
1.3.2 编写UserMapper接口
- @Repository注解:可有可无,可以消去依赖注入的报错信息
package com.star.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.star.entity.User;
import org.springframework.stereotype.Repository;
/**
-
@Description: UserMapper接口
-
@Date: Created in 11:57 2020/7/28
-
@Author: ONESTAR
-
@QQ群: 530311074
-
@URL: https://onestar.newstar.net.cn/
*/
@Repository
public interface UserMapper extends BaseMapper {
}
1.3.3 编写测试类(简单增删改查)
编写好以上代码后,框架基本就搭建好了,可以在测试类中进行测试了,在test中添加测试,代码如下:
- 注入mapper
@Autowired
private UserMapper userMapper;
- 简单增删改查
//查询User
@Test
void findUser() {
//查询列表
List user = userMapper.selectList(null);
System.out.println(“user:” + user);
//根据ID查询
User user1 = userMapper.selectById(1L);
System.out.println(“user1:” + user1);
//通过多个ID批量查询
List users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
//简单的条件查询
HashMap<String, Object> map = new HashMap<>();
map.put(“name”, “onestar”);
map.put(“age”, 18);
List users2 = userMapper.selectByMap(map);
users2.forEach(System.out::println);
}
//添加User
@Test
void addUser(){
User user = new User();
user.setName(“sixstar”);
user.setAge(18);
user.setEmail(“sixstar@136.com”);
int insert = userMapper.insert(user);
System.out.println(insert);
}
//修改User
@Test
void updateUser(){
User user = new User();
user.setId(1L);
user.setAge(12);
int result = userMapper.updateById(user);
System.out.println(result);
}
//删除User
@Test
void deleteUser(){
//根据ID删除
int result = userMapper.deleteById(5L);
System.out.println(result);
//批量删除
int result2 = userMapper.deleteBatchIds(Arrays.asList(1,2,3));
System.out.println(result2);
//简单的条件删除
HashMap<String,Object> map = new HashMap<>();
map.put(“name”,“fourstar”);
map.put(“age”,18);
int result3 = userMapper.deleteByMap(map);
System.out.println(result3);
}
分析:
这里基本上都是直接调用mybatisplus封装好了的方法,有一些基本的方法:
- 查询列表:selectList
- 根据ID查询:selectById
- 根据ID批量查询:selectBatchIds
- 条件查询:selectByMap
- 添加:insert
- 根据ID修改:updateById
- 根据ID删除:deleteById
- 根据ID批量删除:deleteBatchIds
- 条件删除:deleteByMap
2. 提升案例
进阶案例主要讲以下几个知识点:
-
分页查询
-
自动填充
-
mybatisplus实现乐观锁
-
逻辑删除
-
性能分析
-
复杂条件查询
2.1 分页查询
Mybatis-Plus是自带了分页查询功能的,直接使用自集成的插件进行分页查询,在使用之前要配置插件,可以专门创建一个配置类来配置插件
2.1.1 配置插件
在com.star包下创建config包,创建MpConfig配置类,添加分页插件
package com.star.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
-
@Description: 配置类
-
@Date: Created in 10:26 2020/7/29
-
@Author: ONESTAR
-
@QQ群: 530311074
-
@URL: https://onestar.newstar.net.cn/
*/
@Configuration
public class MpConfig {
/**
- 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
2.1.2 测试分页
//分页查询
@Test
void selectPage(){
//创建page对象(1:当前页;3:每页显示记录数)
Page page = new Page<>(1,3);
//调用分页查询方法,将分页所有数据封装到page对象里面
userMapper.selectPage(page,null);
//通过page对象获取分页数据
System.out.println(page.getCurrent()); //当前页
System.out.println(page.getRecords()); //每页数据list集合
System.out.println(page.getPages()); //总页数
System.out.println(page.getSize()); //每页显示记录数
System.out.println(page.getTotal()); //总记录数
System.out.println(page.hasNext()); //是否有下一页
System.out.println(page.hasPrevious()); //是否有上一页
}
分析:
- 创建page对象:new Page<>(1,3); 参数表示当前页和每页显示记录数
- 调用分页查询方法,将分页所有数据封装到page对象里面:selectPage(page,null);
- 通过调用Mybatisplus插件提供的方法实现分页功能
* page.getCurrent():当前页
* page.getRecords():每页数据list集合
* page.getPages():总页数
* page.getSize():每页显示记录数
* page.getTotal():总记录数
* page.hasNext():是否有下一页
* page.hasPrevious():是否有上一页
2.2 自动填充
在平时开发中,会有些数据需要自动填充,比如创建时间、更新时间等,这就可以使用MybatisPlus的自动填充功能,这里就以创建时间和更新时间为例进行演示
2.2.1 添加字段
User表中添加字段:
-
创建时间:create_time
-
更新时间:update_time
实体类添加属性和注解
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
2.2.2 实现元对象处理器接口
这里专门创建一个hander包来访处理器接口,在com.star包下创建hander包,创建MyMetaObjectHandler接口
package com.star.hander;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
-
@Description: 元对象处理器
-
@Date: Created in 14:03 2020/7/29
-
@Author: ONESTAR
-
@QQ群: 530311074
-
@URL: https://onestar.newstar.net.cn/
*/
@Component //交给spring管理
public class MyMetaObjectHandler implements MetaObjectHandler {
//使用MybatisPlus实现添加操作,执行该方法
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName(“createTime”,new Date(),metaObject);
this.setFieldValByName(“updateTime”,new Date(),metaObject);
}
//使用MybatisPlus实现修改操作,执行该方法
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName(“updateTime”,new Date(),metaObject);
}
}
分析:
- @Component:将该类交给spring管理
- metaObject:元数据对象
- setFieldValByName:根据名称来设置值,这里根据创建时间来设置
配置好后可以再测试类中添加User和修改User进行测试
2.3 mybatisplus实现乐观锁
概念
乐观锁和悲观锁
-
悲观锁,顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。悲观锁适用于并发竞争很厉害,写比较多的操作。
-
乐观锁,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。乐观锁适用于读多写少的应用场景,这样可以提高吞吐量。
这里只讲乐观锁,为了解决写数据时丢失更新问题而出现的一种解决方法。当多个人同时修改同一条记录,最后提交的把之前的提交数据覆盖,这就是丢失更新,为了防止出现这种情况,就可以采用乐观锁,在提交更新的时候会判断一下在此期间别人有没有去更新这个数据,如12306抢票
MybatisPlus实现原理:通过添加version字段来判断是否对数据进行了修改,修改将version加一,比较新的version和原有的version是不是一样,一样的version才进行更新操作,更新完成后,version就会+1,这时候另外一个拿到数据想要更新的人,在比较version那里就会不同从而更新失败。
2.3.1 添加乐观锁版本号字段
- 添加字段
ALTER TABLE user
ADD COLUMN version
INT
- 实体类添加属性和注解
@Version
@TableField(fill = FieldFill.INSERT_UPDATE) //更新时修改
private Integer version;
添加操作初始化version
//使用MybatisPlus实现添加操作,执行该方法
@Override
public void insertFill(MetaObject metaObject) {
…
this.setFieldValByName(“version”, 1, metaObject);
}
注:
- 支持的数据类型只有 int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整数类型下 newVersion = oldVersion + 1
- newVersion 会回写到 entity 中
- 仅支持 updateById(id) 与 update(entity, wrapper) 方法
- 在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
2.3.2 配置乐观锁插件
在MpConfig配置文件中添加乐观锁配置插件
/**
- 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
2.3.3 测试乐观锁
//乐观锁
@Test
void optimisticLocker(){
//查询
User user = userMapper.selectById(1L);
//修改数据
user.setAge(1);
//修改失败:模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version
//user.setVersion(user.getVersion() - 1);
//执行更新
userMapper.updateById(user);
}
2.4 逻辑删除
删除可以分为两种,一种是物理删除,一种是逻辑删除
-
物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条删除数据
-
逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍能看到此数据,通过标志位字段来实现
2.4.1 添加字段
- 添加deleted标志位字段
ALTER TABLE user
ADD COLUMN deleted
boolean
最后
这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档
祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!
感谢大家的支持!!
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
2.3.3 测试乐观锁
//乐观锁
@Test
void optimisticLocker(){
//查询
User user = userMapper.selectById(1L);
//修改数据
user.setAge(1);
//修改失败:模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version
//user.setVersion(user.getVersion() - 1);
//执行更新
userMapper.updateById(user);
}
2.4 逻辑删除
删除可以分为两种,一种是物理删除,一种是逻辑删除
-
物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条删除数据
-
逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍能看到此数据,通过标志位字段来实现
2.4.1 添加字段
- 添加deleted标志位字段
ALTER TABLE user
ADD COLUMN deleted
boolean
最后
这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档
祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!
感谢大家的支持!!
[外链图片转存中…(img-WpViL701-1714419373406)]