欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

將應(yīng)用程序進(jìn)行Spring6遷移的最佳使用方式

 更新時間:2023年03月27日 11:13:31   作者:allway2  
這篇文章主要介紹了將應(yīng)用程序進(jìn)行Spring6遷移的最佳方式,以及如何充分利用此升級,需要的朋友可以參考下,如有錯誤的地方還請指正

介紹

在本文中,我們將了解如何將現(xiàn)有應(yīng)用程序遷移到Spring 6以及如何充分利用此升級。

本文中的提示基于我在Hypersistence Optimizer和高性能 Java Persistence 項(xiàng)目中添加對 Spring 6 的支持所做的工作。

Java17

首先,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)槲覐?a rel="external nofollow" target="_blank">Hibernate 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

JPA 3.1

默認(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)。

UUID 實(shí)體屬性

例如,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 函數(shù)

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

冬眠 6

雖然Java 17和JPA 3.1為您帶來了一些功能,但Hibernate 6提供了大量的增強(qiáng)功能。

JDBC 優(yōu)化

以前,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

方言增強(qiáng)功能

在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í)行計劃運(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

有關(guān) JPA 中如何工作的更多詳細(xì)信息,請同時閱讀本文。DISTINCT

情況不再如此,因?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();

結(jié)論

Spring 6 真的值得升級到。除了受益于Java 17提供的所有語言優(yōu)化之外,所有其他框架依賴項(xiàng)還提供了大量新功能,這些依賴項(xiàng)已集成到Spring 6中。

例如,Hibernate 6提供了許多優(yōu)化和新功能,可以滿足您的許多日常數(shù)據(jù)訪問需求。

到此這篇關(guān)于將應(yīng)用程序進(jìn)行Spring6遷移的最佳方式的文章就介紹到這了,更多相關(guān)Spring6遷移的最佳方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論