MyBatis-Plus基本使用。

目录

一、用前准备:

二、简单体验:

 三、分页查询:

1、分页

2、条件分页与排序:

四、条件查询:

1、且条件查询: 

2、或条件查询:

3、null值查询:

4、查询投影:

1)特定对象类型的投影查询:

2)map类型的投影查询:

3、分组统计:

4、eq等于查询:

5、模糊查询like:

6、映射匹配兼容性:

7、根据数组条件查询:

五、主键生成策略:

六、删除:

一)批量删除

二)逻辑删除:

七、ServiceImpl<>类使用:


一、用前准备:

在创建SpringBoot时只需要勾选 mySQL驱动即可

1、导入依赖:以下版本基于SpringBoot 2.6.2

<!--        myBatis-plus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.0</version>
        </dependency>
<!--连接池和mySQL驱动-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

2、yml配置数据库:

spring: 
 datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3307/python?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      username: root
      password: root

二、简单体验:

1、写一个Dao接口打上mapper注解。继承BaseMapper<>类,泛型写数据表对应的实体类。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springbootstudy.db.pojo.StudentInfo;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface testDao extends BaseMapper<StudentInfo> {
}

2、直接调用就会发现testDao的对象会有很多的内置方法:

 三、分页查询:

1、分页

书写一个配置类用于myBatis的拦截器,直接复制粘贴即可

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class myBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor(){
        //1、定义mp拦截器
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //2、添加拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

由于小程序传来的数据是start=1 或start+count这种,比如每次请求五条,则第一次start = 0第二次等于5.....MybatisPlus的Ipage对象两个参数一个是起始页码,一个是请求条数,起始页码是从1卡开始的,所以必须对start进行处理将其转化为对应的页码

1、创建pageCounter对象保存page和count

/**bo用于对所需的业务对象进行封装*/
@Data
public class PageCounter {
    private Integer page;
    private Integer count;
}

 2、写一个工具类用于转化start与page页码的关系:

通过这给类的转化,得到的page是从第1页开始的,就可以直接给MyBatisPlus使用了

public class CommonUtil {
    public static PageCounter convertToPaeParameter(Integer start, Integer count){
        Integer page = start/count+1;
        PageCounter res = new PageCounter();
        res.setPage(page);
        res.setCount(count);
        return res;
    }
}

controller层:

    @GetMapping("/latest")
    public Paging<Spu> getLatestPagingSpu(@RequestParam(defaultValue = "0") Integer start,
                                          @RequestParam(defaultValue = "10") Integer count) {
        PageCounter pageCounter = CommonUtil.convertToPaeParameter(start, count);
        return spuService.getLatestPagingSpu(pageCounter.getPage(), pageCounter.getCount());
    }

service层:

    @Override
    public Paging<Spu> getLatestPagingSpu(Integer page, Integer count) {
        //1、定义page对现象
        IPage pages = new Page(page, count);
        //2、定义查询条件
        QueryWrapper<Spu> wrapper = new QueryWrapper<>();
        //condition可以进行一个bool判断,当为true时,后面的都生效,否则后面写这个条件不生效
        wrapper.orderBy(true, false, "create_time");
        //3、开始执行查询:
        IPage p =  spuDao.selectPage(pages, wrapper);

        return new Paging<Spu>(p.getTotal(), count, page, (int) p.getPages(), p.getRecords());
    }

分页查询API:

    @Test
    void testByPage(){
        IPage pages = new Page(1,2);
        IPage page = tDao.selectPage(page,null);
        System.out.println("当前页码:"+page.getCurrent());
        System.out.println("每页显示条数:"+page.getSize());
        System.out.println("页码总数:"+page.getPages());
        System.out.println("数据总数:"+page.getTotal());
        System.out.println("数据:"+page.getRecords());
    }

2、条件分页与排序:

分页查询的第二个参数上面写的是null,实际上他是进行条件查询,排序进行准备的。

    @Test
    public void test(Integer page, Integer count) {
        //1、定义page对现象
        IPage pages = new Page(page,count);

        //2、定义查询条件
        QueryWrapper<Spu> query = new QueryWrapper<>();
        query.eq("online",1); //条件1:让online属性=1才进行分页排序

        //属性二:排序
        //第一个参数condition是一个布尔判断,当为true时,后面的排序生效,否则后面写这个排序不生效
        //第二个参数,是否是正序,true正序,false倒序
        //第三个参数是排序字段,字段名与数据库的列一致而非对应的实体类。
        query.orderBy(true,false,"create_time");
        
        //3、开始执行查询:
        IPage p = spuDao.selectPage(pages, query);

    }

四、条件查询:

前置知识:

lt

less than 小于

le

less than or equalto 小于等于

eqequal to等于
nenot equal 不等于
ge

greater than or equal to 大于等于

gtgreater then 大于
between查询[a,b]的范围

1、且条件查询: 

链式调用和分开写都是 且 的条件

    @Test //且条件查询
    void queryTest(){
        //1、创建一个lambda查询器
        LambdaQueryWrapper<StudentInfo> lqw =new LambdaQueryWrapper<>();

        //2、书写条件  查询成绩大于90 且 小于100
        lqw.lt(StudentInfo::getScore,100);
        lqw.gt(StudentInfo::getScore,90);
        //也可以链式写法:
        //lqw.lt(StudentInfo::getScore,100).gt(StudentInfo::getScore,90);

        //3、查询器传递给查询方法
        List<StudentInfo> list = tDao.selectList(lqw);
        System.out.println(list);
    }

2、或条件查询:

    @Test //或条件查询
    void queryTest(){
        //1、创建一个lambda查询器
        LambdaQueryWrapper<StudentInfo> lqw =new LambdaQueryWrapper<>();

        //2、书写条件  查询成绩大大于90 或 小于30
        lqw.lt(StudentInfo::getScore,30).or().gt(StudentInfo::getScore,90);

        //3、查询器传递给查询方法
        List<StudentInfo> list = tDao.selectList(lqw);
        System.out.println(list);
    }

3、null值查询:

        StudentInfo studentInfo = new StudentInfo();
        studentInfo.setScore(30);
        //判断前面的条件,如果是true就链接后面的条件
        lqw.lt(null != studentInfo.getScore(), StudentInfo::getScore, 50);

4、查询投影:

就是显示查询出来的部分字段,不是都显示全部字段

1)特定对象类型的投影查询:

    @Test
    //特定对象类型的投影查询
    void queryTest() {
        //1、创建一个lambda查询器
        LambdaQueryWrapper<StudentInfo> lqw = new LambdaQueryWrapper<>();
        //2、书写条件  分数 和 姓名
        lqw.select(StudentInfo::getScore,StudentInfo::getStuname);
        //3、查询器传递给查询方法
        List<StudentInfo> list = tDao.selectList(lqw);
        System.out.println(list);
    }

2)map类型的投影查询:

(查询总数count(*)必须用这种方法)

    @Test
    //map类型投影查询
    void queryTest2(){
        //1、创建一个查询器
        QueryWrapper<StudentInfo> qw =new QueryWrapper<>();
//        qw.select("count(*) as count");   查询所有
        qw.select("stuName","score");
        //2、查询器传递给查询方法
        List<Map<String, Object>> maps = tDao.selectMaps(qw);
        System.out.println(maps);
    }

3、分组统计:

    @Test
    //分组统计:
    void queryTest2(){
        //1、创建一个lambda查询器
        QueryWrapper<StudentInfo> qw =new QueryWrapper<>();
        qw.select("count(*) as count","score");
        //2、分组条件
        qw.groupBy("score");
        //3、查询器传递给查询方法
        List<Map<String, Object>> maps = tDao.selectMaps(qw);
        System.out.println(maps);
    }

4、eq等于查询:

用于密码验证等场景

 @Test
    //LambdaQueryWrapper方式查询
    void queryTest() {
        //1、创建一个lambda查询器
        LambdaQueryWrapper<StudentInfo> lqw = new LambdaQueryWrapper<>();
        //2、查询分数为99且id为1的学生
        lqw.eq(StudentInfo::getScore,99).eq(StudentInfo::getId,1);
        //3、查询器传递给查询方法
        StudentInfo one = tDao.selectOne(lqw);  //selectOne专门用于查询一条数据
        //查出来返回对象,查不出来返回null
        System.out.println(one);
    }

    @Test
        //QueryWrapper方式查询
    void queryTest3(){
        //1、创建一个lambda查询器
        QueryWrapper<StudentInfo> qw =new QueryWrapper<>();
        //2、查询条件
        qw.eq("score",99);
        //3、查询字段
        qw.select("stuName","score");
        //4、查询器传递给查询方法
        List<Map<String, Object>> maps = tDao.selectMaps(qw);
        System.out.println(maps);
    }

5、模糊查询like:

对于Bottom来说like("B")表示B%,llike("B")表示%B.

    @Test
    //LambdaQueryWrapper方式模糊匹配
    void queryTest() {
        //1、创建一个lambda查询器
        LambdaQueryWrapper<StudentInfo> lqw = new LambdaQueryWrapper<>();
        //2、查询李*的学生
        lqw.like(StudentInfo::getStuname,"李");
        //3、查询器传递给查询方法
        List<StudentInfo> list = tDao.selectList(lqw);
        System.out.println(list);
    }

6、映射匹配兼容性:

查询我们会发现:

1、数据库的表名与实体类的表名不一致

2、实体类有的字段表中不存在这个字段

3、实体类属性的名称与表的名称不匹配

7、根据数组条件查询:

前端传来一个数组,现在要通过该数组的数据进行条件查询,如果传来的是id,则有默认的selectById()方法,但是如果不是id是其他属性的数据,此时如果使用sql查询就是使用in关键字,所以在MybatisPlus中也相同。

   //根据一组name来查询数据
    public List<Theme> getByNames(List<String> nameList) {
        QueryWrapper<Theme> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(Theme::getName,nameList);
        return themeDao.selectList(wrapper);
    }

五、主键生成策略:

主要策略:

lAUTO(0)使用数据库id自增策略控制id生成
lNONE(1)不设置id生成策略
lINPUT(2)用户手工输入id
lASSIGN_ID(3)雪花算法生成id(可兼容数值型与字符串型)
lASSIGN_UUID(4)UUID生成算法作为id生成策略

雪花算法:

 1、由64位二进制数组成

 2、首位是0保证生成的数是正数

 3、41位由当前时间戳生成

 4、当同一时间戳收到了多条请求后面再加一段机器号防止重复

 5、防止同一计器在同一时间收到多条请求出现了序列号,表示当前设备的第几个请求。


使用时候只需要在id上打上注解即可:

 上述的表前缀和主键策略可以全局配置:

六、删除:

一)批量删除

之前在使用MyBatis的时候想要实现动态的批量删除需要使用forEach标签,操作十分复杂,有了MyBatis-Plus之后,我们只需要调用相应的API然后传入一个List即可实现批量删除。

二)逻辑删除:

逻辑删除:表面上好像是删除了,但是实际上执行的是update语句,是用一个字段作为标志,来表示这个数据是否被删除。

当执行查询语句时将不会再查询出来被逻辑删除的数据,因为Mybatis-Plus会自动加上一句 where deleted=0

下面的deleted字段就表示逻辑删除字段,1表示数据被删除,0表示数据没有被删除。

1、直接在实体类的属性上加注解:(不常用)

 2、通用配置形式:

我们只需要在yml中进行配置即可:

 1、在数据库中要有对应的deleted字段

2、一定要给deleted字段选上默认值选项

对于时间类型的逻辑删除:

如果数据库中的逻辑删除字段是一个时间,不仅仅有两种可能是由多种可能的,所以需要用到下面的方式:

当数据被删除后,该部分显示的是删除的时间。

1、配置Mybatis-Plus:

mybatis-plus:
  global-config:
    db-config:
      # 逻辑删除(软删除),删除时添加当前时间,未删除是NULL
      logic-delete-value: NOW()
      logic-not-delete-value: 'NULL'

2、为对应字段添加注解:

@Data
public class BasePojo {
    @TableLogic
    private Date deleteTime;

    private Date createTime;

    private Date updateTime;

}

七、ServiceImpl<>类使用:

通过前面的学习我们知道MyBatis-Plus已经为我们提供了很多方便的方法供我们使用,但是我们发现对于简单的selectById()方法,我们需要controller层调用serviceImpl层,然后serviceImpl再调用对应的Mapper层,我们试想能不能直接在Controller调用这种简单的方法,此时需要用到ServiceImpl类。

1、将Mapper层打上@Mapper注解,同时继承BaseMapper类。

@Mapper
public interface BannerMapper extends BaseMapper<BannerDO> {

}

 2、来到Service接口,继承IService类,泛型是对应的DO模型类(数据库映射出来的那个类)

此步是针对具有接口的风格,没有可以直接省略。

public interface BannerService extends IService<BannerDO> {

}

3、ServiceImpl真正业务类,继承ServiceImpl<>,第一个泛型是对应的Mapper接口,第二个是对应的DO类:

@Service
public class BannerServiceImpl extends ServiceImpl<BannerMapper,BannerDO> implements BannerService {
}

4、Controller类,直接将Service注入即可使用:

当我们  .  时会发现多了很多方法:

2、同时可以通过getBaseMapper来获取更多方法:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值