MyBatisPlus配置与实现 您所在的位置:网站首页 idea自动补全new的类 MyBatisPlus配置与实现

MyBatisPlus配置与实现

2023-06-09 17:54| 来源: 网络整理| 查看: 265

目录

基于SpringBoot使用MyBatisPlus

标准数据层开发

Lombok

分页功能

DQL编程控制

构建条件查询

null判定

查询投影

聚合查询

分组查询

查询条件

模糊查询

排序查询

映射匹配兼容性

DML编程控制

id生成策略控制

雪花算法:

简化配置

多记录操作

逻辑删除​编辑

乐观锁

快速开发

 

        MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提供效率

MyBatisPlus的官网为:https://mp.baomidou.com/

基于SpringBoot使用MyBatisPlus

        由于MP并未被收录到idea的系统内置配置,无法直接选择加入,需要手动在pom.xml中配置添加pom.xml补全依赖

 

com.baomidou mybatis-plus-boot-starter 3.4.1 com.alibaba druid 1.1.16

        从MP的依赖关系可以看出,通过依赖传递已经将MyBatis与MyBatis整合Spring的jar包导入,我们不需要额外在添加MyBatis的相关jar包

 添加MP的相关配置信息

根据数据库表创建实体类

创建Dao接口

@Mapper public interface UserDao extends BaseMapper { }

Dao接口要想被容器扫描到,有两种解决方案:

方案一:在Dao接口上添加@Mapper注解,并且确保Dao处在引导类所在包或其子包中该方案的缺点是需要在每一Dao接口中添加注解方案二:在引导类上添加@MapperScan注解,其属性为所要扫描的Dao所在包该方案的好处是只需要写一次,则指定包下的所有Dao接口都能被扫描到,@Mapper就可以不写 标准数据层开发

        数据层标准的CRUD(增删改查)的实现与分页功能

Lombok

Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发

org.projectlombok lombok

 安装Lombok的插件

新版本IDEA已经内置了该插件,如果删除setter和getter方法程序有报红,则需要安装插件

 可以访问如下网站 https://plugins.jetbrains.com/plugin/6317-lombok/versions

 Lombok常见的注解有:

@Setter:为模型类的属性提供setter方法@Getter:为模型类的属性提供getter方法@ToString:为模型类的属性提供toString方法@EqualsAndHashCode:为模型类的属性提供equals和hashcode方法@Data:是个组合注解,包含上面的注解的功能@NoArgsConstructor:提供一个无参构造函数@AllArgsConstructor:提供一个包含所有参数的构造函数 @Data public class User { private Long id; private String name; private String password; private Integer age; private String tel; } 分页功能 IPage selectPage(IPage page, Wrapper queryWrapper) IPage:用来构建分页查询条件Wrapper:用来构建条件查询的条件,目前我们没有可直接传为NullIPage:返回值,你会发现构建分页条件和方法的返回值都是IPage

        IPage是一个接口,我们需要找到它的实现类来构建它,具体的实现类,可以进入到IPage类中按ctrl+h,会找到其有一个实现类为Page

调用方法传入参数获取返回值

@SpringBootTest class Mybatisplus01QuickstartApplicationTests { @Autowired private UserDao userDao; @Test void testGetByPage(){ //IPage对象封装了分页操作相关的数据 IPage page = new Page(2,3); userDao.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()); } }

 设置分页拦截器

@Configuration public class MpConfig { @Bean public MybatisPlusInterceptor mpInterceptor(){ //1.定义Mp拦截器 MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor(); //2.添加具体的拦截器 mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return mpInterceptor; } }

这些内容在MP的官方文档中有详细的说明,我们可以查看官方文档类配置

 

 

 修改application.yml配置文件,查询日志

# 开启mp的日志(输出到控制台) mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

DQL编程控制

        MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合。

 Wrapper类是用来构建查询条件的

构建条件查询

因为它是一个接口,所以我们需要去找它对应的实现类

@Test void testGetAll() { //方式一:按条件查询 QueryWrapper qw = new QueryWrapper(); qw.lt("age",18); List userList = userDao.selectList(qw); System.out.println(userList); //方式二:lambda格式按条件查询 QueryWrapper qw = new QueryWrapper(); qw.lambda().lt(User::getAge, 10); List userList = userDao.selectList(qw); System.out.println(userList); //方式三:lambda格式按条件查询 LambdaQueryWrapper lqw = new LambdaQueryWrapper(); lqw.lt(User::getAge, 10); List userList = userDao.selectList(lqw); System.out.println(userList); //并且与或者关系 LambdaQueryWrapper lqw = new LambdaQueryWrapper(); //并且关系:10到30岁之间 lqw.lt(User::getAge, 30).gt(User::getAge, 10); //或者关系:小于10岁或者大于30岁 lqw.lt(User::getAge, 10).or().gt(User::getAge, 30); List userList = userDao.selectList(lqw); System.out.println(userList); } null判定

        因为前端没有输入值2,所以如果不处理的话,就会出现 price>8000 and price < null问题

使用一个age属性,如何去接收页面上的两个值

方案一:添加属性age2,这种做法可以但是会影响到原模型类的属性内容

@Data public class User { private Long id; private String name; private String password; private Integer age; private String tel; }

方案二:新建一个模型类,让其继承User类,并在其中添加age2属性,UserQuery在拥有User属性后同时添加了age2属性。

@Data public class UserQuery extends User { private Integer age2; } @SpringBootTest class Mybatisplus02DqlApplicationTests { LambdaQueryWrapper lqw = new LambdaQueryWrapper(); //先判定第一个参数是否为true,如果为true连接当前条件 lqw.lt(null != uq.getAge2(),User::getAge, uq.getAge2()); lqw.gt(null != uq.getAge(),User::getAge, uq.getAge()); lqw.lt(null != uq.getAge2(),User::getAge, uq.getAge2()) .gt(null != uq.getAge(),User::getAge, uq.getAge()); List userList = userDao.selectList(lqw); System.out.println(userList); }

查询投影

select(...)方法用来设置查询的字段列,可以设置多个,最终的sql语句为:

// 查询投影 LambdaQueryWrapper lqw = new LambdaQueryWrapper(); lqw.select(User::getId,User::getName,User::getAge); QueryWrapper lqw = new QueryWrapper(); lqw.select("id","name","age","tel"); List userList = userDao.selectList(lqw); System.out.println(userList);

最终的sql语句为:SELECT id,name,age,tel FROM user 

聚合查询 count:总记录数max:最大值min:最小值avg:平均值sum:求和 QueryWrapper lqw = new QueryWrapper(); lqw.select("count(*) as count, tel"); //SELECT count(*) as count FROM user lqw.select("max(age) as maxAge"); //SELECT max(age) as maxAge FROM user lqw.select("min(age) as minAge"); //SELECT min(age) as minAge FROM user lqw.select("sum(age) as sumAge"); //SELECT sum(age) as sumAge FROM user lqw.select("avg(age) as avgAge"); //SELECT avg(age) as avgAge FROM user lqw.groupBy("tel"); List userList = userDao.selectMaps(lqw); System.out.println(userList); 分组查询 QueryWrapper lqw = new QueryWrapper(); lqw.select("count(*) as count, tel"); lqw.groupBy("tel"); List userList = userDao.selectMaps(lqw); System.out.println(userList);

SELECT count(*) as count,tel FROM user GROUP BY tel

聚合与分组查询,无法使用lambda表达式来完成

查询条件 范围匹配(> 、 = 、between)模糊匹配(like)空判定(null)包含性匹配(in)分组(group)排序(order) //条件查询 LambdaQueryWrapper lqw = new LambdaQueryWrapper(); //等同于= lqw.eq(User::getName,"Jerry").eq(User::getPassword,"jerry"); User loginUser = userDao.selectOne(lqw); System.out.println(loginUser); LambdaQueryWrapper lqw = new LambdaQueryWrapper(); //范围查询 lt le gt ge eq between lqw.between(User::getAge,10,30); SELECT id,name,password,age,tel FROM user WHERE (age BETWEEN ? AND?) List userList = userDao.selectList(lqw); System.out.println(userList);

SELECT id,name,password,age,tel FROM user WHERE (name = ? AND password = ?)

模糊查询 like():前后加百分号,如 %J%likeLeft():前面加百分号,如 %JlikeRight():后面加百分号,如 J% //模糊匹配 like lqw.likeLeft(User::getName,"J"); List userList = userDao.selectList(lqw); System.out.println(userList); 排序查询 @Test void testGetAll(){ LambdaQueryWrapper lwq = new LambdaQueryWrapper(); /** * condition :条件,返回boolean, 当condition为true,进行排序,如果为false,则不排序 * isAsc:是否为升序,true为升序,false为降序 * columns:需要操作的列 */ lwq.orderBy(true,false, User::getId); userDao.selectList(lw }

 

orderBy排序

        condition:条件,true则添加排序,false则不添加排序         isAsc:是否为升序,true升序,false降序         columns:排序字段,可以有多个

orderByAsc/Desc(单个column):按照指定字段进行升序/降序orderByAsc/Desc(多个column):按照多个字段进行升序/降序orderByAsc/Desc

        condition:条件,true添加排序,false不添加排序         多个columns:按照多个字段进行排序  

具体参考官方文档的条件构造器来学习使用,具体的网址为: https://mp.baomidou.com/guide/wrapper.html#abstractwrapper

映射匹配兼容性 @Data @TableName("tbl_user") public class User { private Long id; private String name; @TableField(value = "pwd",select = false) private String password; private Integer age; private String tel; @TableField(exist = false) private Integer online; } 名称@TableField类型属性注解位置模型类属性定义上方作用设置当前属性对应的数据库表中的字段关系相关属 性value(默认):设置数据库表字段名称 exist:设置属性在数据库表字段中是否存在,默认为true,此属性不能与value合并 使用 select:设置属性是否参与查询,此属性与select()映射配置不冲突 名称@TableName类型类注解位置模型类定义上方作用设置当前类对应于数据库表关系相关属性value(默认):设置数据库表名称 DML编程控制 id生成策略控制 名称@TableId类型属性注解位置模型类中用于表示主键的属性定义上方作用设置当前类中主键属性的生成策略相关属性value(默认):设置数据库表主键名称 type:设置主键属性的生成策略,值查照IdType的枚举值 @Data @TableName("tbl_user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; @TableField(value = "pwd",select = false) private String password; private Integer age; private String tel; @TableField(exist = false) private Integer online; }

NONE: 不设置id生成策略INPUT:用户手工输入idASSIGN_ID:雪花算法生成id(可兼容数值型与字符串型)ASSIGN_UUID:以UUID生成算法作为id生成策略其他的几个策略均已过时,都将被ASSIGN_ID和ASSIGN_UUID代替掉。 雪花算法:

(SnowFlake),是Twitter官方给出的算法实现 是用Scala写的。其生成的结果是一个64bit大小整数

        1. 1bit,不用,因为二进制中最高位是符号位,1表示负数,0表示正数。生成的id一般都是用整数,所以最高位固定为0。         2. 41bit-时间戳,用来记录时间戳,毫秒级         3. 10bit-工作机器id,用来记录工作机器id,其中高位5bit是数据中心ID其取值范围0-31,低位5bit是工作节点ID其取值范围0-31,两个组合起来最多可以容纳1024个节点         4. 序列号占用12bit,每个节点每毫秒0开始不断累加,最多可以累加到4095,一共可以生产4096个ID

简化配置

 

# mp日志 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: banner: false db-config: id-type: assign_id table-prefix: tbl_ 多记录操作 void testDelete(){ //删除指定多条数据 // List list = new ArrayList(); // list.add(1402551342481838081L); // list.add(1402553134049501186L); // list.add(1402553619611430913L); userDao.deleteBatchIds(list); //查询指定多条数据 // List list = new ArrayList(); // list.add(1L); // list.add(3L); // list.add(4L); userDao.selectBatchIds(list); } 逻辑删除

 

 

        为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中,执行的是update操作

 

@Data public class User { private Long id; private String name; @TableField(value = "pwd",select = false) private String password; private Integer age; private String tel; @TableField(exist = false) private Integer online; //逻辑删除字段,标记当前记录是否被删除 @TableLogic(value = "0" ,delval = "1") private Integer deleted; } void testDelete(){ userDao.deleteById(2L); }

 

# mp日志 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: banner: false db-config: id-type: assign_id table-prefix: tbl_ # 逻辑删除字段名 logic-delete-field: deleted # 逻辑删除字面值:未删除为0 logic-not-delete-value: 0 # 逻辑删除字面值:删除为1 logic-delete-value: 1

逻辑删除的本质其实是修改操作。如果加了逻辑删除字段,查询数据时也会自动带上逻辑删除字段

UPDATE tbl_user SET deleted=1 where id = ? AND deleted=0

 

名称@TableLogic类型属性注解位置模型类中用于表示删除字段的属性定义上方作用标识该字段为进行逻辑删除的字段相关属性value:逻辑未删除值 delval:逻辑删除值 乐观锁

乐观锁主要解决的问题是当要更新一条记录的时候,希望这条记录没有被别人更新。

2000个请求以下解决方案,小型网站

@Data //设置表名映射关系 //@TableName("tbl_user") public class User { //设置主键生成策略 // @TableId(type = IdType.ASSIGN_ID) private Long id; private String name; @TableField(value = "pwd",select = false) private String password; private Integer age; private String tel; @TableField(exist = false) private Integer online; //逻辑删除字段,标记当前记录是否被删除 // @TableLogic(value = "0" ,delval = "1") private Integer deleted; @Version private Integer version; }

添加乐观锁的拦截器  

@Configuration public class MpConfig { @Bean public MybatisPlusInterceptor mpInterceptor() { //1.定义Mp拦截器 MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor(); //2.添加具体的拦截器 mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); //3.添加乐观锁拦截器 mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return mpInterceptor; } }

修改需要携带version数据 

 MP会将1进行加1,然后,更新回到数据库表中。

多个人修改同一个数据

 参考官方文档来实现:

乐观锁插件 | MyBatis-Plus

快速开发 package com.itheima; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.baomidou.mybatisplus.generator.config.PackageConfig; import com.baomidou.mybatisplus.generator.config.StrategyConfig; public class CodeGenerator { public static void main(String[] args) { //1.获取代码生成器的对象 AutoGenerator autoGenerator = new AutoGenerator(); //设置数据库相关配置 DataSourceConfig dataSource = new DataSourceConfig(); dataSource.setDriverName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC"); dataSource.setUsername("root"); dataSource.setPassword("root"); autoGenerator.setDataSource(dataSource); //设置全局配置 GlobalConfig globalConfig = new GlobalConfig(); globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatisplus_04_generator/src/main/java"); //设置代码生成位置 globalConfig.setOpen(false); //设置生成完毕后是否打开生成代码所在的目录 globalConfig.setAuthor("黑马程序员"); //设置作者 globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件 globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称 globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略 autoGenerator.setGlobalConfig(globalConfig); //设置包名相关配置 PackageConfig packageInfo = new PackageConfig(); packageInfo.setParent("com.aaa"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径 packageInfo.setEntity("domain"); //设置实体类包名 packageInfo.setMapper("dao"); //设置数据层包名 autoGenerator.setPackageInfo(packageInfo); //策略设置 StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setInclude("tbl_user"); //设置当前参与生成的表名,参数为可变参数 strategyConfig.setTablePrefix("tbl_"); //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名 例如: User = tbl_user - tbl_ strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格 strategyConfig.setVersionFieldName("version"); //设置乐观锁字段名 strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名 strategyConfig.setEntityLombokModel(true); //设置是否启用lombok autoGenerator.setStrategy(strategyConfig); //2.执行生成操作 autoGenerator.execute(); } }

代码生成器(新) | MyBatis-Plus

官方文档中获取代码进行修改  

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有