国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

jpa多條件查詢重寫Specification的toPredicate方法

2019-11-09 13:32:41
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

SPRing Data JPA支持JPA2.0的Criteria查詢,相應(yīng)的接口是JpaspecificationExecutor。Criteria 查詢:是一種類型安全和更面向?qū)ο蟮牟樵?。

這個(gè)接口基本是圍繞著Specification接口來(lái)定義的, Specification接口中只定義了如下一個(gè)方法:

Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);

要理解這個(gè)方法,以及正確的使用它,就需要對(duì)JPA2.0的Criteria查詢有一個(gè)足夠的熟悉和理解,因?yàn)檫@個(gè)方法的參數(shù)和返回值都是JPA標(biāo)準(zhǔn)里面定義的對(duì)象。

Criteria查詢基本概念

Criteria 查詢是以元模型的概念為基礎(chǔ)的,元模型是為具體持久化單元的受管實(shí)體定義的,這些實(shí)體可以是實(shí)體類,嵌入類或者映射的父類。

CriteriaQuery接口:代表一個(gè)specific的頂層查詢對(duì)象,它包含著查詢的各個(gè)部分,比如:select 、from、where、group by、order by等注意:CriteriaQuery對(duì)象只對(duì)實(shí)體類型或嵌入式類型的Criteria查詢起作用 Root接口:代表Criteria查詢的根對(duì)象,Criteria查詢的查詢根定義了實(shí)體類型,能為將來(lái)導(dǎo)航獲得想要的結(jié)果,它與SQL查詢中的FROM子句類似

1:Root實(shí)例是類型化的,且定義了查詢的FROM子句中能夠出現(xiàn)的類型。

2:查詢根實(shí)例能通過(guò)傳入一個(gè)實(shí)體類型給 AbstractQuery.from方法獲得。

3:Criteria查詢,可以有多個(gè)查詢根。

4:AbstractQuery是CriteriaQuery 接口的父類,它提供得到查詢根的方法。CriteriaBuilder接口:用來(lái)構(gòu)建CritiaQuery的構(gòu)建器對(duì)象Predicate:一個(gè)簡(jiǎn)單或復(fù)雜的謂詞類型,其實(shí)就相當(dāng)于條件或者是條件組合。

Criteria查詢基本對(duì)象的構(gòu)建

1:通過(guò)EntityManager的getCriteriaBuilder或EntityManagerFactory的getCriteriaBuilder方法可以得到CriteriaBuilder對(duì)象2:通過(guò)調(diào)用CriteriaBuilder的createQuery或createTupleQuery方法可以獲得CriteriaQuery的實(shí)例

3:通過(guò)調(diào)用CriteriaQuery的from方法可以獲得Root實(shí)例過(guò)濾條件

A:過(guò)濾條件會(huì)被應(yīng)用到SQL語(yǔ)句的FROM子句中。在criteria 查詢中,查詢條件通過(guò)Predicate或Expression實(shí)例應(yīng)用到CriteriaQuery對(duì)象上。B:這些條件使用 CriteriaQuery .where 方法應(yīng)用到CriteriaQuery 對(duì)象上C:CriteriaBuilder也作為Predicate實(shí)例的工廠,通過(guò)調(diào)用CriteriaBuilder 的條件方( equal,notEqual, gt, ge,lt, le,between,like等)創(chuàng)建Predicate對(duì)象。D:復(fù)合的Predicate 語(yǔ)句可以使用CriteriaBuilder的and, or andnot 方法構(gòu)建。 構(gòu)建簡(jiǎn)單的Predicate示例: Predicate p1=cb.like(root.get(“name”).as(String.class), “%”+uqm.getName()+“%”); Predicate p2=cb.equal(root.get("uuid").as(Integer.class), uqm.getUuid()); Predicate p3=cb.gt(root.get("age").as(Integer.class), uqm.getAge()); 構(gòu)建組合的Predicate示例: Predicate p = cb.and(p3,cb.or(p1,p2));

下面我們用兩個(gè)示例代碼來(lái)更深入的了解:

1.復(fù)雜條件多表查詢//需要查詢的對(duì)象public class Qfjbxxdz { @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid.hex") private String id; @OneToOne @JoinColumn(name = "qfjbxx") private Qfjbxx qfjbxx; //關(guān)聯(lián)表 private String fzcc; private String fzccName; @ManyToOne @JoinColumn(name = "criminalInfo") private CriminalInfo criminalInfo;//關(guān)聯(lián)表 @Column(length=800) private String bz; //get/set......}//創(chuàng)建構(gòu)造Specification的方法//這里我傳入兩個(gè)條件參數(shù)因?yàn)榕c前段框架有關(guān),你們寫的時(shí)候具體自己業(yè)務(wù)自行決斷private Specification<Qfjbxxdz> getWhereClause(final JSONArray condetion,final JSONArray search) { return new Specification<Qfjbxxdz>() { @Override public Predicate toPredicate(Root<Qfjbxxdz> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicate = new ArrayList<>(); Iterator<JSONObject> iterator = condetion.iterator(); Predicate preP = null; while(iterator.hasNext()){ JSONObject jsonObject = iterator.next(); //注意:這里用的root.join 因?yàn)槲覀円胵fjbxx對(duì)象里的字段作為條件就必須這樣做join方法有很多重載,使用的時(shí)候可以多根據(jù)自己業(yè)務(wù)決斷 Predicate p1 = cb.equal(root.join("qfjbxx").get("id").as(String.class),jsonObject.get("fzId").toString()); Predicate p2 = cb.equal(root.get("fzcc").as(String.class),jsonObject.get("ccId").toString()); if(preP!=null){ preP = cb.or(preP,cb.and(p1,p2)); }else{ preP = cb.and(p1,p2); } } JSONObject jsonSearch=(JSONObject) search.get(0); Predicate p3=null; if(null!=jsonSearch.get("xm")&&jsonSearch.get("xm").toString().length()>0){ p3=cb.like(root.join("criminalInfo").get("xm").as(String.class),"%"+jsonSearch.get("xm").toString()+"%"); } Predicate p4=null; if(null!=jsonSearch.get("fzmc")&&jsonSearch.get("fzmc").toString().length()>0){ p4=cb.like(root.join("qfjbxx").get("fzmc").as(String.class),"%"+jsonSearch.get("fzmc").toString()+"%"); } Predicate preA; if(null!=p3&&null!=p4){ Predicate preS =cb.and(p3,p4); preA =cb.and(preP,preS); }else if(null==p3&&null!=p4){ preA=cb.and(preP,p4); }else if(null!=p3&&null==p4){ preA=cb.and(preP,p3); }else{ preA=preP; } predicate.add(preA); Predicate[] pre = new Predicate[predicate.size()]; query.where(predicate.toArray(pre)); return query.getRestriction(); }

編寫DAO類或接口 dao類/接口 需繼承

public interface JpaSpecificationExecutor<T>

接口; 如果需要分頁(yè),還可繼承

public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID>

JpaSpecificationExecutor 接口具有方法

Page<T> findAll(Specification<T> spec, Pageable pageable); //分頁(yè)按條件查詢 List<T> findAll(Specification<T> spec); //不分頁(yè)按條件查詢

方法。 我們可以在Service層調(diào)用這兩個(gè)方法。 兩個(gè)方法都具有 Specification spec 參數(shù),用于設(shè)定查詢條件。 Service 分頁(yè)+多條件查詢 調(diào)用示例:

studentInfoDao.findAll(new Specification<StudentInfo> () { public Predicate toPredicate(Root<StudentInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Path<String> namePath = root.get("name"); Path<String> nicknamePath = root.get("nickname"); /** * 連接查詢條件, 不定參數(shù),可以連接0..N個(gè)查詢條件 */ query.where(cb.like(namePath, "%李%"), cb.like(nicknamePath, "%王%")); //這里可以設(shè)置任意條查詢條件 return null; } }, page); }

這里通過(guò)CriteriaBuilder 的like方法創(chuàng)建了兩個(gè)查詢條件, 姓名(name)字段必須包含“李”, 昵稱(nickname)字段必須包含“王”。 然后通過(guò) 連接多個(gè)查詢條件即可。 這種方式使用JPA的API設(shè)置了查詢條件,所以不需要再返回查詢條件Predicate給Spring Data Jpa,故最后return null;即可。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 滕州市| 五原县| 溧水县| 花垣县| 临湘市| 乡宁县| 资溪县| 逊克县| 太谷县| 宜都市| 潼南县| 南安市| 屯门区| 兴海县| 平山县| 吕梁市| 河曲县| 玉溪市| 临汾市| 繁昌县| 资源县| 西平县| 南澳县| 星座| 聂拉木县| 深泽县| 淮滨县| 马公市| 满洲里市| 宜章县| 石阡县| 小金县| 新邵县| 遂昌县| 景德镇市| 桐城市| 尉氏县| 南宫市| 固阳县| 临清市| 林甸县|