Spring学习——MyBatisPlus使用
创始人
2025-05-30 22:47:11
0

标准CRUD书写

lombok

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

  • 免去getter/setter/toString的书写

  1. 导入依赖
org.projectlomboklombok1.18.12provided

  1. 在实体类前加上@Data注解
@Data
@TableName(value = "tb_user")
public class User {private int id;private String name;private String password;private int age;private String tel;
}

标准CRUD

  • 查询全部
@Test
void testGetAll() {List users = userDao.selectList(null);users.forEach(System.out::println);
}
  • 根据id查询
@Test
void testGetById() {User user = userDao.selectById(1);System.out.println(user);
}
  • 根据id删除
@Test
void testDeleteById() {userDao.deleteById(2);
} 
  • 更新
@Test
void testUpdateById() {User user = new User();user.setId(1);user.setName("jihua");userDao.updateById(user);//只修改提供的字段,不提供的不会修改为NULL
}

分页查询

  1. 设置分页拦截器作为Spring管理的bean(新建配置类)
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {//1.定义MybatisPlus拦截器MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//2.添加具体拦截器mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return mybatisPlusInterceptor;}
}
  1. 执行分页查询
@Test
void testGetByPage() {IPage page = new Page(1,2);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());
}
  • 关于开启MybatisPlus的日志(在配置文件application.yml中)
# 开启日志,输出到控制台
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

DQL编程控制

条件查询

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

条件查询——设置查询条件

格式一:常规格式

//格式一:常规格式
@Test
void testWrapperGet1(){QueryWrapper qw = new QueryWrapper();//查询年龄大于等于18,小于60岁的用户qw.lt("age",60);qw.ge("age",18);List users = userDao.selectList(qw);users.forEach(System.out::println);
}

格式二:链式编程格式

//格式二:链式编程格式
@Test
void testWrapperGet2(){QueryWrapper qw = new QueryWrapper();//查询年龄大于等于18,小于60岁的用户qw.lt("age",60).ge("age",18);List users = userDao.selectList(qw);users.forEach(System.out::println);
}

格式三:lambda格式(推荐)

//格式三:lambda格式(推荐)
@Test
void testWrapperGet3(){QueryWrapper qw = new QueryWrapper();//查询年龄大于等于18,小于60岁的用户qw.lambda().lt(User::getAge,60).ge(User::getAge,18);List users = userDao.selectList(qw);users.forEach(System.out::println);
}

格式四:lambda格式

//格式四:lambda格式
@Test
void testWrapperGet4(){LambdaQueryWrapper lqw = new LambdaQueryWrapper();//查询年龄大于等于18,小于60岁的用户lqw.lt(User::getAge,60).ge(User::getAge,18);List users = userDao.selectList(lqw);users.forEach(System.out::println);
}

条件查询——组合条件

组合条件and

//条件查询——组合条件and
@Test
void testWrapperAnd(){LambdaQueryWrapper lqw= new LambdaQueryWrapper();//查询年龄大于等于18,小于60岁的用户lqw.lt(User::getAge,60).ge(User::getAge,18);List users = userDao.selectList(lqw);users.forEach(System.out::println);
}

组合条件or

//条件查询——组合条件or
@Test
void testWrapperOr(){LambdaQueryWrapper lqw= new LambdaQueryWrapper();//查询年龄小于等于18,或大于60岁的用户lqw.gt(User::getAge,60).or().le(User::getAge,18);List users = userDao.selectList(lqw);users.forEach(System.out::println);
}

条件查询—— null值判定

使用if语句控制条件追加

@Test
void testWrapperNull() {UserQuery user = new UserQuery();user.setAge(18);//下限//user.setAge2(40);//上限LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();if(null != user.getAge()){lqw.gt(User::getAge,user.getAge());}if(null!=user.getAge2()){lqw.lt(User::getAge,user.getAge2());}List users = userDao.selectList(lqw);users.forEach(System.out::println);
}

条件参数控制

@Test
void testWrapperNull() {UserQuery user = new UserQuery();user.setAge(18);//下限//user.setAge2(40);//上限LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();lqw.gt(null != user.getAge(),User::getAge,user.getAge()).lt(null!=user.getAge2(),User::getAge,user.getAge2());List users = userDao.selectList(lqw);users.forEach(System.out::println);
}

查询投影

查询投影——常规

//查询投影——常规
@Test
void testSelect() {QueryWrapper qw = new QueryWrapper<>();qw.select("name", "age", "tel");List users = userDao.selectList(qw);users.forEach(System.out::println);
}

查询投影——lambda

//查询投影——lambda
@Test
void testSelectLambda() {LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();lqw.select(User::getName, User::getAge, User::getTel);List users = userDao.selectList(lqw);users.forEach(System.out::println);
}

查询条件

eq匹配

LambdaQueryWrapper lqw = new LambdaQueryWrapper();
lqw.eq(User::getName, userQuery.getName()).eq(User::getPassword, userQuery.getPassword());
User loginUser = userDao.selectOne(lqw);
System.out.println(loginuser);

le,ge匹配、between匹配

LambdaQueryWrapper lqw = new LambdaQueryWrapper();
//方案一:设定上限下限
lqw.le(User::getAge, userQuery.getAge()).ge(User::getAge, userQuery.getAge2());
//方案二:设定范围
lqw.between(User::getAge, userQuery.getAge( ), userQuery.getAge2( ));List userList = userDao.selectList(lqw);
System.out.println(userList);

like匹配

LambdaQuerywrapper fqw = new LambdaQuerywrapper();
lqw.likeLeft(User::getTel, userQuery.getTel());
List userList = userDao.selectList(lqw);
System.out.println(userList);
  • like匹配
    • like(name, "R"):%R%
    • likeLeft(name, "R"):R%
    • likeRight(name, "R"):%R

分组统计查询

  • 使用count(*)进行统计查询时,查询应该使用 selectMaps()
//分组统计查询
@Test
void testSelectGroup() {QueryWrapper qw = new QueryWrapper<>();qw.select("count(*) as 人数", "age");qw.groupBy("age");List> mapList = userDao.selectMaps(qw);mapList.forEach(System.out::println);
}

字段映射与表名映射

@TableName("tbl_user")//将实体类与表名映射
public class User {private Long id;@TableField(value="pwd")//将实体类的属性和表的列名对应private String name;@TableField(select = false)//设置属性不参与查询 private string password;private Integer age;private String tel;@TableField(exist = false)//设置属性在表中是否存在private Integer online;
}

  • 名称:@TableField

  • 类型:属性注解

  • 位置:模型类属性定义上方

  • 作用:设置当前属性对应的数据库表中的字段关系

  • 范例:

    public class User {private Long id;@TableField(value="pwd")//将实体类的属性和表的列名对应private String name;@TableField(select = false)//设置属性不参与查询 private string password;private Integer age;private String tel;@TableField(exist = false)//设置属性在表中是否存在private Integer online;
    }
    
  • 相关属性

    • value:设置数据库表字段名称
    • exist:设置属性在数据库表字段中是否存在,默认为true。此属性无法与value合并使用
    • select:设置属性是否参与查询,此属性与select()映射配置不冲突

  • 名称:@TableName

  • 类型:类注解

  • 位置:模型类定义上方

  • 作用:设置当前类对应与数据库表关系

  • 范例:

    @TableName("tbl_user")//将实体类与表名映射
    public class User {...
    }
    
  • 相关属性

    • value:设置数据库表名称

DML编程控制

insert

id生成策略控制

  • 不同的表应用不同的id生成策略
    • 日志:自增(1,2,3,4,…)
    • 购物订单:特殊规则(FQ23948AK3843)
    • 外卖单:关联地区日期等信息(10 04 20200314 34 91)
    • 关系表:可省略id

  • 名称:@TableId

  • 类型:属性注解

  • 位置:模型类中用于表示主键的属性定义上方

  • 作用:设置当前类中主键属性的生成策略

  • 范例:

    public class User {@TableId(type = IdType.AUTO)private Long id;
    }
    
  • 相关属性

    • value:设置数据库主键名称
    • type:设置主键属性的生成策略,值参照IdType枚举值

  • AUTO(0):使用数据库id自增策略控制id生成
  • NONE(1):不设置id生成策略
  • INPUT(2):用户手工输入id
  • ASSIGN_ID(3):雪花算法生成id(可兼容数值型与字符串型)
  • ASSIGN_UUID(4):以UUID生成算法作为id生成策略

全局配置

在application.yml中

mybatis-plus:global-config:db-config:#配置id生成策略id-type: auto#配置表名前缀(即表名在实体类名称前面加的前缀)table-prefix: tbl_

delete

多记录操作

  • 按照主键删除多条记录
List ids= Arrays.asList(new Long[ ]{2,3});
userDao.deleteBatchIds(ids);
  • 根据主键查询多条记录
List ids= Arrays.asList(new Long[]{2,3});
List userList = userDao.selectBatchIds(ids);

逻辑删除

  • 逻辑删除就是在执行删除操作时不删除数据,而是将数据标记为已删除

步骤:

  1. 数据库表中添加逻辑删除标记字段

    • 在数据库表中添加一列名为deleted的字段,设置默认值为0
  2. 实体类中添加对应字段,并设定当前字段为逻辑删除标记字段

    public class User {private Long id;@TableLogic(value = "0", delval = "1")//配置逻辑删除,0为未删除,1为已删除private Integer deleted;
    }
    
  3. 也可以在配置(application.yml)中做全局逻辑删除配置

    mybatis-plus:global-config:db-config:#配置逻辑删除字段名logic-delete-field: deleted#配置未删除时的值logic-not-delete-value: 0#配置已删除的值logic-delete-value: 1
    
  • 一旦开启逻辑删除功能后,delete语句都将变为update语句(不是delete而是updata他的deleted值为1 )

  • 查询操作也会自动加上条件where deleted = 0

  • 要想查询全部属性需要自己编写SQL语句进行查询

乐观锁

数据库表中添加锁标记字段version,在操作数据时先查询出当前version,执行操作时将查询到的version与当前表中的version进行对比(防止数据被其他线程修改过),在执行操作后将version+1

  1. 数据库表中添加锁标记字段version

  2. 实体类中添加对应字段,并设定当前字段为逻辑删除标记字段

    public class User {private Long id;@Versionprivate Integer version;
    }
    
  3. 配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装

    @Configuration
    public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {//1.定义MybatisPlus拦截器MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//2.添加乐观锁拦截器mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}
    }
    
  4. 使用乐观锁机制在修改前必须先获取到对应数据的verion方可正常进行

    @Test
    void testUpdate(){//先查询数据,获取到version数据User user = userDao.selectById(1L);User user1 = userDao.selectById(1L);//执行数据修改操作//操作一user.setName("Tom and Jerry");userDao.updateById(user);//操作二user1.setName("6666");userDao.updateById(user1);
    }//此时操作二将不会执行成功
    
    • 执行修改前先执行查询语句:

      SELECT id,name,age,tel,deleted,version FROM tbl_user WHERE id=?
      
    • 执行修改时使用version字段作为乐观锁检查依据

      UPDATE tbl_user SET name=?, age=?, tel=?, version=? WHERE id=? AND version=?
      

相关内容

热门资讯

iPhone手机怎么玩安卓系统... 你有没有想过,你的iPhone手机竟然也能玩安卓系统?没错,就是那个一直以来让你觉得遥不可及的安卓世...
平板删安卓系统更新不了,原因及... 最近是不是你也遇到了这样的烦恼?平板电脑上的安卓系统更新不了,是不是让你头疼得要命?别急,今天就来给...
苹果组装机安卓系统卡,卡顿背后... 你有没有发现,最近用苹果手机的时候,有时候系统有点卡呢?这可真是让人头疼啊!你知道吗,其实这背后还有...
安卓系统原生浏览器,功能与体验... 你有没有发现,每次打开手机,那个小小的浏览器窗口总是默默无闻地在那里,陪你浏览网页、搜索信息、看视频...
安卓机如何上苹果系统,跨平台体... 你是不是也和我一样,对安卓机和苹果系统之间的切换充满了好奇?想象你的安卓手机里装满了各种应用,而苹果...
安卓导入系统证书失败,原因分析... 最近在使用安卓手机的时候,你是不是也遇到了一个让人头疼的问题——导入系统证书失败?别急,今天就来给你...
安卓原生系统有哪些手机,盘点搭... 你有没有想过,为什么有些手机用起来就是那么流畅,那么顺心呢?这背后可大有学问哦!今天,就让我带你一起...
安卓系统关机了怎么定位,安卓系... 手机突然关机了,是不是有点慌张呢?别担心,今天就来教你一招,让你的安卓手机即使关机了,也能轻松定位到...
安卓系统游戏加速器,畅享无延迟... 你有没有发现,手机游戏越来越好玩了?不过,有时候游戏体验可能并不那么顺畅,是不是因为手机性能不够强大...
安卓4系统天气功能,尽在掌握 安卓4系统天气功能大揭秘在当今这个数字化的世界里,手机已经不仅仅是一个通信工具,它更是一个集成了各种...
安卓系统如何玩碧蓝幻想,攻略与... 你有没有想过,在安卓系统上玩《碧蓝幻想》竟然可以这么酷炫?没错,就是那个让你沉迷其中的二次元大作!今...
安卓系统搜不到图朵,图朵生成之... 最近是不是你也遇到了这样的烦恼?手机里明明有那么多美美的图片,但是用安卓系统搜索的时候,却怎么也找不...
魁族8刷安卓系统,系统升级后的... 哇,你知道吗?最近在安卓系统圈子里,有一个话题可是引起了不小的轰动,那就是魁族8刷安卓系统。你是不是...
微信正版安装安卓系统,畅享沟通... 你有没有想过,你的微信是不是正版安装的安卓系统呢?这可不是一个小问题哦,它关系到你的微信使用体验和隐...
电视能刷安卓系统吗,电视也能刷... 电视能刷安卓系统吗?揭秘智能电视的无限可能想象你家的电视不再只是用来观看节目的工具,而是变成了一个功...
安卓系统开通通知功能,畅享智能... 你知道吗?最近安卓系统更新后,新增了一个超级实用的功能——开通通知功能!这可是个大喜事,让咱们的生活...
苹果系统安卓爱思助手,系统兼容... 你有没有发现,手机的世界里,苹果系统和安卓系统就像是一对欢喜冤家,总是各有各的粉丝,各有各的拥趸。而...
安卓系统占用很大内存,揭秘内存... 手机里的安卓系统是不是让你感觉内存不够用,就像你的房间堆满了杂物,总是找不到地方放新东西?别急,今天...
安卓系统p30,安卓系统下的摄... 你有没有发现,最近安卓系统P30在手机圈里可是火得一塌糊涂呢!这不,我就来给你好好扒一扒这款手机的那...
siri被安卓系统进入了,智能... 你知道吗?最近科技圈可是炸开了锅,因为一个大家伙——Siri,竟然悄悄地溜进了安卓系统!这可不是什么...