欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于jpa?querydsl嵌套查詢demo

 更新時(shí)間:2024年05月07日 09:26:58   作者:字母拼裝師  
這篇文章主要介紹了關(guān)于jpa?querydsl?嵌套查詢demo,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

jpa querydsl 嵌套查詢demo

用于進(jìn)行嵌套查詢,查詢一對多,取多的時(shí)間最新的一條記錄。

		// 創(chuàng)建兩個(gè)查詢器
		BlazeJPAQuery<Tuple> jpaQueryHandle = new BlazeJPAQuery<Tuple>(em, cbf);
        BlazeJPAQuery<Tuple> jpaQuery = new BlazeJPAQuery<Tuple>(em, cbf);
		
        QAbnormalRelease qAbnormalRelease = QAbnormalRelease.abnormalRelease;
        QAbnormalReleaseHandle qAbnormalReleaseHandle = QAbnormalReleaseHandle.abnormalReleaseHandle;
        // 更改此別名,同一條sql只允許有一個(gè)別名存在,防止和上面的默認(rèn)別名重復(fù)報(bào)sql別名異常
        QAbnormalReleaseHandle qAbnormalReleaseHandleNow = new QAbnormalReleaseHandle("qAbnormalReleaseHandleNow");
        jpaQuery.select(qAbnormalRelease, qAbnormalReleaseHandle)
                .from(qAbnormalRelease)
                .leftJoin(qAbnormalReleaseHandle).on(qAbnormalReleaseHandle.abnormalReleaseId.eq(qAbnormalRelease.id));
        // 關(guān)聯(lián)查詢,獲取當(dāng)前異常的最新一條處理記錄,后續(xù)還需要關(guān)聯(lián)用戶表
        jpaQuery.where(qAbnormalReleaseHandle.createDate.eq(
        		// 在這里使用更正的別名,查詢出一對多的多條記錄取最新的一條
                jpaQueryHandle.select(qAbnormalReleaseHandleNow.createDate.max()).from(qAbnormalReleaseHandleNow) 
                        .where(qAbnormalReleaseHandleNow.abnormalReleaseId.eq(qAbnormalRelease.id))
        ));

JPA的好搭檔-QueryDSL

相對于 MyBatis ,本人更喜歡 Spring Data JPA ,因?yàn)樗厦嫦驅(qū)ο蟮乃枷?,然?JPA 對復(fù)雜的查詢支持較弱

常見的有兩種方式:

一種方式是Repository繼承JpaSpecificationExecutor接口,優(yōu)點(diǎn)是支持復(fù)雜查詢、編譯期可以規(guī)避一些語法錯(cuò)誤,缺點(diǎn)是語法晦澀難懂,學(xué)習(xí)成本太高。

還有一種方式就是直接寫 SQL ,可以通過JdbcTemplate或者@Query注解的方式查詢,優(yōu)點(diǎn)是簡單,缺點(diǎn)嘛...

先看段代碼:

@Query(value="select bs.* from " +
            "(select t.baseid,t.basesn,t.basecreatorfullname,t.basestatus,t.basesummary,'北京' faultprovince, '北京' faultcity, " +
            "replace(t.INC_ResponseLevel,'響應(yīng)','') inc_responselevel,t.inc_happentime,t.basecreatedate,t.inc_equipmentmanufacturer, " +
            "t.inc_ne_name,t.inc_alarm_id,t.site_alerttype,t.alarmlevel,t.inc_alarm_desc,t.baseacceptouttime,t.basedealouttime, " +
            "decode(t.flagPretreatment,null,'否','未預(yù)處理','否','是') flagpretreatment,decode(t.flagPretreatment,null,'否','未預(yù)處理','否','是') flagpretreatment2, " +
            "decode(nvl(t.isImportantIncident, 0),1,'是','否') isimportantincident, decode(nvl(t.INC_IsEffectOP, 0),1,'是','否') inc_iseffectop, " +
            "t.operationdeal, t.t0_deal,t.faultdescription,t.dealguomodo,t.inc_alarm_cleartime,t.clearinctime, " +
            "t.renewtime,t.baseclosedate,nvl2(t.checkdealresult,'是','否') checkdealresult,g.jtitem1,g.jtitem2,g.jtitem3,t.reasontype " +
            "from T_DEMO t, T_DEMO_MAP g " +
            "where t.Sheet_type = '傳輸網(wǎng)絡(luò)故障處理工單' and t.basestatus = '已歸檔' " +
            "and t.baseCloseDate >= :beginTime and t.baseCloseDate < :endTime " +
            "and (t.Withdraw_Desc = g.withdraw_desc or t.alarmname = g.alarmname) " +
            "union all " +
            "select t.baseid,t.basesn,t.basecreatorfullname,t.basestatus,t.basesummary,'北京' faultprovince, '北京' faultcity, " +
            "replace(t.INC_ResponseLevel,'響應(yīng)','') inc_responselevel,t.inc_happentime,t.basecreatedate,t.inc_equipmentmanufacturer, " +
            "t.inc_ne_name,t.inc_alarm_id,t.site_alerttype,t.alarmlevel,t.inc_alarm_desc,t.baseacceptouttime,t.basedealouttime, " +
            "decode(t.flagPretreatment,null,'否','未預(yù)處理','否','是') flagpretreatment,decode(t.flagPretreatment,null,'否','未預(yù)處理','否','是') flagpretreatment2, " +
            "decode(nvl(t.isImportantIncident, 0),1,'是','否') isimportantincident, decode(nvl(t.INC_IsEffectOP, 0),1,'是','否') inc_iseffectop, " +
            "t.operationdeal,t.t0_deal,t.faultdescription,t.dealguomodo,t.inc_alarm_cleartime,t.clearinctime, " +
            "t.renewtime,t.baseclosedate,nvl2(t.checkdealresult,'是','否') checkdealresult,w.jtitem1,w.jtitem2,w.jtitem3,t.reasontype " +
            "from WF_BMCC_EOMS_ITDealFault t, (select distinct c.value,c.jtitem1,c.jtitem2,c.jtitem3 from WF_Config_EL_00_NetType c) w " +
            "where (t.Sheet_type = 'test0' or t.Sheet_type = 'test1' or t.Sheet_type = 'test2' " +
            "or t.Sheet_type = 'test3' or t.Sheet_type = 'test4') and t.basestatus = '已歸檔' " +
            "and t.baseCloseDate >= :beginTime and t.baseCloseDate < :endTime " +
            "and t.faultclass = w.value "+
            "  ) bs " +
            "where not exists (select dp.processbaseid from T_DEAL dp,T_GROUPS dg where dp.ProcessBaseSchema = " +
            "'DEALFAULT' and dp.processbaseid = bs.baseid and dp.groupid = dg.groupid) ",
            nativeQuery=true)
    List<DemoEntity> findOne(@Param("beginTime") long beginTime, @Param("endTime") long endTime);

看著想吐,就是直接寫SQL的缺點(diǎn)。

下面隆重介紹 JPA 的最佳搭檔:QueryDSL。它的語法跟SQL一樣簡單,且代碼清晰,具有代碼提示、編譯期錯(cuò)誤檢查等優(yōu)勢。同時(shí),在架構(gòu)的層次上實(shí)現(xiàn)了讀寫分離:JPA負(fù)責(zé)增刪改、QueryDSL負(fù)責(zé)查詢。

1. QueryDsl介紹

QueryDSL 是一個(gè)通用的查詢框架,專注于通過 Java API 構(gòu)建類型安全的SQL查詢。

QueryDSL 可以通過一組通用的查詢 API 為用戶構(gòu)建出適合不同類型ORM框架或者是 SQL 的查詢語句,也就是說 QueryDSL 是基于各種 ORM 框架以及 SQL 之上的一個(gè)通用的查詢框架。

借助 QueryDSL 可以在任何支持的 ORM 框架或者 SQL 平臺上以一種通用的API方式來構(gòu)建查詢。目前 QueryDSL 支持的平臺包括 JPA、JDO、SQL、Mongodb 等等。

2. 引入QueryDSL

本文以gradle構(gòu)建為例,前提是已引入 Spring Data Jpa ,且JPA可正常使用。

implementation 'com.querydsl:querydsl-jpa'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'

引入JPAQueryFactory

@Service
public class DemoQueryDSL {
    @Autowired
    private JPAQueryFactory queryFactory;
}

3. 創(chuàng)建JPA Entity

我們分別創(chuàng)建兩個(gè)示例實(shí)體類:職員表、部門表。

/**
 * 職員表
 */
@Data
@Entity
@Table(name = "T_EMP")
public class Emp {
    @Id
    private String id;//ID
    @Column
    private String name;//姓名
    @Column
    private Integer age;//年齡
    @Column
    private String sex;//性別
    @Column
    private String depId;//部門ID
}
 
/**
 * 部門表
 */
@Data
@Entity
@Table(name = "T_DEP")
public class Dep {
    @Id
    private String id;//ID
    @Column
    private String depName;//部門名稱
}

編譯后,QueryDSL 會幫助我們會自動生成兩個(gè)Q類:QEmp、QDep ,我們之后進(jìn)行的所有查詢都是圍繞這些Q類來進(jìn)行的。

4. 簡單查詢

QueryDSL提供了一種類似于SQL的面向?qū)ο髮懛?,并且是類型安全的,搭配上IDEA的語句提示功能,寫起SQL來非常舒服。

請欣賞下面的例子:

public void simpleSql() {
    QEmp emp = QEmp.emp;//員工表
    /**
     * 簡單條件查詢、排序,相當(dāng)于sql:
     * select * from T_EMP
     *  where name like '張%' and age > 25
     *  order by age desc;
     */
    List<Emp> empList = queryFactory.select(emp)
            .where(emp.name.startsWith("張").and(emp.age.gt(25)))
            .orderBy(emp.age.desc())
            .fetch();
 
    /**
     * 分組查詢,相當(dāng)于sql:
     * select e.dep_id, max(e.age) from T_EMP e
     *  grouping by e.depId;
     */
    List<Tuple> list = queryFactory.select(emp.depId, emp.age.max())
            .groupBy(emp.depId)
            .fetch();
 
    /**
     * 分頁查詢,相當(dāng)于sql:
     * select * from T_EMP e
     *  where e.dep_id='123'
     *  limit 20 10;
     */
    List<Emp> pageList = queryFactory.select(emp)
            .where(emp.depId.eq("123"))
            .offset(20)
            .limit(10)
            .fetch();
}

5. 復(fù)雜查詢

QueryDSL對于復(fù)雜查詢的支持也是相當(dāng)優(yōu)秀的,比如多表關(guān)聯(lián)、動態(tài)條件查詢等。

public void complexSql() {
    QEmp emp = QEmp.emp;//員工表
    QDep dep = QDep.dep;//部門表
 
    /**
     * 關(guān)聯(lián)查詢,相當(dāng)于sql:
     * select e.* from T_EMP e
     *  left join T_DEP d on e.dep_id = d.id
     *  where d.dep_name = '財(cái)務(wù)部'
     */
    List<Emp> empList = queryFactory.select(emp)
            .from(emp)
            .leftJoin(dep).on(emp.depId.eq(dep.id))
            .where(dep.depName.eq("財(cái)務(wù)部"))
            .fetch();
 
    /**
     * 嵌套查詢,相當(dāng)于sql:
     * select e.* from T_EMP e
     *  where e.dep_id = (
     *      select id form T_DEP where dep_name = '財(cái)務(wù)部'
     *  )
     */
    List<Emp> empList1 = queryFactory.select(emp)
            .from(emp)
            .where(emp.depId.eq(
                    queryFactory.select(dep.id).from(dep)
                            .where(dep.depName.eq("財(cái)務(wù)部"))
            ))
            .fetch();
 
    /**
     * 動態(tài)條件、別名、獲取不同結(jié)果:
     */
    BooleanBuilder condition = new BooleanBuilder();
    condition.and(emp.age.goe(25));
    if (true) {//動態(tài)條件
        condition.and(emp.sex.eq("男"));
    }
    queryFactory.select(emp.name.as("fullname"))
            .where(condition)
            .fetch();//查找多個(gè)結(jié)果,返回集合
          //.fetchOne();//查詢只返回一個(gè)結(jié)果,如果返回多個(gè)則拋異常
          //.fetchFirst();//返回多個(gè)結(jié)果時(shí),只取第一個(gè)
}

總結(jié)

以上就是 QueryDSL 的簡單應(yīng)用,用寫SQL的方法來寫代碼,是不是很舒服呢!文中的例子僅僅淺嘗輒止,大家可以實(shí)際應(yīng)用一下,后續(xù)我也會更深入的講解一些 QueryDSL 的高級用法。

這些僅為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Centos7.3下jre1.8安裝和配置教程

    Centos7.3下jre1.8安裝和配置教程

    這篇文章主要為大家詳細(xì)介紹了Centos7.3下jre1.8安裝和配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • MyBatis在DAO層定義接口返回類型泛型無效的解決

    MyBatis在DAO層定義接口返回類型泛型無效的解決

    這篇文章主要介紹了MyBatis在DAO層定義接口返回類型泛型無效的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java中Object類4種方法詳細(xì)介紹

    java中Object類4種方法詳細(xì)介紹

    大家好,本篇文章主要講的是java中Object類4種方法詳細(xì)介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • Java 類型相互轉(zhuǎn)換byte[]類型,Blob類型詳細(xì)介紹

    Java 類型相互轉(zhuǎn)換byte[]類型,Blob類型詳細(xì)介紹

    這篇文章主要介紹了Java 類型相互轉(zhuǎn)換byte[]類型,Blob類型的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • java無限遞歸遍歷json對象問題

    java無限遞歸遍歷json對象問題

    這篇文章主要介紹了java無限遞歸遍歷json對象問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 淺談Mybatis二級緩存的缺陷

    淺談Mybatis二級緩存的缺陷

    本文主要介紹了淺談Mybatis二級緩存的缺陷,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java二維數(shù)組查找功能代碼實(shí)現(xiàn)

    Java二維數(shù)組查找功能代碼實(shí)現(xiàn)

    這篇文章主要介紹了Java二維數(shù)組查找功能代碼實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • java的url方式、本地方式獲取json文件內(nèi)容

    java的url方式、本地方式獲取json文件內(nèi)容

    這篇文章給大家分享了java的url方式、本地方式獲取json文件內(nèi)容的實(shí)例代碼,有需要的朋友參考學(xué)習(xí)下。
    2018-07-07
  • 淺談java線程join方法使用方法

    淺談java線程join方法使用方法

    這篇文章主要介紹了淺談java線程join方法使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • java收集器Collector案例匯總

    java收集器Collector案例匯總

    這篇文章主要介紹了java收集器Collector案例匯總,Collectors作為Stream的collect方法的參數(shù),Collector是一個(gè)接口,它是一個(gè)可變的匯聚操作,更多相關(guān)介紹,需要的朋友可以參考下
    2022-06-06

最新評論