溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何將應(yīng)用程序進(jìn)行Spring6遷移

發(fā)布時間:2023-03-27 14:19:33 來源:億速云 閱讀:114 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“如何將應(yīng)用程序進(jìn)行Spring6遷移”,在日常操作中,相信很多人在如何將應(yīng)用程序進(jìn)行Spring6遷移問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何將應(yīng)用程序進(jìn)行Spring6遷移”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

    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)槲覐腍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

    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

    如何將應(yīng)用程序進(jìn)行Spring6遷移

    Although you might rarely need to rely on that because Spring takes care of the on your behalf, it&rsquo;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ī)范模型,即語義查詢模型。

    如何將應(yīng)用程序進(jìn)行Spring6遷移

    通過統(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

    方言增強(qiáng)功能

    在Hibernate 5中,您必須根據(jù)底層數(shù)據(jù)庫版本選擇大量版本,這在Hibernate 6中得到了極大的簡化:Dialect

    如何將應(yīng)用程序進(jìn)行Spring6遷移

    此外,您甚至不需要在 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í)用的文章!

    向AI問一下細(xì)節(jié)

    免責(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)容。

    AI