gpt4 book ai didi

java - 从数据库中获取 Hibernate 实体和附加字段

转载 作者:行者123 更新时间:2023-12-01 19:14:43 25 4
gpt4 key购买 nike

我有一个相当简单的实体,名为 HUser我想计算他们到我的用户的距离。

也许,正确的方法不是在数据库中运行计算,而是在收到数据后在代码中运行计算,但是这个问题可能稍后在不同的项目中出现一次,所以我想知道如何宜早不宜迟。 :)

这是实体:

@Entity
@Table(name = "user")
@TypeDefs({
@TypeDef(name = "string-array", typeClass = StringArrayType.class),
@TypeDef(name = "pgsql_enum", typeClass = PostgreSQLEnumType.class)
})
public class HUser {
@Id
@Column(name = "id")
private UUID id;

@Column(name = "name")
private String name;

@Type(type = "pgsql_enum")
@Enumerated(EnumType.STRING)
@Column(name = "lang", columnDefinition = "LANG")
private SysLang lang;

// ... Some other ~20 fields

@Type(type = "string-array")
@Column(name = "images", columnDefinition = "TEXT[]")
private String[] imageIds;

// The new field I've just added for storing additional data
@Transient
private Double distance;
}

问题是,该实体使用一些重要的映射来填充其字段,因此我不想手动解析数据库响应。 (顺便说一下,它是com.vladmihalcea:hibernate-types-52)

有一个具有新功能的存储库:

@org.springframework.stereotype.Repository
@Qualifier(RO)
public interface ReadOnlyUserRepository extends Repository<HUser, UUID> {
// ... Some other methods there

// New function. Distance is in kilometers
@Query(nativeQuery = true, value = "" +
"SELECT u.*, " +
" 111.3199 * st_distance( " +
" st_setsrid(st_point(u.longitude, u.latitude), 4326), " +
" st_setsrid(st_point(our.longitude, our.latitude), 4326) " +
" ) " +
" FROM \"user\" u, \"user\" our " +
" WHERE our.id=:user_id AND u.id IN (:ids) " +
"ORDER BY 111.3199 * st_distance( " +
" st_setsrid(st_point(u.longitude, u.latitude), 4326), " +
" st_setsrid(st_point(our.longitude, our.latitude), 4326) " +
" ) ")
List<Object[]> getUsers(@Param("user_id") UUID userId, @Param("ids") Collection<UUID> ids);
}

考虑到111.3199 * st_distance,查询本身有点难看。重复两次,返回 List<Object[]>我不想映射到 HUser.java手动。

我觉得 Hibernate 投影可能会做我想做的事情,但是,据我所知,投影用于减少从数据库中选择的字段数量,而不是增加它们。 :/

➥ 那么,有没有办法获取具有一些 @ManyToOne 关系和非标准列映射以及一些附加列的 Hibernate 实体?

最佳答案

我考虑过使用 sql VIEW 并创建一个子类 HUserWithDistance,该子类将使用附加字段扩展 HUser,并映射 HUser 作为 @MappedSuperclass,如下所示:

CREATE VIEW user_with_distance AS
SELECT u.*,
111.3199 * st_distance(
st_setsrid(st_point(u.longitude, u.latitude), 4326),
st_setsrid(st_point(our.longitude, our.latitude), 4326)
) AS distance
FROM "user" u, "user" our
WHERE our.id = :user_id AND u.id IN (:ids)
ORDER BY 111.3199 * st_distance(
st_setsrid(st_point(u.longitude, u.latitude), 4326),
st_setsrid(st_point(our.longitude, our.latitude), 4326)
);

@Entity
@Table(name = "user")
@TypeDefs({
@TypeDef(name = "string-array", typeClass = StringArrayType.class),
@TypeDef(name = "pgsql_enum", typeClass = PostgreSQLEnumType.class)
})
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class HUser {
// ... normal fields

// Distance between this user and the user finding his matches.
@Transient
public Double getDistance() {
return null;
}
}

@Entity
@Table("user_with_distance")
public class HUserWithDistance extends HUser {
@Column(name = "distance")
private Double distance;

@Override
public Double getDistance() {
return distance;
}
}

但我认为这不是一个好主意。

关于java - 从数据库中获取 Hibernate 实体和附加字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59431026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com