springboot整合Mybatis-plus使用(乐观锁,逻辑删除,分页查询,自动填充和Wrapper相关的操作)

Mybatis-plus介绍

mybatis-puls是对mybatis的增强,没有很大的改变,使用时感觉不到太大的变化,可以和springboot很好的整合使用,详情参考mybatis-plus官网,使用springboot整合mybatis-plus必须得导入以下依赖

<dependency>
   <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>

首先的创建出实体类,mybatis-plus注解使用可以参考mybatis-plus注解描述

@Data
@TableName("user")
public class User {
    @TableId
    private Long id;
    @TableField("name")
    private String name;
    @TableField("age")
    private Integer age;
    @TableField("email")
    private String email;
    @TableField(fill = FieldFill.INSERT)// 配合mybatis-plus的自动填充功能,在插入时更新
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)// 配合mybatis-plus的自动填充功能,在插入时和修改时更新
    private Date updateTime;
    @Version // 配合mybatis-plus乐观锁使用
    @TableField(fill = FieldFill.INSERT)
    private Integer version;
    @TableLogic // 配合mybatis的逻辑删除使用
    private Boolean deleted;
}

mybatis-plus与springboot整合简单CRUD使用

创建一个简单的UserMapper类继承Mybatis-plus所封装的一个基础类BaseMaper<T>,泛型写当前所需要操作的实体类,BaseMapper封装了很多基础的CRUD方法基本能满足我们的的使用

public interface UserMapper extends BaseMapper<User> {

}

mybatis对相关的Service也进行了封装,Service接口继承IService<T>接口泛型写需要操作的相关实体,Service实现类继承ServiceImpl<M,T>泛型写相关的Mapper接口和需要操作的实体,且实现本应该实现的Service接口进行操作,当前Service就可以使用简单的CRUD操作

/**
* UserService接口
*/
public interface UserService extends IService<User> {
}
/**
* UserServiceImpl实现类
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

还需要创建一个mybatis-plus的配置类在其中,使用@MapperScan注解扫描到mapper所在的地方,在其中可以注入相关的插件的bean供后续使用

@Configuration
@MapperScan("com.percent.bootmybatispuls.mapper")
public class MpConfig {
    /**
     * 乐观锁插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

}

使用简单的CRUD查询

@Autowired
private UserService userService;

/**
* 查询出所有的数据
*/
@Test
void list() {
    List<User> users = userService.list();
    logger.info("users : {}",users);
}
/**
* 添加相关的数据
*/
@Test
void addUser() {
    User user = new User();
    user.setAge(10);
    user.setEmail("1111111111@qq.com");
    user.setName("zhangsan");
    userService.save(user);
}

/**
* 多个id批量查询
*/
@Test
void selectBatchIds() {
     List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
     logger.info("users : {}",users);
 }

/**
* 简单条件查询
*/
@Test
void selectByMap() {
   Map<String, Object> columnMap = new HashMap<>();
   columnMap.put("name", "Jack");
   columnMap.put("age", 20);
   List<User> users = userMapper.selectByMap(columnMap);
   logger.info("users : {}",users);
}

/**
 * 通过ID删除
 */
@Test
void deleteById(){
    userService.removeById(1L);
}

/**
* 修改
*/
@Test
void update(){
    User user = new User();
    user.setId(1l);
    user.setAge(10);
    user.setEmail("1111111111@qq.com");
    user.setName("zhangsan");
    userService.updateById(user);
}

更多的简单操作可以看mybatis-plus IService封装相关方法或者是mybatis-plus BaseMapper封装相关方法

Mybatis-plus使用分页查询

必须得定义一个mybatis配置类在其中注入PaginationInterceptor分页插件

/**
 * 分页查询
 */
@Test
public void testSelectPage() {
    Page<User> page = new Page(1, 3); // 构建一个page类这个Page类是Myatis-plus包下的第一个参数代表当前页码,第二个参数表示当前页显示多少条数据
    Page<User> userPage = userService.page(page,null); // 调用分页查询方法进行分页查询,第一个参数代表page对象,第二个参数代表查询条件
    //返回对象得到分页所有数据
    long pages = userPage.getPages(); //总页数
    long current = userPage.getCurrent(); //当前页
    List<User> records = userPage.getRecords(); //查询数据集合
    long total = userPage.getTotal(); //总记录数
    boolean hasNext = userPage.hasNext();  //是否有下一页
    boolean hasPrevious = userPage.hasPrevious(); //是否有上一页

    System.out.println(pages);
    System.out.println(current);
    System.out.println(records);
    System.out.println(total);
    System.out.println(hasNext);
    System.out.println(hasPrevious);
}

mybatis-plus逻辑删除

在平常的删除数据业务逻辑中一般不会吧数据真正的删除掉一般都是使用逻辑删除,通过一个字段定义当前数据是无效的,mybatis-plus通过在其字段上标明@TableLogic注解来使用逻辑删除

#在yml文件中写入当前的配置
mybatis-plus:
  config-location:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 可以打印出其中sql语句的日志
  global-config:
    db-config:
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

在现在这种情况下使用删除语句不会把数据库中的数据直接删除掉,并且可以在控制台发现不是执行的delete语句而是执行的update语句将当前所需要删除的数据的逻辑删除字段的值改为了1

/**
  * 通过ID删除
  */
 @Test
 void deleteById(){
     userService.removeById(1L);
 }

控制台输出

在这里插入图片描述

mybatis-plus 乐观锁

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。在mybatis-plus中使用乐观锁必须在乐观锁字段上添加@Version注解并且在配置类中注入OptimisticLockerInterceptor

/**
 * 带乐观锁修改
 */
@Test
void update(){
    User user = new User();
    user.setId(00000000000000000001l);
    user.setAge(10);
    user.setEmail("1112211111@qq.com");
    user.setName("zhangsan");
    user.setVersion(2); // 带上当前要修改的数据的版本号
    userService.updateById(user);
}

控制台打印,version会带入到条件中

在这里插入图片描述

更新完成后数据库中version字段会自动加一

在这里插入图片描述

mybatis-plus自动填充功能

mybatis-plus的自动填充功能,通过注解@TableField(fill = FieldFill.INSERT)其中的fill属性设置值表示该字段在什么过程中进行自增,实现MetaObjectHandler 接口来定义自动填充的值

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
	/**
	* 在数据新增时进行操作
	*/
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
        this.setFieldValByName("version",1,metaObject);
    }
	/**
	* 在数据修改时进行操作
	*/	
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

mybatis-plus使用 Wrapper进行复杂的操作

Wrapper是mybatis-plus提供出来使用的条件构造器

在这里插入图片描述

Wrapper : 条件构造抽象类,最顶端父类
AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
QueryWrapper : 查询条件封装
UpdateWrapper : Update 条件封装
AbstractLambdaWrapper : 使用Lambda 语法
LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
LambdaUpdateWrapper : Lambda 更新封装Wrapper

测试使用

ge、gt、le、lt、isNull、isNotNull
@Test
public void testQuery() {
QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper
        .isNull("name")
        .ge("age", 12)
        .isNotNull("email");
    int result = userMapper.delete(queryWrapper);
System.out.println("delete return count = " + result);
}
eq、ne

注意:seletOne()返回的是一条实体记录,当出现多条时会报错 @Test

public void testSelectOne() {
	QueryWrapper<User>queryWrapper = newQueryWrapper<>();
	queryWrapper.eq("name", "Tom");
	Useruser = userMapper.selectOne(queryWrapper);//只能返回一条记录,多余一条则抛出异常
	System.out.println(user);
}
between、notBetween

包含大小边界

@Test
public void testSelectCount() {
	QueryWrapper<User>queryWrapper = newQueryWrapper<>();
	queryWrapper.between("age", 20, 30);
    Integer count = userMapper.selectCount(queryWrapper); //返回数据数量
	System.out.println(count);
}
like、notLike、likeLeft、likeRight

selectMaps()返回Map集合列表,通常配合select()使用

@Test
public void testSelectMaps() {
	QueryWrapper<User>queryWrapper = newQueryWrapper<>();
	queryWrapper
	        .select("name", "age")
	        .like("name", "e")
	        .likeRight("email", "5");
	List<Map<String, Object>>maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表
	maps.forEach(System.out::println);
}
orderBy、orderByDesc、orderByAsc
@Test
public void testSelectListOrderBy() {
	QueryWrapper<User>queryWrapper = newQueryWrapper<>();
	queryWrapper.orderByDesc("age", "id");
	List<User>users = userMapper.selectList(queryWrapper);
	users.forEach(System.out::println);
}

Wrapper对应的查询方式

更多详情可参考官方 条件构造器

查询方式说明
setSqlSelect设置 SELECT 查询字段
whereWHERE 语句,拼接 + WHERE 条件
andAND 语句,拼接 + AND 字段=值
andNewAND 语句,拼接 + AND (字段=值)
orOR 语句,拼接 + OR 字段=值
orNewOR 语句,拼接 + OR (字段=值)
eq等于=
allEq基于 map 内容等于=
ne不等于<>
gt大于>
ge大于等于>=
lt小于<
le小于等于<=
like模糊查询 LIKE
notLike模糊查询 NOT LIKE
inIN 查询
notInNOT IN 查询
isNullNULL 值查询
isNotNullIS NOT NULL
groupBy分组 GROUP BY
havingHAVING 关键词
orderBy排序 ORDER BY
orderAscASC 排序 ORDER BY
orderDescDESC 排序 ORDER BY
existsEXISTS 条件语句
notExistsNOT EXISTS 条件语句
betweenBETWEEN 条件语句
notBetweenNOT BETWEEN 条件语句
addFilter自由拼接 SQL
last拼接在最后,例如:last(“LIMIT 1”)
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦片王子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值