一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

QueryDSL 的簡(jiǎn)單應(yīng)用

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-09-25 17:03 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

0. 前言

相對(duì)于 MyBatis ,本人更喜歡 Spring Data JPA ,因?yàn)樗厦嫦驅(qū)ο蟮乃枷耄欢?JPA 對(duì)復(fù)雜的查詢支持較弱,常見(jiàn)的有兩種方式:

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

還有一種方式就是直接寫(xiě) SQL ,可以通過(guò)JdbcTemplate或者@Query注解的方式查詢,優(yōu)點(diǎn)是簡(jiǎ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);

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

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

1. QueryDsl介紹

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

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

借助 QueryDSL 可以在任何支持的 ORM 框架或者 SQL 平臺(tái)上以一種通用的API方式來(lái)構(gòu)建查詢。目前 QueryDSL 支持的平臺(tái)包括 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í)體類:職員表、部門(mén)表。

/**
 * 職員表
 */
@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;//部門(mén)ID
}

/**
 * 部門(mén)表
 */
@Data
@Entity
@Table(name = "T_DEP")
public class Dep {
    @Id
    private String id;//ID
    @Column
    private String depName;//部門(mén)名稱
}

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

4. 簡(jiǎn)單查詢

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

請(qǐng)欣賞下面的例子:

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

    /**
     * 分頁(yè)查詢,相當(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對(duì)于復(fù)雜查詢的支持也是相當(dāng)優(yōu)秀的,比如多表關(guān)聯(lián)、動(dòng)態(tài)條件查詢等。

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

    /**
     * 關(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();

    /**
     * 動(dòng)態(tài)條件、別名、獲取不同結(jié)果:

     */
    BooleanBuilder condition = new BooleanBuilder();
    condition.and(emp.age.goe(25));
    if (true) {//動(dòng)態(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 的簡(jiǎn)單應(yīng)用,用寫(xiě)SQL的方法來(lái)寫(xiě)代碼,是不是很舒服呢!文中的例子僅僅淺嘗輒止,希望大家可以實(shí)際應(yīng)用一下,后續(xù)我也會(huì)更深入的講解一些 QueryDSL 的高級(jí)用法。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    9001

    瀏覽量

    153734
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    783

    瀏覽量

    45140
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    679

    瀏覽量

    33983
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    QT串口通信的簡(jiǎn)單使用

    QT串口通信是上位機(jī)和下位機(jī)通信常用的通信方式, 也是學(xué)習(xí)QT必須學(xué)會(huì)的基礎(chǔ)知識(shí), 這篇就簡(jiǎn)單介紹一下QT串口通信的簡(jiǎn)單使用.
    的頭像 發(fā)表于 01-15 09:27 ?3332次閱讀
    QT串口通信的<b class='flag-5'>簡(jiǎn)單</b>使用

    簡(jiǎn)單充電器電路

    簡(jiǎn)單充電器電路 簡(jiǎn)單充電器電路圖
    發(fā)表于 07-13 01:22 ?2373次閱讀
    <b class='flag-5'>簡(jiǎn)單</b>充電器電路

    什么是簡(jiǎn)單電路?簡(jiǎn)述簡(jiǎn)單電路的計(jì)算步驟?

    什么是簡(jiǎn)單電路?簡(jiǎn)述簡(jiǎn)單電路的計(jì)算步驟?僅由串,并聯(lián)電阻以及電源所組成的電路,我們稱之為簡(jiǎn)單電路。在計(jì)算簡(jiǎn)單電路時(shí),所有的串并聯(lián)電阻可以簡(jiǎn)化為一
    發(fā)表于 10-04 15:10 ?6768次閱讀
    什么是<b class='flag-5'>簡(jiǎn)單</b>電路?簡(jiǎn)述<b class='flag-5'>簡(jiǎn)單</b>電路的計(jì)算步驟?

    簡(jiǎn)單的反饋放大電路

    簡(jiǎn)單的反饋放大電路
    發(fā)表于 01-12 15:53 ?1478次閱讀
    <b class='flag-5'>簡(jiǎn)單</b>的反饋放大電路

    簡(jiǎn)單整流電路

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

    簡(jiǎn)單調(diào)節(jié)系統(tǒng)

    簡(jiǎn)單調(diào)節(jié)系統(tǒng) 一、 實(shí)驗(yàn)?zāi)康?、 熟悉簡(jiǎn)單調(diào)節(jié)系統(tǒng)的組成,結(jié)構(gòu)與原理。2、 通過(guò)選定的控制對(duì)象來(lái)組成相應(yīng)的調(diào)節(jié)
    發(fā)表于 05-17 10:54 ?2094次閱讀
    <b class='flag-5'>簡(jiǎn)單</b>調(diào)節(jié)系統(tǒng)

    非常簡(jiǎn)單的紅外遙控電路

    非常簡(jiǎn)單的紅外遙控電路 這是一個(gè)完整的遙控系統(tǒng),由一個(gè)簡(jiǎn)單
    發(fā)表于 09-18 14:53 ?4472次閱讀
    非常<b class='flag-5'>簡(jiǎn)單</b>的紅外遙控電路

    什么是簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議(SNMP)

    什么是簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議(SNMP) SNMP(Simple Network Management Protocol,簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議)的前身是簡(jiǎn)單網(wǎng)關(guān)監(jiān)控協(xié)議(SGMP),用來(lái)對(duì)通信線路進(jìn)
    發(fā)表于 03-20 15:13 ?2466次閱讀

    VB語(yǔ)言基礎(chǔ)_簡(jiǎn)單易懂

    VB語(yǔ)言基礎(chǔ)_ 簡(jiǎn)單易懂
    發(fā)表于 12-08 11:26 ?0次下載

    簡(jiǎn)單的AVR編程器

    這個(gè)編程器簡(jiǎn)單實(shí)用,絕對(duì)是新手的福利,不僅操作簡(jiǎn)單,而且效率高。
    發(fā)表于 01-19 17:07 ?6次下載

    簡(jiǎn)單的點(diǎn)陣程序

    簡(jiǎn)單的點(diǎn)陣程序 包括移動(dòng)簡(jiǎn)單的點(diǎn)陣程序
    發(fā)表于 03-14 14:34 ?8次下載

    PID簡(jiǎn)單教程

    PID簡(jiǎn)單教程 和整定方法 新手學(xué)習(xí)必備
    發(fā)表于 06-14 14:13 ?0次下載

    簡(jiǎn)單&完成

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

    Spring認(rèn)證_什么是Spring GraphQL?

    數(shù)據(jù)整合 Spring GraphQL 支持使用 Querydsl 通過(guò) Spring Data Querydsl 擴(kuò)展 來(lái)獲取數(shù)據(jù)。Querydsl 提供了一種靈活但類型安全的方法,通過(guò)使用注釋
    的頭像 發(fā)表于 08-09 11:31 ?818次閱讀
    Spring認(rèn)證_什么是Spring GraphQL?

    WINDOWS下ANACONDA的安裝和簡(jiǎn)單使用.

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