最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

mybatis-plus QueryWrapper自定義查詢條件的實(shí)現(xiàn)

 更新時(shí)間:2020年08月24日 11:37:11   作者:低調(diào)路人甲  
這篇文章主要介紹了mybatis-plus QueryWrapper自定義查詢條件的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

mybatis-plus框架功能很強(qiáng)大,把很多功能都集成了,比如自動生成代碼結(jié)構(gòu),mybatis crud封裝,分頁,動態(tài)數(shù)據(jù)源等等,附上官網(wǎng)鏈接https://mp.baomidou.com/,github上有代碼例子,國內(nèi)小伙伴推薦碼云https://gitee.com/baomidou/mybatis-plus
 但是,其中還是有些小坑,文檔也沒有涉及的很全面,碰到問題,百度或者發(fā)issue,能力強(qiáng)的還是直接看源碼好,一切答案都在源碼中。

版本推薦用3.1.0,3.1.1及以上版本有bug,訪問mapper接口的時(shí)候,會把數(shù)據(jù)庫date類型轉(zhuǎn)換為localDateTime,報(bào)錯java.sql.SQLFeatureNotSupportedException

解決方案可以參考 http://www.fzitv.net/article/193995.htm

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.1.0</version>
</dependency>

mybatis-plus里有個(gè)類QueryWrapper,封裝sql對象,包括where條件,order by排序,select哪些字段等等。該類的具體用法,網(wǎng)上教程很多。

這里有個(gè)需求,通過前端提交查詢條件,后臺動態(tài)拼接成where的sql語句,用于查詢。常規(guī)做法是前端提交一堆查詢參數(shù),controller層用一個(gè)對象接收,然后在mybatis的xml里對該對象里的各種屬性做判斷

<select id="test">
 select * from test
 <where>
 <if test=" name != null and name != '' ">
  and name=#{name}
 </if>
 ...
 </where>
</select>

這有個(gè)問題是具體字段連接類型就有很多,like,=,>,<等等。當(dāng)然要實(shí)現(xiàn)功能有很多種方式,mybatis-plus的QueryWrapper很強(qiáng)大,可以通過對象的方式進(jìn)行查詢操作,但是不同的頁面都自己管自己,效率低下,會存在大量重復(fù)代碼。所以我就想自己封裝一套,從前端的查詢條件傳固定格式的參數(shù),到后臺進(jìn)行轉(zhuǎn)換,自動拼接成對應(yīng)的where sql語句,再傳到mybatis xml里進(jìn)行動態(tài)查詢。這樣所有頁面就可以統(tǒng)一,便于操作。下面進(jìn)入正題:

前端

前端用的技術(shù)是html+jquery,jquery操作dom做各種操作。html就僅僅是樣式展現(xiàn),不涉及任何的邏輯代碼,沒有使用vue之類的mvvm框架,也沒有使用thymeleaf之類的模板引擎,其實(shí)這些都會在html嵌入污染代碼,導(dǎo)致美工修改頁面樣式的時(shí)候一臉蒙蔽。html就是純的html+css,通過jquery來完成剩余的工作。

index.html

<form id="myform">
 <input name="name"/>
 <input name="age"/>
 <input name="startdate"/>
 <input name="enddate"/>
</form>

jquery發(fā)起post請求,拼接的參數(shù)如下:

var searchParam = [
 {column: "COLUMN_NAME",type: "like", value: "tim"},
 {column: "COLUMN_AGE",type: "eq", value: "22"},
 {column: "COLUMN_DATE",type: "ge", value: "2019-08-16 00:00:00"},
 {column: "COLUMN_DATE",type: "le", value: "2019-08-16 23:59:59"}
];

其中column值 為數(shù)據(jù)表的字段名;type值為sql字段拼接的方式,規(guī)則可自己定制;value就是字段值了;目標(biāo)拼接成的sql語句如下:

COLUMN_NAME like '%tim%' and COLUMN_AGE=22 and COLUMN_DATE>='2019-08-16 00:00:00' and COLUMN_DATE<='2019-08-16 23:59:59'

 jquery發(fā)起post請求:

$.ajax({
 url: "list",
 type: "post",
 data: {pageNum:1,pageSize:20,condition:JSON.stringify(searchParam),...(根據(jù)需要自己加請求參數(shù))}
 success: function(result){...}
});

說明:請求參數(shù)condition為什么要傳json字符串后續(xù)有介紹。

后端

Controller

controller接收前端發(fā)過來的參數(shù),碰到一個(gè)問題,在有多個(gè)請求參數(shù)的情況下,如何接收 集合對象 請求參數(shù)?使用了很多方法都不行,后續(xù)有空再研究下,目前使用的方法簡單粗暴,就上傳json字符串,后端轉(zhuǎn)換成對象。

Controller:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@RequestMapping(value = "/list", method = RequestMethod.POST)
public Object getTestList(@RequestParam(name = "pageNum", required = false, defaultValue = "1") int pageNum,
             @RequestParam(name = "pageSize", required = false, defaultValue = "15") int pageSize,
             @RequestParam(name = "condition",required = false) String conditionJson) {
 QueryWrapper queryWrapper = SearchUtil.parseWhereSql(conditionJson);
   queryWrapper.orderByDesc("CREATE_DATE");
   return service.getPageTestList(queryWrapper,pageNum,pageSize);
}

SearchUtil:

public static QueryWrapper parseWhereSql(String conditionJson){
  QueryWrapper queryWrapper = new QueryWrapper();
  if(StrUtil.isNotEmpty(conditionJson)){
    List<ConditionVo> conditionList = JSON.parseArray(conditionJson,ConditionVo.class);
    if(CollUtil.isNotEmpty(conditionList)){
      for(ConditionVo conditionVo : conditionList){
        switch (conditionVo.getType()){
          case "eq": queryWrapper.eq(conditionVo.getColumn(),conditionVo.getValue());break;
          case "ne": queryWrapper.ne(conditionVo.getColumn(),conditionVo.getValue());break;
          case "like": queryWrapper.like(conditionVo.getColumn(),conditionVo.getValue());break;
          case "leftlike": queryWrapper.likeLeft(conditionVo.getColumn(),conditionVo.getValue());break;
          case "rightlike": queryWrapper.likeRight(conditionVo.getColumn(),conditionVo.getValue());break;
          case "notlike": queryWrapper.notLike(conditionVo.getColumn(),conditionVo.getValue());break;
          case "gt": queryWrapper.gt(conditionVo.getColumn(),conditionVo.getValue());break;
          case "lt": queryWrapper.lt(conditionVo.getColumn(),conditionVo.getValue());break;
          case "ge": queryWrapper.ge(conditionVo.getColumn(),conditionVo.getValue());break;
          case "le": queryWrapper.le(conditionVo.getColumn(),conditionVo.getValue());break;
        }
      }
    }
  }
  return queryWrapper;
}

該類是重點(diǎn),根據(jù)type不同的值進(jìn)行組合,queryWrapper包含了很多拼接方法,可以看文檔。這里只寫了一些常用的拼接方法。

ConditionVo:

@Data
public class ConditionVo implements Serializable {
  private static final long serialVersionUID = -5099378457111419832L;
  /**
   * 數(shù)據(jù)庫字段名
   */
  private String column;
  /**
   * 字段值
   */
  private String value;
  /**
   * 連接類型,如llike,equals,gt,ge,lt,le
   */
  private String type;
}

拿到queryWrapper對象就是重點(diǎn)了,之后就是sql操作了。

Service

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@Override
public IPage<ListVo> getPageEntityList(QueryWrapper queryWrapper, int pageNum, int pageSize) {
   Page<ListVo> page = new Page<>(pageNum,pageSize);
   IPage<ListVo> list = page(page,queryWrapper);
   return list;
 }
@Override
public IPage<ListVo> getPageTestList(QueryWrapper queryWrapper, int pageNum, int pageSize) {
  Page<ListVo> page = new Page<>(pageNum,pageSize);
  IPage<ListVo> list = mapper.getPageTestList(page,queryWrapper);
  return list;
}

上面的第一個(gè)方法getPageEntityList使用的是mybatis-plus自帶的page(page,queryWrapper)方法,具體使用方法可以查看官方文檔。使用該方法就不需要自己寫sql語句了。本篇文章重點(diǎn)是下面那個(gè)方法getPageTestList。
mybatis-plus自帶了強(qiáng)大的翻頁功能,只需往mapper方法里傳入一個(gè)Page類,該類實(shí)現(xiàn)了IPage接口。
 這里有個(gè)坑,通過看源碼發(fā)現(xiàn),mapper方法的參數(shù)有順序要求:page對象一定要放在第一個(gè)參數(shù),否則翻頁查詢會報(bào)錯。源碼在com.baomidou.mybatisplus.core.override.MybatisMapperMethod中public Object execute(SqlSession sqlSession, Object[] args)方法的case SELECT判斷里,因反編譯后的行數(shù)可能不同,所以貼上具體是哪個(gè)方法,我這邊反編譯后在68行。
ListVo是自己的業(yè)務(wù)對象。

Mapper

import com.baomidou.mybatisplus.core.toolkit.Constants;
IPage<ListVo> getPageTestList(Page<ListVo> page,@Param(Constants.WRAPPER) Wrapper query);

大家可以進(jìn)Constans這個(gè)接口看下源碼都有哪些值,后續(xù)xml要用到。

XML

<select id="getPageTestList" resultType="xx.xx.xx.ListVo">
  select * from test
  <if test="ew.emptyOfWhere == false">
    ${ew.customSqlSegment}
  </if>
</select>

這里先強(qiáng)調(diào)一點(diǎn),${ew.customSqlSegment}是用美元符號$,而不是#。

這里的ew是啥?其實(shí)就是mapper方法里的@Param(Constants.WRAPPER) Wrapper query對象,Constants.WRAPPER的值就是ew。

首先判斷ew.emptyOfWhere是否存在where條件,有的話再拼接上去。ew里還有個(gè)屬性nonEmptyOfWhere,看單詞應(yīng)該跟emptyOfWhere的值相反,但是在xml中使用卻提示不存在,不知道為什么,又是一個(gè)地雷?

ew.customSqlSegment又是啥,該值是WHERE + sql語句,還有個(gè)ew.sqlSegment是不包括WHERE字符串。大家可以在service層輸出queryWrapper里面的相關(guān)方法:

log.info(queryWrapper.isEmptyOfWhere()+"");
log.info(queryWrapper.getCustomSqlSegment());
log.info(queryWrapper.getSqlSegment());
log.info(queryWrapper.getParamNameValuePairs().toString());

輸出如下:

getCustomSqlSegment()
 WHERE COLUMN_NAME LIKE #{ew.paramNameValuePairs.MPGENVAL1}
 getSqlSegment()
 COLUMN_NAME LIKE #{ew.paramNameValuePairs.MPGENVAL1}
 getParamNameValuePairs()
 {MPGENVAL1=%tim%}

看到這,mybatis框架用的熟練的小伙伴們應(yīng)該就懂了吧,這樣就可以避免sql注入的問題。
 這里又有 一個(gè)小坑,就是order by排序。傳入了page參數(shù),mybatis-plus底層就會幫你翻頁查詢,會查詢總數(shù)量。通過輸出的sql日志可以發(fā)現(xiàn),其實(shí)框架是在你的sql基礎(chǔ)上外面再套一層select count(1) from。這里會有個(gè)問題,本人用的數(shù)據(jù)庫是sqlserver,如果在count查詢語句里用了order by就會出錯,解決方法是調(diào)用queryWrapper對象中的排序方法,如:queryWrapper.orderByDesc("CREATE_DATE"),xml中就不要用order by。所以我在controller層用了這個(gè)方法,這樣mybatis-plus底層會合理地進(jìn)行查詢。

總結(jié)

通過上面這種封裝方式,就不需要在xml里面做一大堆的where條件if判斷來拼接sql。
mybatis-plus框架功能很強(qiáng)大,且還在維護(hù)中,有空可以仔細(xì)閱讀下文檔、官方例子,能力強(qiáng)的可以直接看源碼,一切答案都在源碼中。

到此這篇關(guān)于mybatis-plus QueryWrapper自定義查詢條件的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)mybatis-plus QueryWrapper查詢條件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解Mybatis中的resultType和resultMap

    深入理解Mybatis中的resultType和resultMap

    這篇文章給大家介紹了mybatis中的resultType和resultMap的用法實(shí)例講解,MyBatis中在查詢進(jìn)行select映射的時(shí)候,返回類型可以用resultType,也可以用resultMap,至于兩種用法區(qū)別,通過本文一起學(xué)習(xí)吧
    2016-09-09
  • java學(xué)生信息管理系統(tǒng)設(shè)計(jì)

    java學(xué)生信息管理系統(tǒng)設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了java學(xué)生信息管理系統(tǒng)設(shè)計(jì),學(xué)生信息添加進(jìn)入數(shù)據(jù)庫的事務(wù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 淺談springcloud gateway 連接保活問題

    淺談springcloud gateway 連接?;顔栴}

    這篇文章主要介紹了springcloud gateway 連接?;顔栴},具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • kafka 重新分配partition和調(diào)整replica的數(shù)量實(shí)現(xiàn)

    kafka 重新分配partition和調(diào)整replica的數(shù)量實(shí)現(xiàn)

    當(dāng)需要提升Kafka集群的性能和負(fù)載均衡時(shí),可通過kafka-reassign-partitions.sh命令手動重新分配Partition,增加節(jié)點(diǎn)后,可以將Topic的Partition的Leader節(jié)點(diǎn)均勻分布,以提高寫入和消費(fèi)速度,感興趣的可以了解一下
    2022-03-03
  • 深入理解注解與自定義注解的一些概念

    深入理解注解與自定義注解的一些概念

    今天給大家?guī)淼奈恼率亲⒔獾南嚓P(guān)知識,本文圍繞著注解與自定義注解的一些概念展開,文中詳細(xì)介紹了這些知識,需要的朋友可以參考下
    2021-06-06
  • @CacheEvict中的allEntries與beforeInvocation的區(qū)別說明

    @CacheEvict中的allEntries與beforeInvocation的區(qū)別說明

    這篇文章主要介紹了@CacheEvict中的allEntries與beforeInvocation的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • spring boot task實(shí)現(xiàn)動態(tài)創(chuàng)建定時(shí)任務(wù)的方法

    spring boot task實(shí)現(xiàn)動態(tài)創(chuàng)建定時(shí)任務(wù)的方法

    這篇文章主要介紹了spring boot task實(shí)現(xiàn)動態(tài)創(chuàng)建定時(shí)任務(wù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • spring boot項(xiàng)目中MongoDB的使用方法

    spring boot項(xiàng)目中MongoDB的使用方法

    前段時(shí)間分享了關(guān)于Spring Boot中使用Redis的文章,除了Redis之后,我們在互聯(lián)網(wǎng)產(chǎn)品中還經(jīng)常會用到另外一款著名的NoSQL數(shù)據(jù)庫MongoDB。下面這篇文章主要給大家介紹了關(guān)于在spring boot項(xiàng)目中MongoDB的使用方法,需要的朋友可以參考下。
    2017-09-09
  • JavaWeb response完成重定向?qū)崿F(xiàn)過程詳解

    JavaWeb response完成重定向?qū)崿F(xiàn)過程詳解

    這篇文章主要介紹了JavaWeb response完成重定向?qū)崿F(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • spring應(yīng)用中多次讀取http post方法中的流遇到的問題

    spring應(yīng)用中多次讀取http post方法中的流遇到的問題

    這篇文章主要介紹了spring應(yīng)用中多次讀取http post方法中的流,文中給大家列舉處理問題描述及解決方法,需要的朋友可以參考下
    2018-11-11

最新評論

彭山县| 精河县| 靖西县| 临武县| 专栏| 集贤县| 安溪县| 来凤县| 广东省| 巩义市| 互助| 遵义市| 保靖县| 绥棱县| 阳高县| 涪陵区| 乌海市| 武清区| 政和县| 富民县| 辉南县| 凯里市| 茂名市| 东源县| 大同县| 定陶县| 伊通| 南华县| 咸宁市| 盐池县| 永新县| 江油市| 贺州市| 阆中市| 云龙县| 甘孜县| 秭归县| 淮滨县| 怀宁县| 泰来县| 密云县|