日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jpa的查询api_为JPA的本机查询API键入安全查询

發(fā)布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jpa的查询api_为JPA的本机查询API键入安全查询 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

jpa的查詢api

當您使用JPA時-有時-JPQL不能解決問題,您將不得不使用本機SQL。 從一開始,像Hibernate這樣的ORM就為這些情況保留了開放的“后門”,并為Spring的JdbcTemplate , Apache DbUtils或jOOQ提供了類似的API,用于純SQL 。 這很有用,因為您可以繼續(xù)將ORM用作數(shù)據(jù)庫交互的單個入口點。

但是,使用字符串連接編寫復(fù)雜的動態(tài)SQL既繁瑣又容易出錯,并且是SQL注入漏洞的門戶。 使用像jOOQ這樣的類型安全的API會非常有用,但是您可能會發(fā)現(xiàn)僅在10-15個本機查詢中就很難在同一應(yīng)用程序中維護兩個不同的連接,事務(wù)和會話模型。

但事實是:

您可以將jOOQ用于JPA本機查詢!

確實如此! 有幾種方法可以實現(xiàn)此目的。

提取元組(即Object [])

最簡單的方法將不會利用JPA的任何高級功能,而只是為您獲取JPA的本機Object[]形式的元組。 假設(shè)這個簡單的實用方法:

public static List<Object[]> nativeQuery(EntityManager em, org.jooq.Query query ) {// Extract the SQL statement from the jOOQ query:Query result = em.createNativeQuery(query.getSQL());// Extract the bind values from the jOOQ query:List<Object> values = query.getBindValues();for (int i = 0; i < values.size(); i++) {result.setParameter(i + 1, values.get(i));}return result.getResultList(); }

使用API

這就是您以最簡單的形式橋接這兩個API所需要的,以通過EntityManager運行“復(fù)雜”查詢:

List<Object[]> books = nativeQuery(em, DSL.using(configuration).select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, BOOK.TITLE).from(AUTHOR).join(BOOK).on(AUTHOR.ID.eq(BOOK.AUTHOR_ID)).orderBy(BOOK.ID));books.forEach((Object[] book) -> System.out.println(book[0] + " " + book[1] + " wrote " + book[2]));

同意的結(jié)果中沒有很多類型安全性,因為我們只得到一個Object[] 。 我們期待著將來支持Scala或Ceylon之類的元組(甚至記錄)類型的Java。

因此,更好的解決方案可能是以下方法:

獲取實體

假設(shè)您具有以下非常簡單的實體:

@Entity @Table(name = "book") public class Book {@Idpublic int id;@Column(name = "title")public String title;@ManyToOnepublic Author author; }@Entity @Table(name = "author") public class Author {@Idpublic int id;@Column(name = "first_name")public String firstName;@Column(name = "last_name")public String lastName;@OneToMany(mappedBy = "author")public Set<Book> books; }

并假設(shè),我們將添加一個附加的實用程序方法,該方法還將Class引用傳遞給EntityManager :

public static <E> List<E> nativeQuery(EntityManager em, org.jooq.Query query,Class<E> type ) {// Extract the SQL statement from the jOOQ query:Query result = em.createNativeQuery(query.getSQL(), type);// Extract the bind values from the jOOQ query:List<Object> values = query.getBindValues();for (int i = 0; i < values.size(); i++) {result.setParameter(i + 1, values.get(i));}// There's an unsafe cast here, but we can be sure// that we'll get the right type from JPAreturn result.getResultList(); }

使用API

現(xiàn)在這相當靈活,只需將jOOQ查詢放入該API并從中獲取JPA實體-兩者兼有,因為您可以輕松地從獲取的實體中添加/刪除嵌套集合,就好像您是通過JPQL來獲取它們一樣:

List<Author> authors = nativeQuery(em,DSL.using(configuration).select().from(AUTHOR).orderBy(AUTHOR.ID) , Author.class); // This is our entity class hereauthors.forEach(author -> {System.out.println(author.firstName + " " + author.lastName + " wrote");books.forEach(book -> {System.out.println(" " + book.title);// Manipulate the entities here. Your// changes will be persistent!}); });

獲取實體結(jié)果

如果您比較敢于冒險并且對注釋有一種奇怪的喜好 ,或者只想在休假前給同事開個玩笑,還可以使用JPA的javax.persistence.SqlResultSetMapping 。 想象以下映射聲明:

@SqlResultSetMapping(name = "bookmapping",entities = {@EntityResult(entityClass = Book.class,fields = {@FieldResult(name = "id", column = "b_id"),@FieldResult(name = "title", column = "b_title"),@FieldResult(name = "author", column = "b_author_id")}),@EntityResult(entityClass = Author.class,fields = {@FieldResult(name = "id", column = "a_id"),@FieldResult(name = "firstName", column = "a_first_name"),@FieldResult(name = "lastName", column = "a_last_name")})} )

本質(zhì)上,以上聲明將數(shù)據(jù)庫列( @SqlResultSetMapping -> entities -> @EntityResult -> fields -> @FieldResult -> column )映射到實體及其對應(yīng)的屬性。 使用這項強大的技術(shù),您可以從任何類型SQL查詢結(jié)果中生成實體結(jié)果。

同樣,我們將創(chuàng)建一個小的實用工具方法:

public static <E> List<E> nativeQuery(EntityManager em, org.jooq.Query query,String resultSetMapping ) {// Extract the SQL statement from the jOOQ query:Query result = em.createNativeQuery(query.getSQL(), resultSetMapping);// Extract the bind values from the jOOQ query:List<Object> values = query.getBindValues();for (int i = 0; i < values.size(); i++) {result.setParameter(i + 1, values.get(i));}// This implicit cast is a lie, but let's risk itreturn result.getResultList(); }

請注意, 上面的API使用了anti-pattern ,在這種情況下可以使用,因為JPA首先不是類型安全的API。

使用API

現(xiàn)在,再次,您可以通過上述API將類型安全的jOOQ查詢傳遞給EntityManager ,并傳遞SqlResultSetMapping的名稱,如下SqlResultSetMapping :

List<Object[]> result = nativeQuery(em,DSL.using(configuration.select(AUTHOR.ID.as("a_id"),AUTHOR.FIRST_NAME.as("a_first_name"),AUTHOR.LAST_NAME.as("a_last_name"),BOOK.ID.as("b_id"),BOOK.AUTHOR_ID.as("b_author_id"),BOOK.TITLE.as("b_title")).from(AUTHOR).join(BOOK).on(BOOK.AUTHOR_ID.eq(AUTHOR.ID)).orderBy(BOOK.ID)), "bookmapping" // The name of the SqlResultSetMapping );result.forEach((Object[] entities) -> {JPAAuthor author = (JPAAuthor) entities[1];JPABook book = (JPABook) entities[0];System.out.println(author.firstName + " " + author.lastName + " wrote " + book.title); });

在這種情況下,結(jié)果仍然是Object[] ,但是這一次, Object[]并不表示具有單獨列的元組,而是表示由SqlResultSetMapping注釋聲明的實體。

這種方法很吸引人,當您需要從查詢中映射任意結(jié)果但仍需要托管實體時,可能會用到它。 如果您想了解更多信息,我們只能推薦Thorben Janssen關(guān)于這些高級JPA功能的有趣博客系列:

  • 結(jié)果集映射:基礎(chǔ)
  • 結(jié)果集映射:復(fù)雜映射
  • 結(jié)果集映射:構(gòu)造函數(shù)結(jié)果映射
  • 結(jié)果集映射:Hibernate特定功能

結(jié)論

在ORM和SQL之間(特別是在Hibernate和jOOQ之間)進行選擇并不總是那么容易。

  • 當涉及到應(yīng)用對象圖持久性時,即當您有很多復(fù)雜的CRUD(涉及復(fù)雜的鎖定和事務(wù)策略)時,ORM會閃耀。
  • 當運行批量SQL(用于讀取和寫入操作),運行分析,報告時,SQL大放異彩。

當您“幸運”時(例如,工作很簡單),您的應(yīng)用程序僅位于安全柵的一側(cè),您可以在ORM和SQL之間進行選擇。 當您“幸運”時(例如– ooooh,這是一個有趣的問題),您將不得不同時使用兩者。 ( 另請參閱Mike Hadlow關(guān)于該主題的有趣文章 )

這里的信息是:可以! 使用JPA的本機查詢API,您可以利用RDBMS的全部功能運行復(fù)雜的查詢,并且仍然可以將結(jié)果映射到JPA實體。 您不限于使用JPQL。

邊注

盡管過去我們一直在批評JPA的某些方面(有關(guān)詳細信息,請閱讀JPA 2.1如何成為新的EJB 2.0 ),但我們的批評主要集中在JPA對注釋的濫用上。 當使用jOOQ之類的類型安全API時,可以輕松地向編譯器提供所有必需的類型信息以構(gòu)造結(jié)果。 我們堅信,將來的JPA版本將更積極地使用Java的類型系統(tǒng),從而可以更流暢地集成SQ??L,JPQL和實體持久性。

翻譯自: https://www.javacodegeeks.com/2015/05/type-safe-queries-for-jpas-native-query-api.html

jpa的查詢api

總結(jié)

以上是生活随笔為你收集整理的jpa的查询api_为JPA的本机查询API键入安全查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品免费久久久久 | 一本大道一区二区 | 午夜av在线播放 | 午夜在线精品偷拍 | 国产偷自拍| 国产成人精品三级麻豆 | 日韩视频在线免费观看 | 中文字幕日韩三级 | 真实的国产乱xxxx在线91 | 国产欧美日韩亚洲 | 欧美男女动态图 | 一级片a级片 | 老司机一区二区三区 | 国产裸体永久免费视频网站 | 国内精品久久久久久久影视简单 | 久久久久久久久久久久Av | 一区二区三区视频在线观看免费 | 少妇特殊按摩高潮惨叫无码 | 一级毛片儿| 国产精品三级电影 | 蜜桃久久av | 亚洲蜜桃在线 | 久久一区二区三区精品 | 亚洲精品久久久久久国产精华液 | 国产精品久久久久久一区 | 国产资源第一页 | 男男大尺度 | 国产黄色大片视频 | 欧美成人精品一区二区三区在线观看 | 成人中文字幕+乱码+中文字幕 | 国产高潮失禁喷水爽到抽搐 | 里番精品3d一二三区 | 最近中文字幕在线mv视频在线 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 小敏的受孕日记h | 久久久这里有精品 | 国产a久久麻豆入口 | av私库在线观看 | 欧美成人三级在线观看 | 小sao货大ji巴cao死你 | 国产在线无 | 国产一区二区高清 | 国产黄色网络 | 亚洲最新在线视频 | 国产精品国产一区二区 | 久久综合精品国产二区无码不卡 | 日韩av午夜 | 久久精品综合网 | 秋霞午夜伦理 | 国产精品不卡视频 | 无码乱人伦一区二区亚洲 | 久久久久久久久久99 | 手机av电影在线 | 欧美videos另类极品 | 黄a在线| 99色99| 色综合av在线 | 影音先锋激情在线 | 欧美s码亚洲码精品m码 | 日本中文字幕观看 | 免费看黄色一级片 | 中文字幕超碰在线 | 日日噜噜噜噜久久久精品毛片 | 亚洲啊v | 男女啪啪软件 | 中文字母av | 日韩av一级 | 国产毛片自拍 | 99人妻少妇精品视频一区 | 成年人视频在线观看免费 | 亚州一级 | 美女扒开尿口让男人爽 | 人人人人干| 99热这里 | 成人在线视屏 | 亚洲AV成人精品 | 大桥未久视频在线观看 | 黄色一级国产 | 相亲对象是问题学生动漫免费观看 | 日韩精品一区二区在线播放 | 国产在线h| 最新黄色在线 | 18pao国产成视频永久免费 | 男生和女生差差视频 | 毛片官网| 国产一区二区三区成人 | 一区二区免费在线 | 一本一道久久a久久精品综合 | 懂色av一区二区 | 人人草在线 | 亚洲色图丝袜 | 自拍偷拍专区 | 97干干干| 九色国产在线 | av片一区二区三区 | 欧美特级特黄aaaaaa在线看 | 欧美午夜精品久久久久久蜜 | 中文字幕狠狠 | 一本亚洲 |