JPQL語言,即 Java Persistence Query Language 的簡稱。JPQL 是一種和 SQL 非常類似的中間性和對象化查詢語言,它最終會被編譯成針對不同底層數據庫的 SQL 查詢,從而屏蔽不同數據庫的差異。 JPQL語言的語句可以是 select 語句、update 語句或delete語句,它們都通過 Query 接口封裝執行。
1。Query接口封裝了執行數據庫查詢的相關方法。調用 EntityManager 的 createQuery、create NamedQuery 及 createNativeQuery 方法可以獲得查詢對象,進而可調用 Query 接口的相關方法來執行查詢操作。
2。Query接口的主要方法:
int executeUpdate(): 用於執行update或delete語句。 List getResultList() :用於執行select語句並返回結果集實體列表。 Object getSingleResult() 用於執行只返回單個結果實體的select語句。 Query setFirstResult(int startPosition) 用於設置從哪個實體記錄開始返回查詢結果。 Query setMaxResults(int maxResult) 用於設置返回結果實體的最大數。與setFirstResult結合使用可實現分頁查詢。 Query setFlushMode(FlushModeType flushMode) 設置查詢對象的Flush模式。參數可以取2個枚舉值:FlushModeType.AUTO 為自動更新數據庫記錄,FlushMode Type.COMMIT 為直到提交事務時才更新數據庫記錄。setHint(String hintName, Object value) 設置與查詢對象相關的特定供應商參數或提示信息。參數名及其取值需要參考特定 JPA 實現庫提供商的文檔。如果第二個參數無效將拋出IllegalArgumentException異常。 setParameter(int position, Object value) 為查詢語句的指定位置參數賦值。Position 指定參數序號,value 為賦給參數的值。 setParameter(int position, Date d, TemporalType type) 為查詢語句的指定位置參數賦 Date 值。Position 指定參數序號,value 為賦給參數的值,temporalType 取 TemporalType 的枚舉常量,包括 DATE、TIME 及 TIMESTAMP 三個,,用於將 Java 的 Date 型值臨時轉換為數據庫支持的日期時間類型(java.sql.Date、java.sql.Time及java.sql.Timestamp)。setParameter(int position, Calendar c, TemporalType type) 為查詢語句的指定位置參數賦 Calenda r值。position 指定參數序號,value 為賦給參數的值,temporalType 的含義及取舍同前。 setParameter(String name, Object value) 為查詢語句的指定名稱參數賦值。 setParameter(String name, Date d, TemporalType type) 為查詢語句的指定名稱參數賦 Date 值。用法同前。 setParameter(String name, Calendar c, TemporalType type) 為查詢語句的指定名稱參數設置Calendar值。name為參數名,其它同前。該方法調用時如果參數位置或參數名不正確,或者所賦的參數值類型不匹配,將拋出 IllegalArgumentException 異常。
3,其實除了上面這些方法外,JPQL和一般的sql也沒有什么區別了。
SELECT語句:select o from VO o;查詢語句就需要注意幾點,第一,VO值得是這個實體類,還有就是涉及到條件的時候,字段都是vo的屬性,而不是數據表中的字段。
@Test public void testJPQL(){ String sql="select o from User o where id=?1"; Query query=em.createQuery(sql); query.setParameter(1, 1); List<User> users=query.getResultList(); for(User u:users){ System.out.println(u.getName()); } }
WHERE:
where子句用於指定查詢條件,where跟條件表達式。例: select o from Orders o where o.id = 1 select o from Orders o where o.id > 3 and o.confirm = 'true' select o from Orders o where o.address.streetNumber >= 123 JPQL也支持包含參數的查詢,例如: select o from Orders o where o.id = :myId select o from Orders o where o.id = :myId and o.customer = :customerName 注意:參數名前必須冠以冒號(:),執行查詢前須使用Query.setParameter(name, value)方法給參數賦值
也可以不使用參數名而使用參數的序號,例如: select o from Order o where o.id = ?1 and o.customer = ?2 其中 ?1 代表第一個參數,?2 代表第一個參數。在執行查詢之前需要使用重載方法Query.setParameter(pos, value) 提供參數值。 Query query = entityManager.createQuery( "select o from Orders o where o.id = ?1 and o.customer = ?2" ); query.setParameter( 1, 2 ); query.setParameter( 2, "John" ); List orders = query.getResultList(); … …
where條件表達式中可用的運算符基本上與SQL一致,包括: 算術運算符:+ - * / +(正) -(負) 關系運算符:== <> > >= < <= between…and like in is null 等 邏輯運算符: and or not
下面是一些常見查詢表達式示例: // 以下語句查詢 Id 介於 100 至 200 之間的訂單。 select o from Orders o where o.id between 100 and 200 // 以下語句查詢國籍為的 'US'、'CN'或'JP' 的客戶。 select c from Customers c where c.county in ('US','CN','JP') // 以下語句查詢手機號以139開頭的客戶。%表示任意多個字符序列,包括0個。 select c from Customers c where c.phone like '139%' // 以下語句查詢名字包含4個字符,且234位為ose的客戶。_表示任意單個字符。 select c from Customers c where c.lname like '_ose' // 以下語句查詢電話號碼未知的客戶。Nul l用於測試單值是否為空。 select c from Customers c where c.phone is null // 以下語句查詢尚未輸入訂單項的訂單。empty用於測試集合是否為空。 select o from Orders o where o.orderItems is empty
查詢部分屬性:
如果只須查詢實體的部分屬性而不需要返回整個實體。例如: select o.id, o.customerName, o.address.streetNumber from Order o order by o.id 執行該查詢返回的不再是Orders實體集合,而是一個對象數組的集合(Object[]),集合的每個成員為一個對象數組,可通過數組元素訪問各個屬性。
/**
* 使用查詢緩存
*/
String sql="select 0 from User o";
Query query=em.createQuery(sql);
query.setHint(QueryHints.CACHEABLE, false);
order by子句:order by子句用於對查詢結果集進行排序。和SQL的用法類似,可以用 “asc“ 和 "desc“ 指定升降序。如果不顯式注明,默認為升序。 select o from Orders o order by o.id select o from Orders o order by o.address.streetNumber desc select o from Orders o order by o.customer asc, o.id desc
group by子句與聚合查詢:group by 子句用於對查詢結果分組統計,通常需要使用聚合函數。常用的聚合函數主要有 AVG、SUM、COUNT、MAX、MIN 等,它們的含義與SQL相同。例如: select max(o.id) from Orders o 沒有 group by 子句的查詢是基於整個實體類的,使用聚合函數將返回單個結果值,可以使用Query.getSingleResult()得到查詢結果。例如: Query query = entityManager.createQuery( "select max(o.id) from Orders o"); Object result = query.getSingleResult(); Long max = (Long)result; … …
having子句:Having 子句用於對 group by 分組設置約束條件,用法與where 子句基本相同,不同是 where 子句作用於基表或視圖,以便從中選擇滿足條件的記錄;having 子句則作用於分組,用於選擇滿足條件的組,其條件表達式中通常會使用聚合函數。 例如,以下語句用於查詢訂購總數大於100的商家所售商品及數量: select o.seller, o.goodId, sum(o.amount) from V_Orders o group by o.seller, o.goodId having sum(o.amount) > 100 having子句與where子句一樣都可以使用參數.
關聯查詢:在JPQL中,很多時候都是通過在實體類中配置實體關聯的類屬性來實現隱含的關聯(join)查詢。例如: select o from Orders o where o.address.streetNumber=2000 上述JPQL語句編譯成以下SQL時就會自動包含關聯,默認為左關聯。 在某些情況下可能仍然需要對關聯做精確的控制。為此,JPQL 也支持和 SQL 中類似的關聯語法。如: left out join / left join inner join left join / inner join fetch 其中,left join和left out join等義,都是允許符合條件的右邊表達式中的實體為空。
子查詢:JPQL也支持子查詢,在 where 或 having 子句中可以包含另一個查詢。當子查詢返回多於 1 個結果集時,它常出現在 any、all、exist s表達式中用於集合匹配查詢。它們的用法與SQL語句基本相同.
JPQL函數:JPQL提供了以下一些內建函數,包括字符串處理函數、算術函數和日期函數。 字符串處理函數主要有: concat(String s1, String s2):字符串合並/連接函數。 substring(String s, int start, int length):取字串函數。 trim([leading|trailing|both,] [char c,] String s):從字符串中去掉首/尾指定的字符或空格。 lower(String s):將字符串轉換成小寫形式。 upper(String s):將字符串轉換成大寫形式。 length(String s):求字符串的長度。 locate(String s1, String s2[, int start]):從第一個字符串中查找第二個字符串(子串)出現的位置。若未找到則返回0。算術函數主要有 abs、mod、sqrt、size 等。Size 用於求集合的元素個數。 日期函數主要為三個,即 current_date、current_time、current_timestamp,它們不需要參數,返回服務器上的當前日期、時間和時戳
update語句:update語句用於執行數據更新操作。主要用於針對單個實體類的批量更新 以下語句將帳戶余額不足萬元的客戶狀態設置為未償付: update Customers c set c.status = '未償付' where c.balance < 10000
delete語句:delete語句用於執行數據更新操作。 以下語句刪除不活躍的、沒有訂單的客戶: delete from Customers c where c.status = 'inactive' and c.orders is empty