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定義了以下保留標誌符(雖然下面列表中顯示是大寫形式,保留標誌符並不區分大小寫,所以SELECT和select或SelECt等同。)
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類型。
private int eId;
e.eId
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'
標識變量有
e和
p。
p表示任何能夠從一個
User實例中直接訪問的
Phone
路徑表達式
路徑表達式就是一個標識符號緊跟一個訪問操作符(.)再緊跟一個狀態字段或是關聯字段。
ex:
PrivateMessage所屬於的
User的 關係是由
PrivateMessage的關聯關係字段
toUser表示的。
User有一個關聯到
Role的集合關聯字段
roles,還有 一個關聯到
UserIpAddress的字段
userIpAddress。
PrivateMessage User Roles
private User toUser private Role roles private UserIpAddress userIP
*使用導航操作符(.)來遍歷實體對象關係圖
-------------------------------------------------------------------------------------------
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()方法,可用於取得單一個查詢結果.