mybatis-plus 介绍

springboot具体集成mybatis-plus可以查看:

    springBoot 使用 mybatis-plus 插件 实现分页

mybatis-plus

1、官方文档

https://baomidou.com/guide/sequence.html#spring-boot

2、MyBatis Plus 介绍

MyBatis-plus 是国内人员开发的 MyBatis 增强工具,在 MyBatis 的基础上只做增强不做改变,引入 Mybatis-Plus 不会对现有的 Mybatis 构架产生任何影响,而且 MyBatis-plus 支持所有 Mybatis 原生的特性,为简化开发、提高效率而生。

3、MyBatis Plus 优点

3.1、依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring 。

3.2、损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 。

3.3、预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击 。

3.4、通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作。

3.5、内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。

4、主要功能

MyBatis Plus 的核心功能有:

4.1、条件构造器

4.2、通用的 CRUD接口

4.3、分页插件

4.4、代码生成器

4.5、自定义ID生成器

4.6、Sequence主键

5、条件构造器

5.1、三个绿色父类就不讲了,主要介绍以下四个:

  • LambdaQueryWrapper :Lambda形式的查询Wrapper。

    LambdaQueryWrapper<PressInfoEntity> lambdaQueryWrapper = new QueryWrapper<>().lambda();
    LambdaQueryWrapper<PressInfoEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  • LambdaUpdateWrapper :Lambda 形式的更新Wrapper。

    LambdaUpdateWrapper<PressInfoEntity> updateWrapper = new UpdateWrapper<>().lambda()            
    LambdaUpdateWrapper<PressInfoEntity> updateWrapper = new LambdaUpdateWrapper();
  • QueryWrapper :继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件及 LambdaQueryWrapper, 可以通过 new QueryWrapper().lambda() 方法获取。

  • UpdateWrapper : 继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件及 LambdaUpdateWrapper, 可以通过 new UpdateWrapper().lambda() 方法获取。

5.2、使用方法

5.3、注意点

1、对于上述存在sql注入风险的方法,建议能不用就不用。如果要用的话,必须确保里面的参数不存在sql注入问题。

2、单表操作的时候优先使用LambdaQueryWrapper ,因为QueryWrapper与表字段名强绑,如果修改表字段,n个方法使用这个条件,改动的地方会很多

QueryWrapper<PressInfoEntity> queryWrapper = new QueryWrapper<>()
                 .like("short_press","版");
​
LambdaQueryWrapper<PressInfoEntity> lambdaQueryWrapper = new QueryWrapper<>()
                 .lambda()
                 .like(PressInfoEntity::getShortPress,"版");

6、通用CRUD(版本不同,通用方法会有差异,这里以3.3.2为例)

PressInfoEntity.java实体类

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value="t_press_info")
public class PressInfoEntity {
        @TableId
        private int id;
        @TableField(value = "short_press")
        private String shortPress;
        @TableField(value = "press")
        private String press;
        @TableField(value = "create_time")
        private Date createTime;
        @TableField(value = "update_time")
        private Date updateTime;           
        // 表示当前字段不存在t_press_info表中
        @TableField(value = "name" ,exist = false)
        private String name;
}

6.1、新增 int insert(T entity);

 int insert(T entity);

例子:

PressInfoEntity pressInfoEntity = PressInfoEntity.builder()
        .shortPress("ces")
        .press("c")
        .createTime(new Date())
        .build();
int flag= pressInfoMapper.insert(pressInfoEntity);

6.2、删除

int deleteById(Serializable id);
​
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
​
int delete(@Param("ew") Wrapper<T> wrapper);
​
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

例子:以下方法按查询删除

LambdaQueryWrapper<PressInfoEntity> wrapper=new LambdaQueryWrapper().eq(PressInfoEntity::getId,id);
pressInfoMapper.delete(wrapper);

6.3、修改

int updateById(@Param("et") T entity);
​
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

例子:

  PressInfoEntity pressInfoEntity = PressInfoEntity.builder().id(id).press("我也被修改了!").build();
  pressInfoMapper.updateById(pressInfoEntity);
 
 #LambdaUpdateWrapper  用于生成where条件,定位哪些数据需要修改,PressInfoEntity才是具体修改的内容
  LambdaUpdateWrapper<PressInfoEntity> updateWrapper = new LambdaUpdateWrapper<>().eq(PressInfoEntity::getId,id);
  PressInfoEntity pressInfoEntity = PressInfoEntity.builder().press("我被修改了!").build();
  pressInfoMapper.update(pressInfoEntity,updateWrapper);
 #sql: UPDATE t_press_info SET press=? WHERE (id = ?)      
 
 #如果只是修改单独个一两个值可以直接将第一个条件传null
 LambdaUpdateWrapper<PressInfoEntity> updateWrapper = new LambdaUpdateWrapper<>()
                .set(PressInfoEntity::getShortPress,"我被修改了")
                .eq(PressInfoEntity::getId,id);
 pressInfoMapper.update(null,updateWrapper);
 

6.4、查询

T selectById(Serializable id);
​
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
​
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
​
T selectOne(@Param("ew") Wrapper<T> queryWrapper);
​
Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);
​
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
​
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
​
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

例子:

List<Integer> idList= Arrays.asList(2,3);
List<PressInfoEntity> list=pressInfoMapper.selectBatchIds(idList);
​
LambdaQueryWrapper<PressInfoEntity> queryWrapper = new LambdaQueryWrapper<()
                .like(PressInfoEntity::getShortPress,shortPress);
List<PressInfoEntity> list=   pressInfoMapper.selectList(queryWrapper);
​

6.5、分页查询(放到分页插件内细说)

<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);
​
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param("ew") Wrapper<T> queryWrapper);

6.6、QuerWapper使用 FIND_IN_SET

SELECT
	id,
	
FROM
	xxxxx
WHERE
	(
	grade_id = ? 
	AND semester_id = ? 
	AND subject_id = ? 
	AND staged_type = ? 
	AND province_id = ? 
	AND FIND_IN_SET ( '340800', city_id ) 
	AND source_type IN ( ?,? ) 
	AND test_online = ? 
	)
wrapper.apply(examinationPaperQueryVO.getCityId() != null, "FIND_IN_SET ('" + examinationPaperQueryVO.getCityId() + "',city_id)");

6.7、MybatisPlus结合groupby实现分组和Count

wrapper.groupBy(ExaminationPaperRelevancePO::getSchoolId);

实体类添加字段

 

注意:添加count(1) 之后,所有默认方法执行的sql都会加上它,统计数量,慎用

          如果非得用,尽可能所有查询接口都根据某个唯一值groupBy一下

7、分页插件

7.1、新建MybatisPluConfig.java

@Configuration
@MapperScan("xxxx")
public class MybatisPluConfig {
    /**
     * mybatis-plus分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return paginationInterceptor;
    }
}

7.2、只需配置好分页拦截就可以直接使用

LambdaQueryWrapper<PressInfoEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>()
              .like(PressInfoEntity::getShortPress,shortPress);
Page<PressInfoEntity> page=new Page<>(pageNo,pageSize);
IPage<PressInfoEntity> iPage=  pressInfoMapper.selectPage(page,lambdaQueryWrapper);
#执行两条sql
#统计总数
SELECT COUNT(1) FROM t_press_info WHERE (short_press LIKE ?)
#分页查询
SELECT id,short_press,press,create_time,update_time FROM t_press_info WHERE (short_press LIKE ?) LIMIT ?,?

7.3、执行结果

{
  "records": [
    {
      "id": 1,
      "shortPress": "北京版",
      "name": null,
      "press": "北京出版社",
      "createTime": null,
      "updateTime": null
    },
    ......
  ],
  "total": 78,
  "size": 3,
  "current": 1,
  "orders": [],
  "optimizeCountSql": true,
  "hitCount": false,
  "searchCount": true,
  "pages": 26
}

7.4、自定义多表关联分页查询

使用LambdaQueryWrapper

 LambdaQueryWrapper<PressInfoEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>()
                .like(PressInfoEntity::getShortPress,"版")
                .like(PressInfoEntity::getName,"测试");            
 IPage<PressInfoEntity> iPage=   pressInfoService.selectPageByPressLambda(page,lambdaQueryWrapper);
 抛出异常,9.1会说明原因。
 如果去掉 .like(PressInfoEntity::getName,"测试");可以正常执行。       

使用QueryWrapper

 QueryWrapper<PressInfoEntity> queryWrapper = new QueryWrapper<PressInfoEntity>();
 queryWrapper.like("t.short_press","版");
 queryWrapper.like("t1.name","测试");
 IPage<PressInfoEntity> iPage=   pressInfoService.selectPageByPressWrapper(page,queryWrapper);

推荐常规写法

 PressInfoEntity pressInfoEntity = PressInfoEntity.builder().press(press).build();       
 Page<PressInfoEntity> page=new Page<>(1,5);
 IPage<PressInfoEntity> iPage=   pressInfoService.selectPageByEntity(page,pressInfoEntity); 

 #sql和mybatis一样就好
  select t.*,t1.name from t_press_info t
        left join t_press t1 on t.id=t1.press_info_id
        <where> t.short_press like CONCAT('%',#{et.shortPress},'%')  </where>
xml中要有相应的方法
 <select id="selectPageByEntity"  parameterType="com.test.mybatisplus.entity.PressInfoEntity" resultType="com.test.mybatisplus.entity.PressInfoEntity">
        select t.*,t1.name from t_press_info t
        left join t_press t1 on t.id=t1.press_info_id
        <where> t.short_press like CONCAT('%',#{et.shortPress},'%')  </where>
    </select>

9、注意点

9.1、优先使用LambdaQueryWrapper ,QueryWrapper与表字段名强绑,如果修改表字段,改动的地方会很多

QueryWrapper<PressInfoEntity> queryWrapper = new QueryWrapper<PressInfoEntity>();
queryWrapper.like("short_press","版");
​
LambdaQueryWrapper<PressInfoEntity> lambdaQueryWrapper = new QueryWrapper<PressInfoEntity>()
                .lambda()
                .like(PressInfoEntity::getShortPress,"版")

缺点:如果自定义sql多表关联查询无法使用LambdaQueryWrapper,这种时候只能用其他方式

​
 LambdaQueryWrapper<PressInfoEntity> queryWrapper = new QueryWrapper<>().lambda();
        queryWrapper.like(PressInfoEntity::getShortPress,"版");
        //使用非当前表内字段做查询
        queryWrapper.like(PressInfoEntity::getName,"测试");
  异常:can not find lambda cache for this property [name] of entity[com.test.mybatisplus.entity.PressInfoEntity]
  原因:lambda cache 在初始化缓存数据的时候跟t_press_info强相关,name不在当前表中,所以获取的时候导致异常。   

9.2、分页插件也执行了两条sql,源码里可以看到,如果isSearchCount=true则执行 queryTotal

SELECT COUNT(1) FROM t_press_info WHERE (short_press LIKE ?)
​
select * from t_press_info WHERE (short_press LIKE ?) ORDER BY id DESC LIMIT ?,?
​

本文github地址:https://github.com/nlxs0511/springmybatisplus.git

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值