LambdaQueryWrapper&QueryWrapper增删改CURD使用教程案例

 目录




前言:



最近很多新入职的应届生开始进入项目组,可是他们真的是零基础的开发经验,大学过程中也没有好好地历练过怎么样开发一个应用程序,SpringBoot没使用过,Mybatis还是老套的xml配置化,真让我无语至极,不懂的现在SPringBoot里面的JPa可以注解实现SQL的增删改查,也不知道针对单表查询现在实际项目开发过程中根本不使用原生的Hibernate或者Mybatis了,现在使用的是Mybatis Plus,使用轻便友好,开发代码段少且完美的实现,在这里我需要写一个文档针对这些初级开发者做一个入门的讲解是如何开发使用的!



好处:单表查询的话,可以直接的使用对象操作,其实实现起来极其方便而且简单!


如果多表的查询的话,那就建议使用xml格式的配置化进行关联,文章末尾也进行了案例讲解参考学习!


目前在重构一个项目的时候要针对原有的SQL进行重写,所以针对一个好用的Mybatis的插件使用。在这里做一些总结,然后通过我们组内人员使用,统一的改用LambdaQueryWrapper&QueryWrapper


简单对象查询方式用起来极为方便!涉及到单表查询的是该该对象查询继承;


推荐使用:LambdaQueryWrapper


查询使用案例增删改查总结如下


1、【大小比较: ( =, <>, >, >=, <, <= )】


    eq(R column, Object val); // 等价于 =,例: eq("name", "媳妇") ---> name = '媳妇'
    ne(R column, Object val); // 等价于 <>,例: ne("name", "媳妇") ---> name <> '媳妇'
    gt(R column, Object val); // 等价于 >,例: gt("name", "媳妇") ---> name > '媳妇'
    ge(R column, Object val); // 等价于 >=,例: ge("name", "媳妇") ---> name >= '媳妇'
    lt(R column, Object val); // 等价于 <,例: lt("name", "媳妇") ---> name < '媳妇'     le(R column, Object val); // 等价于 <=,例: le("name", "媳妇") ---> name <= '媳妇'


使用上面直接对象的名称,以及入参即可,比如下面java代码实现列表查询


  1. public List<DimDict> listByDictCode(DictCodeEnum dictCodeEnum) {

  2. LambdaQueryWrapper<DimDict> wrapper = Wrappers.lambdaQuery();

  3. wrapper.eq(DimDict::getDictCode, dictCodeEnum.getCode())

  4. .eq(DimDict::getEnabled, DictEnableEnum.VALID.getType());

  5. return this.list(wrapper);


 2、【范围:(between、not between、in、not in)】


between(R column, Object val1, Object val2); // 等价于 between a and b, 例:                between("age", 18, 30) ---> age between 18 and 30
notBetween(R column, Object val1, Object val2); // 等价于 not between a and b, 例:    notBetween("age", 18, 30) ---> age not between 18 and 30
in(R column, Object... values); // 等价于 字段 IN (v0, v1, ...),例: in("age",{1,2,3}) ---> age in (1,2,3)
notIn(R column, Object... values); // 等价于 字段 NOT IN (v0, v1, ...), 例: notIn("age",{1,2,3}) ---> age not in (1,2,3)
inSql(R column, Object... values); // 等价于 字段 IN (sql 语句), 例: inSql("id", "select id from table where id < 3") ---> id in (select id from table where id < 3) notInSql(R column, Object... values); // 等价于 字段 NOT IN (sql 语句) 


主要实现的java代码如下,实现查询一个页面。里面会带有分页且根据时间排序


  1. public IPage<TbmNewsDupFilter> getInfoListByNewsId(String newsId, Byte position, Date startTime, Date endTime, Integer current, Integer size) {

  2. IPage<TbmNewsDupFilter> page = new Page<>(current, size);

  3. LambdaQueryWrapper<TbmNewsDupFilter> lqw = new LambdaQueryWrapper<>();

  4. lqw.eq(TbmNewsDupFilter::getNewsId, newsId).ne(TbmNewsDupFilter::getPosition, 0)

  5. .between(TbmNewsDupFilter::getCreateTime, startTime, endTime);

  6. if (null != position) {

  7. lqw.eq(TbmNewsDupFilter::getPosition, position);

  8. lqw.orderByDesc(TbmNewsDupFilter::getCreateTime);

  9. return tbmNewsDupFilterMapper.selectPage(page, lqw);


3、【模糊匹配:(like)】


like(R column, Object val); // 等价于 LIKE '%值%',例: like("name", "媳妇") ---> name like '%媳妇%'
notLike(R column, Object val); // 等价于 NOT LIKE '%值%',例: notLike("name", "媳妇") ---> name not like '%媳妇%'
likeLeft(R column, Object val); // 等价于 LIKE '%值',例: likeLeft("name", "媳妇") ---> name like '%媳妇' likeRight(R column, Object val); // 等价于 LIKE '值%',例: likeRight("name", "媳妇") ---> name like '媳妇%'


java代码查询右边末尾模糊查询,前端字符串匹配代码实现如下


  1. private Map<String, Double> queryWeight() {

  2. QueryWrapper<TagWeight> wrapper = new QueryWrapper<>();

  3. wrapper.lambda().likeRight(TagWeight::getTagType, "101109");

  4. List<TagWeight> list = tagWeightService.list(wrapper);

  5. if (CollectionUtils.isEmpty(list)) {

  6. return Maps.newHashMap();

  7. return list.stream().collect(Collectors.toMap(TagWeight::getTagType, TagWeight::getWeight));


  4、【空值比较:(isNull、isNotNull)】


    isNull(R column); // 等价于 IS NULL,例: isNull("name") ---> name is null     isNotNull(R column); // 等价于 IS NOT NULL,例: isNotNull("name") ---> name is not null


java代码使用的案例实现的代码如下可以一共参考,isnotNUll使用上比较多的


  1. private List<HwSecuritiesInfo> getHwSecuritiesInfoList(Long jsid, int limit) {

  2. LambdaQueryWrapper<HwSecuritiesInfo> lambda = new LambdaQueryWrapper<>();

  3. lambda.isNotNull(HwSecuritiesInfo::getCompanyCode)

  4. .ne(HwSecuritiesInfo::getSecuritiesSection, EXCLUDE_SEUCRITIES_SECTION)

  5. .gt(HwSecuritiesInfo::getJsid, jsid)

  6. .orderByAsc(HwSecuritiesInfo::getJsid);

  7. lambda.last("limit " + limit);

  8. return hwSecuritiesInfoService.list(lambda);


5、【分组、排序:(group、having、order)】


groupBy(R... columns); // 等价于 GROUP BY 字段, ..., 例: groupBy("id", "name") ---> group by id,name
orderByAsc(R... columns); // 等价于 ORDER BY 字段, ... ASC, 例: orderByAsc("id", "name") ---> order by id ASC,name ASC
orderByDesc(R... columns); // 等价于 ORDER BY 字段, ... DESC, 例: orderByDesc("id", "name") ---> order by id DESC,name DESC having(String sqlHaving, Object... params); // 等价于 HAVING ( sql语句 ), 例: having("sum(age) > {0}", 11) ---> having sum(age) > 11


实现的java代码参考如下通过分组来查询分页的使用代码


  1. @DataSource(DataSourceType.HW_BUSINESS)

  2. public IPage<Ds> selectDistinctDsByPage(DsQueryForm queryForm) {

  3. Integer currentPage = queryForm.getCurrentPage();

  4. Integer pageSize = queryForm.getPageSize();

  5. Page<Ds> page = new Page<>(currentPage, pageSize);

  6. LambdaQueryWrapper<Ds> lqw = new LambdaQueryWrapper<>();

  7. //数据源编码, 媒体栏目, 信息来源参数只传了一个

  8. String dsCode = queryForm.getDsCode();

  9. String dsSourceName = queryForm.getDsSourceName();

  10. String dsNewsColumns = queryForm.getDsNewsColumns();

  11. if (!StringUtil.isEmpty(dsCode)) {

  12. lqw.likeRight(Ds::getDsCode, SqlUtil.escapeLike(dsCode));

  13. lqw.groupBy(Ds::getDsCode).having("count (0) >1");

  14. } else if (!StringUtil.isEmpty(dsSourceName)) {

  15. lqw.like(Ds::getDsSourceName, SqlUtil.escapeLike(dsSourceName));

  16. lqw.groupBy(Ds::getDsSourceName);

  17. } else if (!StringUtils.isEmpty(dsNewsColumns)) {

  18. lqw.like(Ds::getDsNewsColumns, SqlUtil.escapeLike(dsNewsColumns));

  19. lqw.groupBy(Ds::getDsNewsColumns);

  20. lqw.orderByAsc(Ds::getDsCode);

  21. return dsMapper.selectPage(page, lqw);


6、【拼接、嵌套 sql:(or、and、nested、apply)】


or(); // 等价于 a or b, 例:eq("id",1).or().eq("name","媳妇") ---> id = 1 or name = '媳妇'
or(Consumer<Param> consumer); // 等价于 or(a or/and b),or 嵌套。例: or(i -> i.eq("name", "李白").ne("status", "活着")) ---> or (name = '李白' and status <> '活着')
and(Consumer<Param> consumer); // 等价于 and(a or/and b),and 嵌套。例: and(i -> i.eq("name", "李白").ne("status", "活着")) ---> and (name = '李白' and status <> '活着')
nested(Consumer<Param> consumer); // 等价于 (a or/and b),普通嵌套。例: nested(i -> i.eq("name", "李白").ne("status", "活着")) ---> (name = '李白' and status <> '活着')
apply(String applySql, Object... params); // 拼接sql(若不使用 params 参数,可能存在 sql 注入),例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08") ---> date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
last(String lastSql); // 无视优化规则直接拼接到 sql 的最后,可能存若在 sql 注入。
exists(String existsSql); // 拼接 exists 语句。例: exists("select id from table where age = 1") ---> exists (select id from table where age = 1) 使用案例java实现的代码逻辑last案例


  1. public Long calculateFileRealMd5(Long minId, Integer limit) {

  2. LambdaQueryWrapper<AnncFile> wrapper = new LambdaQueryWrapper<>();

  3. wrapper.eq(AnncFile::getUploadStatus, UploadStatusEnum.SUCCESS.getCode())

  4. .isNull(AnncFile::getRealFileMd5)

  5. .gt(AnncFile::getId, minId)

  6. .orderByAsc(AnncFile::getId)

  7. .last("limit " + limit);

  8. List<AnncFile> list = anncFileService.list(wrapper);


7、【QueryWrapper 条件:】


    select(String... sqlSelect); // 用于定义需要返回的字段。例: select("id", "name", "age") ---> select id, name, age
    select(Predicate<TableFieldInfo> predicate); // Lambda 表达式,过滤需要的字段。
    lambda(); // 返回一个 LambdaQueryWrapper    实际使用的select语句java代码实现案例


  1. private List<HwSecuritiesInfo> query(QueryParam param) {

  2. QueryWrapper<HwSecuritiesInfo> wrapper = new QueryWrapper<>();

  3. wrapper.lambda().gt(HwSecuritiesInfo::getId, param.getJsid())

  4. .orderByAsc(HwSecuritiesInfo::getId);

  5. wrapper.lambda().select(HwSecuritiesInfo::getId, HwSecuritiesInfo::getBusinessId, HwSecuritiesInfo::getCompanyCode);

  6. wrapper.last("limit " + param.getCount());

  7. return hwSecuritiesInfoService.list(wrapper);


8、【UpdateWrapper 条件:】


    set(String column, Object val); // 用于设置 set 字段值。例: set("name", null) ---> set name = null
    etSql(String sql); // 用于设置 set 字段值。例: setSql("name = '老公'") ---> set name = '老公'     lambda(); // 返回一个 LambdaUpdateWrapper 


java代码使用案例如下


  1. public List<GelonghuiNews> selectGelonghuiNews(Long lastId) {

  2. QueryWrapper<GelonghuiNews> wrapper = new QueryWrapper<>();

  3. if (null == lastId) {

  4. wrapper.lambda().gt(GelonghuiNews::getJsid, lastId).eq(GelonghuiNews::getImageStatus,OssImageStatus.YES.getStatus());

  5. return super.baseMapper.selectList(wrapper);


使用功能简单地开发代码截图如下



LambdaQueryWrapper<HwPicture> lambdaQueryWrapper = new LambdaQueryWrapper<>();


9、 LambdaQueryWrapper使用其实更为方便;


因为很多个性化的功能呢都在这里面使用的,所以目前开发组建议使用这个;


java使用案例如下:


  1. public List<TbmNewsPopularFeelings> selectNewsPopularFeelings(Date startTime, Date endTime, Integer limitSize) {

  2. LambdaQueryWrapper<TbmNewsPopularFeelings> lambdaQueryWrapper = new LambdaQueryWrapper<>();

  3. lambdaQueryWrapper.ge(startTime != null, TbmNewsPopularFeelings::getCreateTime, startTime);

  4. lambdaQueryWrapper.le(endTime != null, TbmNewsPopularFeelings::getCreateTime, endTime);

  5. lambdaQueryWrapper.orderByAsc(TbmNewsPopularFeelings::getCreateTime);

  6. lambdaQueryWrapper.last("limit " + limitSize);

  7. return historyNewsEventMapper.selectList(lambdaQueryWrapper);



10,多表查询如何配置使用



代码案例使用


11.pom依赖


目前的Mybatis-Plus版本已经跟新到2.5.2【本篇博客更新2022-06-15】


<mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version><mybatis-plus-boot-starter.version>3.5.2</mybatis-plus-boot-starter.version><mybatis-plus-extension.version>3.5.2</mybatis-plus-extension.version><mybatis-plus-core.version>3.5.2</mybatis-plus-core.version>


目前如果仅仅只是使用上面的功能的话,下面的俩个依赖已经完全满足需要了!


  1. <groupId>com.baomidou</groupId>

  2. <artifactId>mybatis-plus-core</artifactId>

  3. <version>${mybatis-plus-core.version}</version>

  4. <groupId>com.baomidou</groupId>

  5. <artifactId>mybatis-plus-boot-starter</artifactId>

  6. <version>${mybatis-plus-boot-starter.version}</version>

  7. </dependency>

本文同步于我的CSDN文章 [我的原始文章参考] 

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容