激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - JPA之使用JPQL語(yǔ)句進(jìn)行增刪改查

JPA之使用JPQL語(yǔ)句進(jìn)行增刪改查

2021-03-12 14:13落葉飛逝的戀 Java教程

這篇文章主要介紹了JPA之使用JPQL語(yǔ)句進(jìn)行增刪改查,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

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

1.Java持久化查詢語(yǔ)句入門(mén)

 

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

 

1.這個(gè)查詢語(yǔ)句類似于SQL。但它與真正的SQL的區(qū)別是,它不是從一個(gè)表中進(jìn)行選擇查詢,而是指定來(lái)自應(yīng)用程序域模型的實(shí)體。

2.查詢select子句也只是列出了查詢實(shí)體的別名,如果只查詢某一列的,可以使用點(diǎn)(.)操作符進(jìn)行來(lái)導(dǎo)航實(shí)體屬性。如下所示:

 

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

 

1.1.篩選條件

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

 

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

 

1.2.投影結(jié)果

對(duì)于查詢的數(shù)據(jù)量比較大的話,可以使用投影的方式,只查詢出有用的列。

 

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

 

1.3.聚合查詢

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

 

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

 

1.4.查詢參數(shù)

JPQL支持兩種類型的參數(shù)綁定語(yǔ)法。

1.位置參數(shù)表示法

其中參數(shù)是在查詢字符串中指示,該字符串是在一個(gè)問(wèn)號(hào)(?)之后緊隨參數(shù)的編號(hào)。當(dāng)執(zhí)行查詢的時(shí)候,開(kāi)發(fā)人員指定應(yīng)該替換的參數(shù)編

?
1
2
3
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.命名參數(shù)表示法

通過(guò)在一個(gè)冒號(hào)(:)之后緊隨參數(shù)名稱,在查詢字符串對(duì)它進(jìn)行指示,當(dāng)執(zhí)行查詢的時(shí)候,開(kāi)發(fā)人員指定應(yīng)該替換的參數(shù)名稱

?
1
2
3
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引入)接口來(lái)配置和執(zhí)行查詢。Query的返回的Object類型,而TypedQuery返回的是指定的Class類型。

?
1
2
3
4
//未指定類型,返回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.動(dòng)態(tài)查詢定義

JPA查詢引擎,可以將JPQL字符串解析成語(yǔ)法樹(shù),獲取表達(dá)式中的實(shí)體對(duì)象-關(guān)系映射的元數(shù)據(jù),然后生成等價(jià)的SQL。故有兩種方式進(jìn)行動(dòng)態(tài)查詢。

1.拼接字符串方式

Tip:會(huì)引起SQL注入問(wèn)題

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * 動(dòng)態(tài)拼接字符串構(gòu)建查詢條件
 *
 * @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;
}
 
//調(diào)用
 Query query = entityManager.createQuery(queryPersonJPQL("jack", 21));

2.動(dòng)態(tài)參數(shù)化構(gòu)建查詢條件(推薦使用)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * 動(dòng)態(tài)參數(shù)化構(gòu)建查詢條件
 *
 * @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.命名查詢定義

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

Tip:命名查詢通暢放置在對(duì)應(yīng)查詢結(jié)果的實(shí)體類上

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

Tip:NamedQuery里面定義的名稱在整個(gè)持久化單元中需要唯一,不然運(yùn)行會(huì)出錯(cuò)。

eg:

 

復(fù)制代碼 代碼如下:

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

 

調(diào)用

 

復(fù)制代碼 代碼如下:

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

 

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

2.3.綁定參數(shù)

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

1.位置參數(shù)化

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

2.命名參數(shù)化

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

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

2.4.執(zhí)行查詢

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

1.executeUpdate

用來(lái)執(zhí)行批量更新或者刪除

2.getSingleResult

獲取單個(gè)結(jié)果集。如果沒(méi)有獲取到數(shù)據(jù),則會(huì)拋出NoResultException異常。如果獲取多條數(shù)據(jù)的話,則會(huì)拋出NonUniqueResultException異常

3.getResultList

獲取對(duì)應(yīng)的結(jié)果集合,指定順序的集合,需要使用List作為返回值類型。如果沒(méi)有獲取到數(shù)據(jù)的話,則返回一個(gè)空集合,不會(huì)拋出異常

2.5.分頁(yè)

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

查詢頁(yè)碼為0,每頁(yè)展示2條數(shù)據(jù)

 

復(fù)制代碼 代碼如下:

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

 

Tip:不能用于通過(guò)集合關(guān)系連接的查詢,因?yàn)檫@些查詢可能返回重復(fù)的值。

2.6.查詢超時(shí)

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

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

2.7.批量更新和刪除

批量更新實(shí)體是通過(guò)update語(yǔ)句完成。批量刪除實(shí)體是通過(guò)delete語(yǔ)句完成。兩者皆指定的是實(shí)體及其類的屬性。

?
1
2
3
4
5
6
7
8
9
10
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查詢的建議

在應(yīng)用系統(tǒng)中,通常使用查詢的次數(shù)要比增加、修改、刪除要多。故合理的使用查詢顯的尤為重要。

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

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

2.大數(shù)量?jī)?yōu)先使用投影方式檢索少量的列

jpa查詢通常返回的是整個(gè)實(shí)體的所有列,但是對(duì)于龐大的數(shù)據(jù)量而言,并不是所有的實(shí)體列都需要用到。那么我們可以使用投影的方式來(lái)處理。

?
1
2
3
4
5
6
7
8
9
10
11
List<List<Object[]>> persons = entityManager.createQuery("select new List(firstName,age) from Person p").getResultList();
for (Object o : persons) {
  System.out.println(o);
}
//輸出結(jié)果
[Jack, 21]
[Jack, 21]
[Jack, 21]
[lily, 19]
[tom, 23]
[tom, 23]

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.jianshu.com/p/06beda1a0831

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色网免费观看 | 国产精品一区2区3区 | 操操电影 | 双性精h调教灌尿打屁股的文案 | 91看片在线观看视频 | 在线免费观看麻豆 | 国产超碰人人做人人爱ⅴa 色天天综合网 | 色视频在线 | 国产精品视频免费网站 | 免费一级毛片在线播放视频老 | 美女视频大全网站免费 | 超久久| 神马福利电影 | 久久99精品久久久久久秒播放器 | 欧美在线电影 | 在线成人www免费观看视频 | 亚洲成人综合网站 | 成片免费大全 | 一级国产精品一级国产精品片 | 日日操日日操 | 久久久久久久久久久av | 日韩在线观看视频免费 | 斗罗破苍穹在线观看免费完整观看 | 一级在线观看视频 | 美女一级视频 | 蜜桃传媒视频麻豆第一区免费观看 | 欧美成人一区在线观看 | av在线视 | 男女一边摸一边做羞羞视频免费 | 国产精品久久久久久久久久久久午夜 | 久久亚洲一区二区三区成人国产 | 久久精品中文字幕一区二区三区 | 一级黄色在线免费观看 | 久久综合九色综合久久久精品综合 | 日韩欧美精品电影 | 九九热免费在线观看 | 草草久 | 欧美性猛交xxxxx按摩国内 | 久久生活片 | 久久精品伊人网 | 中文字幕亚洲欧美 |