jpql

    

JPQL


JPQL是一種與資料庫無關的(沒有直接對資料庫做查詢),基本實體(entity-based)的查詢語言。


JPQL支持projection(可以查詢某個實體的字段而不需要查詢整個實體),批量操作(update

和delete),子查詢,join,group by 和having操作。


JPQL就是一種查詢語言,具有與SQL 相類似的特徵,JPQL是完全面向物件 的,具備繼承、多態和關聯等特性。


所有的JPQL操作都在靜態查詢(命名查 詢,named query)和動態查詢中得到支持。


JPQL在語法上與SQL相似

SELECT 語法結構由幾個部份組成:
SELECT 子句 FROM 字句 [WHERE 子句] [GROUP BY 子句] [HAVING 子句] [ORDER BY 子句]

JPQL 所提供的查詢語法主要分為三類:
  • 查詢用的 SELECT 語法
  • 更新用的 UPDATE 語法
  • 刪除用的 DELETE 語法

JPQL查詢不區分大小寫

保留標誌符

JPA定義了以下保留標誌符(雖然下面列表中顯示是大寫形式,保留標誌符並不區分大小寫,所以SELECTselectSelECt等同。)

 

SELECT, FROM, WHERE, UPDATE, DELETE, JOIN, OUTER, INNER, LEFT, GROUP,
BY, HAVING, FETCH, DISTINCT, OBJECT, NULL, TRUE, FALSE, NOT, AND, OR,
BETWEEN, LIKE, IN, AS, UNKNOWN, EMPTY, MEMBER, OF, IS, AVG, MAX, MIN,
SUM, COUNT, ORDER, BY, ASC, DESC, MOD, UPPER, LOWER, TRIM, POSITION,
CHARACTER_LENGTH, CHAR_LENGTH, BIT_LENGTH, CURRENT_TIME, CURRENT_DATE,
CURRENT_TIMESTAMP, NEW, EXISTS, ALL, ANY, SOME.
UNKNOWN目前在JPQL中 還沒有用到。

JPQL是一種強類型語言,一個JPQL語句中每個表達式都有類型。
EX:
SELECT e.eId FROM Employee e

在這個查詢語句中,e.eId一個表達式的結果是一個String類型。


  • 狀態字段(state-field):這種類型包括一個實體不代表關聯關係的任何字段或屬性。字段的類型或者一個屬性get方法的返回結果決定了狀態字段。

       private int eId;
       e.eId
  • 關聯字段(association-field):這種類型包括了一個實體中任何表示關聯關係的字段或屬性。 

      private Department depart;

      e.depart


實體的名稱就是你使用@Entity註釋時指定的名稱

@Entity(name="message")

實體的限定詞 (unqualified name)。


@Entity
public class User{

實體名稱是「 message 」, 因為你在使用@Entity時候指定了名稱(在一個持久化單元內實體名稱必須是唯一的)。
實體的限定詞是User(以一個大寫的「U」開頭)。

SELECT u FROM User u
一個標識變量(identification variable)是一個在FROM語句中指定的一個標誌符號。
u就是一個標識變量。
u
類型就是能夠識別名稱User的實體
所以u的類型是User

標識變量也可以使用JOIN關鍵字定義

 

SELECT p.number FROM Employee e,Phome p
WHERE e=p.employee AND e.department.name='NA42' AND p.type='Cell'
 
SELECT p.number FROM Employee e JOIN e.phome p
WHERE e.department.name=' NA42' AND p.type='Cell'

標識變量有epp表示任何能夠從一個User實例中直接訪問的Phone


路徑表達式

路徑表達式就是一個標識符號緊跟一個訪問操作符(.)再緊跟一個狀態字段或是關聯字段。


ex:
PrivateMessage所屬於的User的 關係是由PrivateMessage的關聯關係字段toUser表示的。
User
有一個關聯到Role的集合關聯字段roles,還有 一個關聯到UserIpAddress的字段userIpAddress
 

PrivateMessage           User                        Roles
private User toUser      private Role roles      private UserIpAddress userIP

  • PrivateMessage所屬用戶User的 IP地址UserIpAddresses

    SELECT p.toUser.userIP from PrivateMessage p

*使用導航操作符(.)來遍歷實體對象關係圖

-------------------------------------------------------------------------------------------
JPQL支持的聚合函數包括:
1. AVG()
2. SUM()
3. COUNT()返回類型為Long
4. MAX()
5. MIN()

EX:SELECT max(p.age) FROM Person p

排序
"ASC""DESC"分別為升序和降序,JPQL中默認為asc升序

PQL語句支持兩種方式的參數定義方式: 命名參數和位置參數
命令參數的格式為:「: +參數名稱」
例:
Query query = em.createQuery("select p from Person p where p.personid=:Id");
query.setParameter("Id",new Integer(1));
 
位置參數的格式為「?+位置編號」
例:
Query query = em.createQuery("select p from Person p where p.personid=?3");
query.setParameter(3,new Integer());
------------------------------------------------------------------------------------------
//查找年齡為26,21 Person
select p from Person as p where p.age in(26,21)
300~1000之間
select o from Order as o where o.amount between 300 and 1000

-------------------------------------------------------------------------------------------
批量更新(Batch Update)

例:
//把所有訂單的金額加10
Query query = em.createQuery("update Order as o set o.amount=o.amount+10");
//update 的記錄數
int result = query.executeUpdate();
 
 
批量刪除(Batch Remove)
DELETE來刪除資料,例如:
DELETE User u WHERE u.name='bush
--------------------------------------------------------------------------------------------
命名查詢
可以在實體bean通過@NamedQuery or @NamedQueries預先定義一個或多個查詢語句,減少每次因撰寫錯誤
通常把經常使用的查詢語句定義成命名查詢
 
定義單個命名查詢:
@NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1")
@Entity
public class Person implements Serializable{
 
如果要定義多個命名查詢,應在 @javax.persistence.NamedQueries裡定義@NamedQuery
@NamedQueries({
@NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1"),
@NamedQuery(name="getPersonList", query= "FROM Person WHERE age>?1")
})
@Entity
public class Person implements Serializable{
 
當命名查詢定義好了之後,我們就可以通過名稱執行其查詢。代碼如下:
Query query = em.createNamedQuery("getPerson");
query.setParameter(1, 1);
----------------------------------------------------------------------------------------------
透過EntityManager的createQuery()搭配JPQL語句來建立Query物件,是指定為select語句,若要取得查詢結果
則是透過Query的getResultList()方法來取回,該方法傳回List物件,當中每個物件皆已將表格的資訊封裝為User實例。

要指定位置參數的值,則指定位置參數的 數字,如範例中的setParameter()方法,在這邊也示範了Query的getSingleResult()方法,可用於取得單一個查詢結果.



Comments