您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何將應(yīng)用程序進(jìn)行Spring6遷移”,在日常操作中,相信很多人在如何將應(yīng)用程序進(jìn)行Spring6遷移問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何將應(yīng)用程序進(jìn)行Spring6遷移”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
首先,Spring 6 將最低 Java 版本提升到 17 個,這太棒了,因?yàn)槟悻F(xiàn)在可以使用文本塊和記錄。
多虧了文本塊,您的注釋將更具可讀性:@Query
@Query(""" select p from Post p left join fetch p.comments where p.id between :minId and :maxId """) List<Post> findAllWithComments( @Param("minId") long minId, @Param("maxId") long maxId );
有關(guān) Java 文本塊的更多詳細(xì)信息,請查看本文。
Java Records 非常適合 DTO 投影。例如,你可以像這樣定義 aclass:PostRecord
public record PostCommentRecord( Long id, String title, String review ) {}
然后,您可以使用 Spring Data JPA 查詢方法獲取對象:PostCommentRecord
@Query(""" select new PostCommentRecord( p.id as id, p.title as title, c.review as review ) from PostComment c join c.post p where p.title like :postTitle order by c.id """) List<PostCommentRecord> findCommentRecordByTitle( @Param("postTitle") String postTitle );
我們之所以可以在 JPQL 構(gòu)造函數(shù)表達(dá)式中使用 theJava 的簡單名稱,是因?yàn)槲覐腍ibernate Type 項(xiàng)目中注冊了以下內(nèi)容:PostCommentRecordClassClassImportIntegrator
properties.put( "hibernate.integrator_provider", (IntegratorProvider) () -> Collections.singletonList( new ClassImportIntegrator( List.of( PostCommentRecord.class ) ) ) );
有關(guān) Java 記錄的更多詳細(xì)信息,請查看本文。
這還不是全部!Java 17 改進(jìn)了 forand 的錯誤消息,并添加了模式匹配 forand。NullPointerExceptionswitchinstanceOf
默認(rèn)情況下,Spring 6 使用 Hibernate 6.1,而 Hibernate 6.1 又使用 Jakarta Persistence 3.1。
現(xiàn)在,3.0版本標(biāo)志著從Java持久性到Jakarta Patersistence的遷移,因此,出于這個原因,您必須將軟件包導(dǎo)入替換為命名空間。javax.persistencejakarta.persistence
這是遷移到 JPA 3 必須進(jìn)行的最重要的更改。與此同時,發(fā)布了3.1版本,但這個版本只包括Hibernate已經(jīng)支持的一些小改進(jìn)。
例如,JPA 3 現(xiàn)在支持基本類型:UUID
@Column( name = "external_id", columnDefinition = "UUID NOT NULL" ) private UUID externalId;
您甚至可以將它們用作實(shí)體標(biāo)識符:
@Id @GeneratedValue(strategy = GenerationType.UUID) private UUID id;
但這只是一個糟糕的主意,因?yàn)槭褂?anfor 主鍵會導(dǎo)致很多問題:UUID
索引頁將很少填充,因?yàn)槊總€新的 UUID 都將在 B+樹聚集索引中隨機(jī)添加。
由于主鍵值的隨機(jī)性,將會有更多的頁面拆分
UUID很大,需要的字節(jié)數(shù)是列的兩倍。它不僅影響主鍵,還影響所有關(guān)聯(lián)的外鍵。bigint
此外,如果您使用的是SQL Server,MySQL或MariaDB,則默認(rèn)表將被組織為聚簇索引,從而使所有這些問題變得更糟。
因此,最好避免使用 for 實(shí)體標(biāo)識符。如果您確實(shí)需要從應(yīng)用程序生成唯一標(biāo)識符,那么最好使用64 位時間排序的隨機(jī) TSID。UUID
JPQL 通過許多新功能得到了增強(qiáng),例如,,,,,,數(shù)字函數(shù)。CEILINGFLOOREXPLNPOWERROUNDSIGN
但是,我發(fā)現(xiàn)最有用的是日期/時間函數(shù):EXTRACT
List<Post> posts = entityManager.createQuery(""" select p from Post p where EXTRACT(YEAR FROM createdOn) = :year """, Post.class) .setParameter("year", Year.now().getValue()) .getResultList();
這很有用,因?yàn)槿掌?時間處理通常需要特定于數(shù)據(jù)庫的函數(shù),并且擁有一個可以呈現(xiàn)適當(dāng)?shù)奶囟ㄓ跀?shù)據(jù)庫的函數(shù)的泛型函數(shù)肯定很方便。
可自動關(guān)閉的實(shí)體管理器和實(shí)體管理器工廠
雖然Hibernateand已經(jīng)擴(kuò)展了接口,但現(xiàn)在JPAand也遵循了這種做法:SessionSessionFactoryAutoClosableEntityManagerEntityManagerFactory
Although you might rarely need to rely on that because Spring takes care of the on your behalf, it’s very handy when you have to process the programmatically.EntityManagerEntityManager
雖然Java 17和JPA 3.1為您帶來了一些功能,但Hibernate 6提供了大量的增強(qiáng)功能。
以前,Hibernate使用關(guān)聯(lián)的列別名讀取JDBC列值,這被證明很慢。出于這個原因,Hibernate 6 已切換到按基礎(chǔ) SQL 投影中的位置讀取基礎(chǔ)列值。ResultSet
除了速度更快之外,進(jìn)行此更改還有一個非常好的副作用?;A(chǔ) SQL 查詢現(xiàn)在更具可讀性。
例如,如果您在 Hibernate 5 上運(yùn)行此 JPQL 查詢:
Post post = entityManager.createQuery(""" select p from Post p join fetch p.comments where p.id = :id """, Post.class) .setParameter("id", 1L) .getSingleResult();
將執(zhí)行以下 SQL 查詢:
SELECT bidirectio0_.id AS id1_0_0_, comments1_.id AS id1_1_1_, bidirectio0_.title AS title2_0_0_, comments1_.post_id AS post_id3_1_1_, comments1_.review AS review2_1_1_, comments1_.post_id AS post_id3_1_0__, comments1_.id AS id1_1_0__ FROM post bidirectio0_ INNER JOIN post_comment comments1_ ON bidirectio0_.id=comments1_.post_id WHERE bidirectio0_.id=1
如果您在Hibernate 6上運(yùn)行相同的JPQL,將如何改為運(yùn)行以下SQL查詢:
SELECT p1_0.id, c1_0.post_id, c1_0.id, c1_0.review, p1_0.title FROM post p1_0 JOIN post_comment c1_0 ON p1_0.id=c1_0.post_id WHERE p1_0.id = 1
好多了,對吧?
語義查詢模型和條件查詢
Hibernate 6提供了一個全新的實(shí)體查詢解析器,能夠從JPQL和Criteria API生成規(guī)范模型,即語義查詢模型。
通過統(tǒng)一實(shí)體查詢模型,現(xiàn)在可以使用 Jakarta 持久性不支持的功能(如派生表或公用表表達(dá)式)來增強(qiáng)條件查詢。
有關(guān) Hibernate 語義查詢模型的更多詳細(xì)信息,請查看本文。
舊的休眠標(biāo)準(zhǔn)已被刪除,但標(biāo)準(zhǔn) API 已通過 提供許多新功能得到增強(qiáng)。HibernateCriteriaBuilder
例如,您可以使用函數(shù)進(jìn)行不區(qū)分大小寫的 LIKE 匹配:ilike
HibernateCriteriaBuilder builder = entityManager .unwrap(Session.class) .getCriteriaBuilder(); CriteriaQuery<Post> criteria = builder.createQuery(Post.class); Root<Post> post = criteria.from(Post.class); ParameterExpression<String> parameterExpression = builder .parameter(String.class); List<Post> posts = entityManager.createQuery( criteria .where( builder.ilike( post.get(Post_.TITLE), parameterExpression) ) .orderBy( builder.asc( post.get(Post_.ID) ) ) ) .setParameter(parameterExpression, titlePattern) .setMaxResults(maxCount) .getResultList();
但是,這只是一個基本示例。使用新的,您現(xiàn)在可以渲染:HibernateCriteriaBuilder
全部聯(lián)盟
窗口函數(shù)
派生表
CTE和遞歸CTE
在Hibernate 5中,您必須根據(jù)底層數(shù)據(jù)庫版本選擇大量版本,這在Hibernate 6中得到了極大的簡化:Dialect
此外,您甚至不需要在 Spring 配置中提供,因?yàn)樗梢詮?JDBC 解析。DialectDatabaseMetaData
有關(guān)此主題的更多詳細(xì)信息,請查看此文章。
自動重復(fù)數(shù)據(jù)刪除
您還記得在使用時為實(shí)體重復(fù)數(shù)據(jù)刪除提供關(guān)鍵字是多么煩人嗎?DISTINCTJOIN FETCH
List<Post> posts = entityManager.createQuery(""" select distinct p from Post p left join fetch p.comments where p.title = :title """, Post.class) .setParameter("title", "High-Performance Java Persistence") .setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH, false) .getResultList();
如果你忘記發(fā)送提示,那么Hibernate 5會將關(guān)鍵字傳遞給SQL查詢,并導(dǎo)致執(zhí)行計(jì)劃運(yùn)行一些額外的步驟,這些步驟只會讓你的查詢變慢:PASS_DISTINCT_THROUGHDISTINCT
Unique (cost=23.71..23.72 rows=1 width=1068) (actual time=0.131..0.132 rows=2 loops=1) -> Sort (cost=23.71..23.71 rows=1 width=1068) (actual time=0.131..0.131 rows=2 loops=1) Sort Key: p.id, pc.id, p.created_on, pc.post_id, pc.review Sort Method: quicksort Memory: 25kB -> Hash Right Join (cost=11.76..23.70 rows=1 width=1068) (actual time=0.054..0.058 rows=2 loops=1) Hash Cond: (pc.post_id = p.id) -> Seq Scan on post_comment pc (cost=0.00..11.40 rows=140 width=532) (actual time=0.010..0.010 rows=2 loops=1) -> Hash (cost=11.75..11.75 rows=1 width=528) (actual time=0.027..0.027 rows=1 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Seq Scan on post p (cost=0.00..11.75 rows=1 width=528) (actual time=0.017..0.018 rows=1 loops=1) Filter: ( (title)::text = 'High-Performance Java Persistence eBook has been released!'::text ) Rows Removed by Filter: 3
情況不再如此,因?yàn)楝F(xiàn)在實(shí)體對象引用重復(fù)數(shù)據(jù)刪除是自動完成的,因此您的查詢不再需要關(guān)鍵字:JOIN FETCHDISTINCT
List<Post> posts = entityManager.createQuery(""" select p from Post p left join fetch p.comments where p.title = :title """, Post.class) .setParameter("title", "High-Performance Java Persistence") .getResultList();
到此,關(guān)于“如何將應(yīng)用程序進(jìn)行Spring6遷移”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。