国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

JPA之使用JPQL語句進行增刪改查

2024-07-13 10:15:34
字體:
來源:轉載
供稿:網友

JPA支持兩種表達查詢的方法來檢索實體和來自數據庫的其他持久化數據:查詢語句(Java Persistence Query Language,JPQL)和條件API(criteria API)。JPQL是獨立于數據庫的查詢語句,其用于操作邏輯上的實體模型而非物理的數據模型。條件API是根據實體模型構建查詢條件

1.Java持久化查詢語句入門

 

復制代碼 代碼如下:
List<Person> persons= entityManager.createQuery("select p from Person p").getResultList();

 

1.這個查詢語句類似于SQL。但它與真正的SQL的區別是,它不是從一個表中進行選擇查詢,而是指定來自應用程序域模型的實體。

2.查詢select子句也只是列出了查詢實體的別名,如果只查詢某一列的,可以使用點(.)操作符進行來導航實體屬性。如下所示:

 

復制代碼 代碼如下:
List<String> persons= entityManager.createQuery("select p.firstName from Person p").getResultList();

 

1.1.篩選條件

像SQL一樣,JPQL也支持where子句,用于對搜索的條件過濾。包括大多數的操作符,如:in,between、like以及函數表達式substring、length等等

 

復制代碼 代碼如下:
List<Person> persons = entityManager.createQuery("select p from Person p where p.age>23").getResultList();

 

1.2.投影結果

對于查詢的數據量比較大的話,可以使用投影的方式,只查詢出有用的列。

 

復制代碼 代碼如下:
//投影List<Object> persons = entityManager.createQuery("select p.firstName,p.age from Person p").getResultList();

 

1.3.聚合查詢

JPQL的聚合查詢語法類似于SQL。例如count

 

復制代碼 代碼如下:
List<Integer> count=entityManager.createQuery("select count(p) from Person p").getResultList();

 

1.4.查詢參數

JPQL支持兩種類型的參數綁定語法。

1.位置參數表示法

其中參數是在查詢字符串中指示,該字符串是在一個問號(?)之后緊隨參數的編號。當執行查詢的時候,開發人員指定應該替換的參數編

Query query=entityManager.createQuery("select p from Person p where p.age=?1 and p.firstName=?2");query.setParameter(1,21);query.setParameter(2,"Jack");

2.命名參數表示法

通過在一個冒號(:)之后緊隨參數名稱,在查詢字符串對它進行指示,當執行查詢的時候,開發人員指定應該替換的參數名稱

Query query=entityManager.createQuery("select p from Person p where p.age=:age and p.firstName=:name");query.setParameter("age",21);query.setParameter("name","Jack");

2.定義查詢

JPA提供Query和TypedQuery(JPA 2.0引入)接口來配置和執行查詢。Query的返回的Object類型,而TypedQuery返回的是指定的Class類型。

//未指定類型,返回Object類型Query q = entityManager.createQuery("select p from Person p");//指定返回類型為Person類型TypedQuery<Person> q1 = entityManager.createQuery("select p from Person p", Person.class);

2.1.動態查詢定義

JPA查詢引擎,可以將JPQL字符串解析成語法樹,獲取表達式中的實體對象-關系映射的元數據,然后生成等價的SQL。故有兩種方式進行動態查詢。

1.拼接字符串方式

Tip:會引起SQL注入問題

/** * 動態拼接字符串構建查詢條件 * * @param name * @param age * @return */public static String queryPersonJPQL(String name, int age) { String queryQL = "select p from Person p where p.firstName= '" + name + "' and p.age=" + age; return queryQL;}//調用 Query query = entityManager.createQuery(queryPersonJPQL("jack", 21));

2.動態參數化構建查詢條件(推薦使用)

/** * 動態參數化構建查詢條件 * * @return */public static String queryPersonJPQLByParams() { String queryQL = "select p from Person p where p.firstName=:name and p.age=:age"; return queryQL;}Query query = entityManager.createQuery(queryPersonJPQLByParams());query.setParameter("name", "Jack");query.setParameter("age", 21);

2.2.命名查詢定義

命名查詢是一個強大的工具。使用@NamedQuery注解定義一個命名查詢,可以把它放在任何實體的類定義之上。該注解定義了查詢的名稱,及其查詢的文本。

Tip:命名查詢通暢放置在對應查詢結果的實體類上

@Entity@NamedQuery(name = "findByAge", query = "select p from Person p where p.age=:age")public class Person { //省略}

Tip:NamedQuery里面定義的名稱在整個持久化單元中需要唯一,不然運行會出錯。

eg:

 

復制代碼 代碼如下:

Exception in thread "main" org.hibernate.DuplicateMappingException: Duplicate query mapping findByAge at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.checkQueryName

 

調用

 

復制代碼 代碼如下:

List<Person> people = entityManager.createNamedQuery("findByAge", Person.class).setParameter("age", 21).getResultList();

 

如果一個類定義兩個或者以上個的命名查詢,那么必須把它放置在@NamedQueries()

2.3.綁定參數

通過前面的例子,我們可以看到綁定參數有兩種方式:1.位置參數化綁定。2.命名參數化綁定。都是通過Query接口的setParameter方法進行綁定。

1.位置參數化

TypedQuery<X> setParameter(int position, Object value);

2.命名參數化

TypedQuery<X> setParameter(String name, Object value);

第一種位置參數化綁定,如果位置發生變化都需要改變綁定的代碼。推薦使用第二種。

2.4.執行查詢

Query接口與TypedQuery接口提供了三種不同的方式執行查詢。

1.executeUpdate

用來執行批量更新或者刪除

2.getSingleResult

獲取單個結果集。如果沒有獲取到數據,則會拋出NoResultException異常。如果獲取多條數據的話,則會拋出NonUniqueResultException異常

3.getResultList

獲取對應的結果集合,指定順序的集合,需要使用List作為返回值類型。如果沒有獲取到數據的話,則返回一個空集合,不會拋出異常

2.5.分頁

通過setFirstResult() 和setMaxResults() 方法可以完成分頁的查詢

查詢頁碼為0,每頁展示2條數據

 

復制代碼 代碼如下:

List<Person> people = entityManager.createQuery("select p from Person p ", Person.class).setFirstResult(0).setMaxResults(2).getResultList();

 

Tip:不能用于通過集合關系連接的查詢,因為這些查詢可能返回重復的值。

2.6.查詢超時

如果一個應用程序需要設置查詢響應時間的限制,那么可以在查詢中設置javax.persistence.query.timeout屬性(jpa 2.0引入)或者將它作為持久化屬性的一部分。此屬性定義了查詢在終止前允許允許運行的==毫秒數==。如果查詢超時的時候,會拋出QueryTimeoutException。

TypedQuery<Person> query = entityManager.createQuery("select p from Person p", Person.class);//單位為毫秒 javax.persistence.query.timeoutquery.setHint("javax.persistence.query.timeout", 5000);List<Person> people = query.getResultList();

2.7.批量更新和刪除

批量更新實體是通過update語句完成。批量刪除實體是通過delete語句完成。兩者皆指定的是實體及其類的屬性。

entityManager.getTransaction().begin();Query query = entityManager.createQuery("update Person p set p.firstName=:name where p.id=:id");query.setParameter("name", "xiaobai");query.setParameter("id", 2);query.executeUpdate();Query query1 = entityManager.createQuery("delete Person p where p.id=:id");query1.setParameter("id", 9);query1.executeUpdate();entityManager.getTransaction().commit();

3.使用JPQL查詢的建議

在應用系統中,通常使用查詢的次數要比增加、修改、刪除要多。故合理的使用查詢顯的尤為重要。

1.建議采用命名查詢(NamedQuery)

持久化提供的程序通常會采用預編譯的方式將命名查詢作為程序初始化階段的一部分。這樣就避免了連續解析JPQL和生成SQL的系統開銷。

2.大數量優先使用投影方式檢索少量的列

jpa查詢通常返回的是整個實體的所有列,但是對于龐大的數據量而言,并不是所有的實體列都需要用到。那么我們可以使用投影的方式來處理。

List<List<Object[]>> persons = entityManager.createQuery("select new List(firstName,age) from Person p").getResultList();for (Object o : persons) {  System.out.println(o);}//輸出結果[Jack, 21][Jack, 21][Jack, 21][lily, 19][tom, 23][tom, 23]

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大名县| 嘉义市| 郧西县| 汝南县| 卢湾区| 高青县| 屯留县| 田东县| 五常市| 扎囊县| 滁州市| 巴青县| 兴和县| 怀远县| 义乌市| 海宁市| 淅川县| 宜都市| 吉林省| 科尔| 古浪县| 灵宝市| 大兴区| 都江堰市| 民县| 醴陵市| 启东市| 诏安县| 梅河口市| 景东| 宁海县| 鲁山县| 阆中市| 特克斯县| 南雄市| 临湘市| 喀喇| 南宁市| 潜江市| 河池市| 金昌市|