如何在Spring Boot 3中使用Java记录 DTO? - foojay


随着 Spring 6 和 Spring Boot 3 的发布,Java 17+ 成为了基准框架版本。

因此,现在是开始使用紧凑型Java 记录作为各种数据库和 API 调用的数据传输对象 ( DTO ) 的好时机。

如果您想安装示例数据库并自己进行试验,请按照这些说明进行操作。否则,请随意跳过此部分:

  • 下载PostgreSQL 语法的Chinook 数据库数据集(音乐商店)。
  • 在 Docker 中启动一个 YugabyteDB 实例,一个符合 PostgreSQL 标准的分布式数据库
    mkdir ~/yb_docker_data

    docker network create custom-network

    docker run -d --name yugabytedb_node1 --net custom-network \
      -p 7001:7000 -p 9000:9000 -p 5433:5433 \
      -v ~/yb_docker_data/node1:/home/yugabyte/yb_data --restart unless-stopped \
      yugabytedb/yugabyte:latest \
      bin/yugabyted start \
      --base_dir=/home/yugabyte/yb_data --daemon=false

 
  • 在 YugabyteDB 中 创建数据库chinook:
    createdb -h 127.0 . 0.1 -p 5433 -U yugabyte -E UTF8 chinook

  • 加载示例数据集:
    psql -h 127.0.0.1 -p 5433 -U yugabyte -f Chinook_PostgreSql_utf8.sql -d chinook


接下来,创建一个示例 Spring Boot 3 应用程序:
  • 使用 Spring Boot 3+ 和 Java 17+ 以及 Spring Data JPA 作为依赖项生成应用程序模板:https://start.spring.io/
  • 将 PostgreSQL 驱动程序添加到pom.xml文件中:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.5.4</version>
</dependency>

  • 在文件application.properties中提供数据库连接设置:spring.datasource.url =
    jdbc:postgresql://127.0.0.1:5433/chinook
    spring.datasource.username = xxx
    spring.datasource.password = xxx

可以了,好了!现在,您已准备好按照指南的其余部分进行操作。

数据模型
Chinook 数据库带有许多关系,但两个表足以说明如何将 Java 记录用作 DTO。

第一个表是Track,下面是一个对应的JPA实体类的定义:

@Entity
public class Track {
    @Id
    private Integer trackId;

    @Column(nullable = false)
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "album_id")
    private Album album;

    @Column(nullable = false)
    private Integer mediaTypeId;

    private Integer genreId;

    private String composer;

    @Column(nullable = false)
    private Integer milliseconds;

    private Integer bytes;

    @Column(nullable = false)
    private BigDecimal unitPrice;

   
// Getters and setters are omitted
}

第二个表是Album并且具有以下实体类:

@Entity
public class Album {
    @Id
    private Integer albumId;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private Integer artistId;

    // Getters and setters are omitted
}

除了实体类之外,创建一个名为 Java RecordTrackRecord的存储简短但描述性的歌曲信息:

public record TrackRecord(String name, String album, String composer) {}


JPA 查询中的 Java 记录
是在 JPA 查询中实例化 Java Record 实例。

首先,用一个自定义的查询来扩展TrackRepository接口的实现,从请求的数据库列中创建一个TrackRecord实例:

public interface TrackRepository extends JpaRepository<Track, Integer> {
        @Query("""
                        SELECT new com.my.springboot.app.TrackRecord(t.name, a.title, t.composer)
                        FROM Track t
                        JOIN Album a ON t.album.albumId=a.albumId
                        WHERE t.trackId=:id
                       
""")
        TrackRecord findTrackRecord(@Param(
"id") Integer trackId);

接下来,更新公共TrackRecord getTrackRecord(Integer trackId)的实现,如下所示:

@Transactional(readOnly = true)
public TrackRecord getTrackRecord(Integer trackId) {
     return repository.findTrackRecord(trackId);
}

因此,方法实现是一个一行程序,它直接从JPA存储库中获取 跟踪记录TrackRecord实例,尽可能简单。

但这还不是全部。还有一个小问题。

构建Java记录的JPA查询需要你为TrackRecord类提供一个完整的包名:

SELECT new com.my.springboot.app.TrackRecord(t.name, a.title, t.composer)...

让我们找到一种方法来绕过这个要求。理想情况下,Java记录需要在没有包名的情况下进行实例化:

SELECT new TrackRecord(t.name, a.title, t.composer)...

详细点击标题