精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

QueryDSL 的簡單應用

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-09-25 17:03 ? 次閱讀

今天給大家介紹一個JPA的好搭檔:QueryDSL。

0. 前言

相對于 MyBatis ,本人更喜歡 Spring Data JPA ,因為它更符合面向對象的思想,然而 JPA 對復雜的查詢支持較弱,常見的有兩種方式:

一種方式是Repository繼承JpaSpecificationExecutor接口,優點是支持復雜查詢、編譯期可以規避一些語法錯誤,缺點是語法晦澀難懂,學習成本太高。

還有一種方式就是直接寫 SQL ,可以通過JdbcTemplate或者@Query注解的方式查詢,優點是簡單,缺點嘛...先看段代碼:

@Query(value="select bs.* from " +
            "(select t.baseid,t.basesn,t.basecreatorfullname,t.basestatus,t.basesummary,'北京' faultprovince, '北京' faultcity, " +
            "replace(t.INC_ResponseLevel,'響應','') 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,'否','未預處理','否','是') flagpretreatment,decode(t.flagPretreatment,null,'否','未預處理','否','是') 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 = '傳輸網絡故障處理工單' 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,'響應','') 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,'否','未預處理','否','是') flagpretreatment,decode(t.flagPretreatment,null,'否','未預處理','否','是') 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的缺點。

下面隆重介紹 JPA 的最佳搭檔:QueryDSL。它的語法跟SQL一樣簡單,且代碼清晰,具有代碼提示、編譯期錯誤檢查等優勢。同時,在架構的層次上實現了讀寫分離:JPA負責增刪改、QueryDSL負責查詢。

1. QueryDsl介紹

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

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

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

2. 引入QueryDSL

本文以gradle構建為例,前提是已引入 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. 創建JPA Entity

我們分別創建兩個示例實體類:職員表、部門表。

/**
 * 職員表
 */
@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 會幫助我們會自動生成兩個 Q類 :QEmp、QDep ,我們之后進行的所有查詢都是圍繞這些Q類來進行的。

4. 簡單查詢

QueryDSL提供了一種類似于SQL的面向對象寫法,并且是類型安全的,搭配上IDEA的語句提示功能,寫起SQL來非常舒服。

請欣賞下面的例子:

public void simpleSql() {
    QEmp emp = QEmp.emp;//員工表
    /**
     * 簡單條件查詢、排序,相當于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();

    /**
     * 分組查詢,相當于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();

    /**
     * 分頁查詢,相當于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. 復雜查詢

QueryDSL對于復雜查詢的支持也是相當優秀的,比如多表關聯、動態條件查詢等。

public void complexSql() {
    QEmp emp = QEmp.emp;//員工表
    QDep dep = QDep.dep;//部門表

    /**
     * 關聯查詢,相當于sql:
     * select e.* from T_EMP e
     *  left join T_DEP d on e.dep_id = d.id
     *  where d.dep_name = '財務部'
     */
    List< Emp > empList = queryFactory.select(emp)
            .from(emp)
            .leftJoin(dep).on(emp.depId.eq(dep.id))
            .where(dep.depName.eq("財務部"))
            .fetch();

    /**
     * 嵌套查詢,相當于sql:
     * select e.* from T_EMP e
     *  where e.dep_id = (
     *      select id form T_DEP where dep_name = '財務部'
     *  )
     */
    List< Emp > empList1 = queryFactory.select(emp)
            .from(emp)
            .where(emp.depId.eq(
                    queryFactory.select(dep.id).from(dep)
                            .where(dep.depName.eq("財務部"))
            ))
            .fetch();

    /**
     * 動態條件、別名、獲取不同結果:

     */
    BooleanBuilder condition = new BooleanBuilder();
    condition.and(emp.age.goe(25));
    if (true) {//動態條件
        condition.and(emp.sex.eq("男"));
    }
    queryFactory.select(emp.name.as("fullname"))
            .where(condition)
            .fetch();//查找多個結果,返回集合
          //.fetchOne();//查詢只返回一個結果,如果返回多個則拋異常
          //.fetchFirst();//返回多個結果時,只取第一個
}

小結

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8504

    瀏覽量

    150840
  • SQL
    SQL
    +關注

    關注

    1

    文章

    760

    瀏覽量

    44078
  • 編譯
    +關注

    關注

    0

    文章

    654

    瀏覽量

    32810
收藏 人收藏

    評論

    相關推薦

    簡單介紹MOSFET的原理

    簡單介紹MOSFET的原理
    的頭像 發表于 04-11 19:19 ?4.8w次閱讀
    <b class='flag-5'>簡單</b>介紹MOSFET的原理

    QT串口通信的簡單使用

    QT串口通信是上位機和下位機通信常用的通信方式, 也是學習QT必須學會的基礎知識, 這篇就簡單介紹一下QT串口通信的簡單使用.
    的頭像 發表于 01-15 09:27 ?1829次閱讀
    QT串口通信的<b class='flag-5'>簡單</b>使用

    簡單實用的多點控制開關

    簡單實用的多點控制開關
    發表于 12-16 01:16 ?989次閱讀
    <b class='flag-5'>簡單</b>實用的多點控制開關

    什么是簡單電路?簡述簡單電路的計算步驟?

    什么是簡單電路?簡述簡單電路的計算步驟?僅由串,并聯電阻以及電源所組成的電路,我們稱之為簡單電路。在計算簡單電路時,所有的串并聯電阻可以簡化為一
    發表于 10-04 15:10 ?6390次閱讀
    什么是<b class='flag-5'>簡單</b>電路?簡述<b class='flag-5'>簡單</b>電路的計算步驟?

    簡單整流電路

    簡單整流電路:下面要介紹的簡單整流電路是三倍壓整流電路。
    發表于 05-06 13:44 ?3992次閱讀
    <b class='flag-5'>簡單</b>整流電路

    簡單調節系統

    簡單調節系統 一、 實驗目的1、 熟悉簡單調節系統的組成,結構與原理。2、 通過選定的控制對象來組成相應的調節
    發表于 05-17 10:54 ?1883次閱讀
    <b class='flag-5'>簡單</b>調節系統

    簡單的電機故障修復技巧

    簡單的電機故障修復技巧
    發表于 12-11 09:42 ?576次閱讀

    什么是簡單網絡管理協議(SNMP)

    什么是簡單網絡管理協議(SNMP) SNMP(Simple Network Management Protocol,簡單網絡管理協議)的前身是簡單網關監控協議(SGMP),用來對通信線路進
    發表于 03-20 15:13 ?2354次閱讀

    簡單的AVR編程器

    這個編程器簡單實用,絕對是新手的福利,不僅操作簡單,而且效率高。
    發表于 01-19 17:07 ?6次下載

    簡單的點陣程序

    簡單的點陣程序 包括移動簡單的點陣程序
    發表于 03-14 14:34 ?8次下載

    PID簡單教程

    PID簡單教程 和整定方法 新手學習必備
    發表于 06-14 14:13 ?0次下載

    vc6.0 簡單教程

    vc6.0 簡單教程
    發表于 03-04 17:48 ?8次下載

    簡單&完成

    簡單&完成
    發表于 05-11 09:34 ?0次下載
    <b class='flag-5'>簡單</b>&完成

    Spring認證_什么是Spring GraphQL?

    數據整合 Spring GraphQL 支持使用 Querydsl 通過 Spring Data Querydsl 擴展 來獲取數據。Querydsl 提供了一種靈活但類型安全的方法,通過使用注釋
    的頭像 發表于 08-09 11:31 ?587次閱讀
    Spring認證_什么是Spring GraphQL?

    WINDOWS下ANACONDA的安裝和簡單使用.

    WINDOWS下ANACONDA的安裝和簡單使用.(數字電源技術及其應用 pdf)-WINDOWS下ANACONDA的安裝和簡單使用? ? ? ? ? ? ? ? ?
    發表于 09-18 12:58 ?9次下載
    WINDOWS下ANACONDA的安裝和<b class='flag-5'>簡單</b>使用.