Java 16 中引入的 Java Records 允许轻松定义透明数据载体。对于维护依赖于 JPA 、Spring Data的应用程序的开发人员来说,Records 可能是使用数据库投影的绝佳选择。
记录不是实体:记录只能用作投影。
流行的 JPA 实现(如 Hibernate)依赖于无参数构造函数、非最终字段、设置器和非最终类的实体来创建代理,而记录不鼓励或明确禁止所有这些操作。
Spring Data 有多种使用记录的方法:
自动映射
如果记录的组件与跟踪实体的字段匹配,Spring Data 可以自动处理查询返回映射,如下例所示:
public interface AdvocateRepo
extends CrudRepository
Iterable findByRegion(String region);
}
记录Record
这里的组件 Record AdvocateRecord 与 以@Entity 标注的AdvocateEntity类的字段相匹配:
public record AdvocateRecord(
int id,
String fName,
String lName,
String region,
int twitterFollowers) {}
以@Entity 标注的AdvocateEntity类
public class AdvocateEntity {
@Id
private int id;
private String fName;
private String lName;
private String region;
private int twitterFollowers;
...
查询
Spring Data 还允许在 @Query 中提供 JPQL 查询:
public interface AdvocateRepo
extends CrudRepository
@Query("""
SELECT
new com.bk.records.AdvocateNameRecord(a.fName, a.lName)
FROM AdvocateEntity a
WHERE region = ?1
""")
Iterable findNamesByRegion(String region);
}
自定义 repo 实现
Spring Data 还支持自定义 repo 实现,它也可用于处理查询返回到 Record 类的映射。要使用自定义 repo 实现,请定义一个接口:
public interface CustomAdvocateRepo {
Iterable findAllNameRecords();
}
在对Spring Data repo的extends中添加接口:
public interface AdvocateRepo
extends CrudRepository
CustomAdvocateRepo {
}
并提供 repo 的实现。本例中使用了 RowMapper 来处理查询结果的映射:
public class CustomAdvocateRepoImpl implements CustomAdvocateRepo {
private JdbcTemplate jdbcTemplate;
protected CustomAdvocateRepoImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
class AdvocateRecordDtoRowMapper
implements RowMapper {
@Override
public AdvocateNameRecord
mapRow(ResultSet rs, int rowNum) throws SQLException {
return new AdvocateNameRecord(
rs.getString("f_name"), rs.getString("l_name"));
}
}
@Override
public Iterable findAllNameRecords() {
return jdbcTemplate.query(
"SELECT f_name, l_name FROM advocates",
new AdvocateRecordDtoRowMapper());
}
}
https://www.jdon.com/69046.html