JPA 動態查詢之AND OR結合使用

2021-09-25 23:46:18 字數 2556 閱讀 5665

現在,我負責開發的專案中,使用jpa作為orm框架。有了jpa,一行sql都沒寫過。在昨天,有乙個新的需求,需要進行動態查詢,這個簡單。但是有乙個地方需要and、or結合使用,這裡,我將記錄下我的理解與寫法,希望能幫助到大家。

需要根據條件進行動態查詢,實現一條類似下文的語句:

select *

from table

where 1 = 1

if (a == 1)

and table.column1 = a

if (b != null)

and table.column2 = b

if (clist != null && clist.size() > 0)

and table.column3 in clist

if (d == 2 || dd == 2)

and (table.column4 = d or table.column5 = dd)

上面是幾行偽**。意思是,幾個條件之間是and連線,但是其中的部分條件,是使用or連線的。

在我們的實際專案中,這個場景也是很常見的。這裡,我將分享下具體的寫法。以我們專案中的例子為例。

jpa的動態查詢,這裡我們使用的方式是:實現 specification 介面,自定義動態查詢邏輯。這也是我個人比較推薦的方式。jpa的使用、specification 介面基礎知識這裡我就不講了。有興趣的朋友可以查閱官方文件學習。

下面,我們首先定義好我們的資料庫實體:

@data

@entity

@table(name = "user")

public class user

然後定義好dao層介面:

@repository

public inte***ce userdao extends jparepository

下面是前端傳過來的動態查詢的引數物件:

@data

public class userdto

然後,重要的地方來了,我們實現 specification 介面,定義查詢邏輯:

在實際**操作中,我會將這部分邏輯抽離為乙個單獨的方法,使用lambda表示式完成,其實也就是匿名內部類。

private specificationgetlistspec(userdto userdto) 

listagelist = userdto.getagelist();

if (!collectionutils.isempty(agelist))

/* 下面這一行**很重要。

* criteriabuilder.or(predicate... restrictions) 接收多個predicate,可變引數;

* 這多個 predicate條件之間,是使用or連線的;該方法最終返回 乙個predicate物件;

*/predicatelist.add(criteriabuilder.or(usernameoragepredicate.toarray(new predicate[0])));

// 使用者id list,in 查詢

listuseridlist = reqdto.getuseridlist();

if (!collectionutils.isempty(useridlist))

// 生日時間段查詢

date birthdaybegin = reqdto.getbirthdaybegin();

date birthdayend = reqdto.getbirthdayend();

if (birthdaybegin != null && birthdayend != null)

// 最終,使用and 連線 多個 predicate 查詢條件

return criteriabuilder.and(predicatelist.toarray(new predicate[0]));

};}

這樣,我們的動態查詢部分就構建完畢了。具體怎麼使用呢?如下:

specificationqueryspec = this.getlistspec(userdto);

listuserlist = userdao.findall(queryspec);

就這樣,我們就執行了一次動態查詢,並獲取到了結果。

上面的動態查詢,實際上等價於下面的偽**:

select * 

from user

where user.deleteflag = 0

and ( user.username like '%%' or user.age in agelist )

and user.id in useridlist

and user.birthday > birthdaybegin and user.birthday < birthdayend ;

當前,需要對應值不為空,才會拼接相應的and條件。

動態 SQL 匹配查詢 AND OR

在接收前端傳入乙個關鍵字用來匹配資料庫的兩個欄位中的其中乙個的時候,mybatis 可以採用 and or 關鍵字進行查詢 and method like concat or eventcode like concat and statusofread and bizcaseid 傳入字段 stri...

jpa 動態sql拼接 JPA的動態查詢拼接

在使用spring jpa提供的方法只能進行簡單的crud,如果遇到複雜的情況就需要我們動態來構建查詢條件了。這裡我們來看使用criteriabuilder如何來構造查詢。核心 criteriabuilder criteriabuilder entitymanager.getcriteriabuil...

採坑系列之JPA查詢

最近在研究spring的jpa的動態查詢,使用比較方便,但是著實也踩了不少的坑,簡單的總結一下。com.github.wenhao jpa spec 2.2.1 兩個關聯表 user和address 配置 引用lombok依賴便可以利用註解省略setter和getter方法,下面 是兩個關聯表多對多...