进行 Spring 6 迁移的最佳方式

news2025/7/3 20:03:23

介绍

在本文中,我们将了解如何将现有应用程序迁移到Spring 6以及如何充分利用此升级。

本文中的提示基于我在Hypersistence Optimizer和高性能 Java Persistence 项目中添加对 Spring 6 的支持所做的工作。

爪哇 17

首先,Spring 6 将最低 Java 版本提升到 17 个,这太棒了,因为你现在可以使用文本块和记录。

文本块

多亏了文本块,您的注释将更具可读性:@Query

1
2
3
4
5
6
7
8
9
10
@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
);

有关 Java 文本块的更多详细信息,请查看本文。

记录

Java Records 非常适合 DTO 投影。例如,你可以像这样定义 aclass:PostRecord

1
2
3
4
5
public record PostCommentRecord(
    Long id,
    String title,
    String review
) {}

然后,您可以使用 Spring Data JPA 查询方法获取对象:PostCommentRecord

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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 构造函数表达式中使用 theJava 的简单名称,是因为我从Hibernate Type 项目中注册了以下内容:PostCommentRecordClassClassImportIntegrator

1
2
3
4
5
6
7
8
9
10
properties.put(
    "hibernate.integrator_provider",
    (IntegratorProvider) () -> Collections.singletonList(
        new ClassImportIntegrator(
            List.of(
                PostCommentRecord.class
            )
        )
    )
);

有关 Java 记录的更多详细信息,请查看本文。

这还不是全部!Java 17 改进了 forand 的错误消息,并添加了模式匹配 forand。NullPointerExceptionswitchinstanceOf

JPA 3.1

默认情况下,Spring 6 使用 Hibernate 6.1,而 Hibernate 6.1 又使用 Jakarta Persistence 3.1。

现在,3.0版本标志着从Java持久性到Jakarta Patersistence的迁移,因此,出于这个原因,您必须将软件包导入替换为命名空间。javax.persistencejakarta.persistence

这是迁移到 JPA 3 必须进行的最重要的更改。与此同时,发布了3.1版本,但这个版本只包括Hibernate已经支持的一些小改进。

UUID 实体属性

例如,JPA 3 现在支持基本类型:UUID

1
2
3
4
5
@Column(
    name = "external_id",
    columnDefinition = "UUID NOT NULL"
)
private UUID externalId;

您甚至可以将它们用作实体标识符:

1
2
3
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;

但这只是一个糟糕的主意,因为使用 anfor 主键会导致很多问题:UUID

  • 索引页将很少填充,因为每个新的 UUID 都将在 B+树聚集索引中随机添加。
  • 由于主键值的随机性,将会有更多的页面拆分
  • UUID 很大,需要的字节数是列的两倍。它不仅影响主键,还影响所有关联的外键。bigint

此外,如果您使用的是SQL Server,MySQL或MariaDB,则默认表将被组织为聚簇索引,从而使所有这些问题变得更糟。

因此,最好避免使用 for 实体标识符。如果您确实需要从应用程序生成唯一标识符,那么最好使用64 位时间排序的随机 TSID。UUID

新的 JPQL 函数

JPQL 通过许多新功能得到了增强,例如,,,,,,数字函数。CEILINGFLOOREXPLNPOWERROUNDSIGN

但是,我发现最有用的是日期/时间函数:EXTRACT

1
2
3
4
5
6
7
List<Post> posts = entityManager.createQuery("""
    select p
    from Post p
    where EXTRACT(YEAR FROM createdOn) = :year
    """, Post.class)
.setParameter("year", Year.now().getValue())
.getResultList();

这很有用,因为日期/时间处理通常需要特定于数据库的函数,并且拥有一个可以呈现适当的特定于数据库的函数的泛型函数肯定很方便。

可自动关闭的实体管理器和实体管理器工厂

虽然Hibernateand已经扩展了接口,但现在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提供了大量的增强功能。

JDBC 优化

以前,Hibernate使用关联的列别名读取JDBC列值,这被证明很慢。出于这个原因,Hibernate 6 已切换到按基础 SQL 投影中的位置读取基础列值。ResultSet

除了速度更快之外,进行此更改还有一个非常好的副作用。基础 SQL 查询现在更具可读性。

例如,如果您在 Hibernate 5 上运行此 JPQL 查询:

1
2
3
4
5
6
7
8
Post post = entityManager.createQuery("""
    select p
    from Post p
    join fetch p.comments
    where p.id = :id
    """, Post.class)
.setParameter("id", 1L)
.getSingleResult();

将执行以下 SQL 查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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上运行相同的JPQL,将如何改为运行以下SQL查询:

1
2
3
4
5
6
7
8
9
10
11
12
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提供了一个全新的实体查询解析器,能够从JPQL和Criteria API生成规范模型,即语义查询模型。

通过统一实体查询模型,现在可以使用 Jakarta 持久性不支持的功能(如派生表或公用表表达式)来增强条件查询。

有关 Hibernate 语义查询模型的更多详细信息,请查看本文。

旧的休眠标准已被删除,但标准 API 已通过 提供许多新功能得到增强。HibernateCriteriaBuilder

例如,您可以使用函数进行不区分大小写的 LIKE 匹配:ilike

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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();

但是,这只是一个基本示例。使用新的,您现在可以渲染:HibernateCriteriaBuilder

  • 全部联盟
  • 窗口函数
  • 派生表
  • CTE和递归 CTE

方言增强功能

在Hibernate 5中,您必须根据底层数据库版本选择大量版本,这在Hibernate 6中得到了极大的简化:Dialect

 

此外,您甚至不需要在 Spring 配置中提供,因为它可以从 JDBC 解析。DialectDatabaseMetaData

有关此主题的更多详细信息,请查看此文章。

自动重复数据删除

您还记得在使用时为实体重复数据删除提供关键字是多么烦人吗?DISTINCTJOIN FETCH

1
2
3
4
5
6
7
8
9
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();

如果你忘记发送提示,那么Hibernate 5会将关键字传递给SQL查询,并导致执行计划运行一些额外的步骤,这些步骤只会让你的查询变慢:PASS_DISTINCT_THROUGHDISTINCT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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

有关 JPA 中如何工作的更多详细信息,请同时阅读本文。DISTINCT

情况不再如此,因为现在实体对象引用重复数据删除是自动完成的,因此您的查询不再需要关键字:JOIN FETCHDISTINCT

1
2
3
4
5
6
7
8
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();

厉害吧?

如果你喜欢这篇文章,我敢打赌你也会喜欢我的书籍和视频课程。

<img data-lazy-fallback=“1” src=“https://vladmihalcea.com/wp-content/uploads/2018/01/HPJP_h200.jpg” /正在上传…重新上传取消正在上传…重新上传取消正在上传…重新上传取消

结论

Spring 6 真的值得升级到。除了受益于Java 17提供的所有语言优化之外,所有其他框架依赖项还提供了大量新功能,这些依赖项已集成到Spring 6中。

例如,Hibernate 6提供了许多优化和新功能,可以满足您的许多日常数据访问需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/40830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022.11.27 学习周报

文章目录摘要文献阅读1.题目2.摘要3.介绍4.基于后向传播算法的多时间尺度RNN4.1 循环神经网络&#xff08;RNN&#xff09;4.2 基于多时间尺度的RNN预测模型5.实验5.1 数据简介5.2 数据分析5.3 评价指标5.4 实验结果6.结论深度学习1.循环神经网络&#xff08;RNN&#xff09;1.…

Flutter 5 大本地数据库解决方案

Flutter 5 大本地数据库解决方案 原文 https://levelup.gitconnected.com/top-5-local-database-solutions-for-flutter-development-6351cd494070 前言 这里列出了最流行的数据库解决方案以及代码示例。 选择正确的数据管理系统对于提高效率和可 extension 性以及影响可用性和…

3DConvCaps:3DUNet与卷积胶囊编码器用于医学图像分割

摘要 卷积神经网络需要大量的训练数据&#xff0c;无法处理物体的姿态和变形。此外其中的池化层也倾向于丢弃位置等重要的信息。CNN对旋转和仿射变换非常敏感。 胶囊网络是最近出现的一种新型体系结构&#xff0c;其通过动态路由和卷积步长代替池化层&#xff0c;在部分整体表…

steam搬砖项目的核心内容解答

大家好&#xff0c;我是阿阳 如果你有个几千块钱积蓄&#xff0c;想做点小生意&#xff0c;又不知道做啥&#xff0c;那我建议你来做steam搬砖&#xff0c;steam搬砖是什么呢&#xff1f;steam搬砖怎么赚钱的呢&#xff1f;你听我一步步跟你说来 steam搬砖是什么呢&#xff1f…

详解GMM高斯混合模型EM模型

一般讲到GMM就会讲到EM。 我不过多的介绍EM算法。这里只是举一些例子来看看真实的GMM怎么用EM算的。 一、GMM的作用 记住GMM的作用&#xff0c;就是聚类&#xff01; 二、GMM有hard和soft两种 hard-GMM和soft-GMM是为了对标k-means和soft k-means。在中文互联网上搜索到的GM…

【SVM分类】基于matlab哈里斯鹰算法优化支持向量机SVM分类【含Matlab源码 2243期】

⛄一、哈里斯鹰算法简介 HHO算法用数学公式来模拟现实中哈里斯鹰在不同机制下捕捉猎物的策略.在HHO中&#xff0c;哈里斯鹰是候选解&#xff0c;猎物随迭代逼近最优解.HHO算法包括两个阶段&#xff1a;全局探索阶段、局部开采阶段。 1 全局探索阶段 在这一阶段中&#xff0c;哈…

springboot thymeleaf使用

导入依赖 <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.11.RELEASE</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <a…

springboot集成swagger并更换主题

前言 swagger对于web一个开发人员&#xff0c;可以说是非常熟悉的了&#xff0c;之前都是用的公司搭好的框架拿来就用&#xff0c;自己也没有研究过&#xff0c;最近想搞一个自己拿来练手的基础框架&#xff0c;因此来记录一下springboot集成swagger的过程和注意事项。 swagg…

云南白药正在度过“中年危机”

​文丨熔财经 作者|kinki 今年&#xff0c;正是云南白药创制的120周年&#xff0c;虽然是一个百年老字号品牌&#xff0c;但在过去的数年间&#xff0c;云南白药在新品研制、跨界发展乃至品牌推广上都做了不少新尝试。今年&#xff0c;云南白药更提出了“141”战略&#xff0…

备战 2023 春招,P7大咖位手打 26 大后端面试专题神技,1500+题解析助力offer

年过后&#xff0c;不少人已经蓄势待发&#xff0c;信心满满地准备投递简历&#xff0c;到处面试&#xff0c;在不同的 Offer 之中择优而栖。 与此同时&#xff0c;也有人会悔恨自己这半年进步不大&#xff0c;每天噼里啪啦敲代码&#xff0c;但面对那些不能再熟悉的 Java 面试…

分布式解决方案 Percolator--详解

Percolator简介 Google在2012年将Percolator的架构设计作为论文发表&#xff0c;其目的是构建于BigTalbe的基础上&#xff0c;主要用于网页搜索索引等服务。由于BigTable只支持单行级别的事务&#xff0c;不支持多行事务等更复杂的事务&#xff0c;因此Percolator的诞生就是为了…

数据增强:Simple Questions Generate Named Entity Recognition Datasets

数据增强的方式一般是无标注数据集的情形的一种解决方式&#xff0c;今天的讲座报告中对这问题做了梳理。11.27学术报告文章&#xff0c;应该是韩旭的报告。 文章目录问题背景一、论文核心二、文章内容三、experiments总结问题背景 还是在于方法的创新&#xff0c;虽然是数据增…

Centos7下安装Oracle11g

1. 下载安装包 由于Oracle官网上无法下载Oracle数据库之前的版本&#xff0c;可以在 Oracle Software Delivery Cloud 里搜索oracle database 11g 或者百度网盘下载链接&#xff1a;https://pan.baidu.com/s/1r57xI5fSVba_Q3biCj06yg 提取码&#xff1a;xk30 2. 创建运行ora…

【BSC】使用Python玩转PancakeSwap(入门篇)

需求 最近我们需要在BSC上实现代币的自动化兑换&#xff0c;比如自动把BNB兑换成USDT&#xff0c;自动把USDT兑换成CAKE等其它代币&#xff0c;同时也要监视价格&#xff0c;在价格合适的时候再兑换代币。而PancakeSwap正是BSC上最大的去中心化平台&#xff0c;我们已经学会了…

潜匿的怪物,你的供应链真的安全吗?

网络钓鱼、DNS欺骗      勒索软件、MITM攻击      在这个网络环境      风声鹤唳的时代      这些网络攻击类型      你一定不会感到陌生      无孔不入,这个词用来形容网络攻击毫不为过。世上没有绝对锋利的矛,同样也没有坚不可摧的盾,即使您养成了安…

如何编写列名中带有空格的SQL查询

在这篇文章中&#xff0c;我们将学习如何写出列名中带有空格的SQL查询。空格在数据库对象的名称和表的列名的命名规则中受到限制。如果你想在对象名或列名中加入空格&#xff0c;查询和应用代码必须以不同的方式编写。在编写动态SQL查询时&#xff0c;你必须小心和精确。本文解…

【JavaWeb】Servlet系列 --- Tomcat安装及配置和常见的问题(2022最新详解、图文教程)

Tomcat的配置安装1. 关于WEB服务器软件2. 配置Tomcat的服务器第一步&#xff1a;配置Java的运行环境第二步&#xff1a;Tomcat的安装第三步&#xff1a;启动Tomcat3. 问题一&#xff1a;解决Tomcat服务器在DOS命令窗口中的乱码问题&#xff08;控制台乱码&#xff09;4. 测试To…

linux 用户不在sudoers文件中,此事将被报告

出现如下提示 gaokaoli 出现不在 sudoers 文件中。此事将被报告 一般是该用户 权限不够 既然知道权限不够可以添加到root用户组&#xff0c;获取权限即可 通过命令行添加到权限&#xff0c;发现还是不行 sudo usermod -g root gaokaoli 那就直接在配置文件中修改 通过执行…

word设置页码从非第一页开始

设置过程 参考&#xff1a;https://zhuanlan.zhihu.com/p/84998841 显示出分隔符和分页符 方法一&#xff1a; 在文档中直接按【CtrlShift8】组合键&#xff0c;即可显示出分节符。. 方法二&#xff1a; 点击【开始】-【段落】-【显示/隐藏编辑标记】按钮&#xff0c;也可显…

如何安装Jmeter监控服务器资源插件(JMeterPlugins + ServerAgent 方法一)?

一、下载插件 ServerAgent-2.2.3.zip 下载 JMeterPlugins-Extras-1.4.0.zip下载 JMeterPlugins-Standard-1.4.0.zip下载 &#xff08;或者可以到网站下载插件&#xff1a;JMeterPlugins-Standard和JMeterPlugins-Extras 下载地址&#xff1a;https://jmeter-plugins.org/down…