Java Persistence:根据运行时参数连接不同的列
Posted
技术标签:
【中文标题】Java Persistence:根据运行时参数连接不同的列【英文标题】:Java Persistence: join different columns dependent on runtime parameter 【发布时间】:2019-08-05 15:12:15 【问题描述】:考虑以下示例:
我想使用 JPA/Hibernate 来查询左侧的对象,同时直接加入标签。但是,使用哪个标签列由动态会话参数确定。对于某些用户,它是“英语”,而对于其他用户,它是“德语”。因此,我的联接需要针对仅在运行时在动态变量范围内定义的列。
我看到了以下(理论上的)解决方案:
-
之后不要使用连接和查询标签
让连接根据运行时参数寻址列
将语言设为列并使用复合键加入标签(同时提供运行时参数作为复合键的第二部分)
使用视图创建两个不同的翻译表(一个用于德语,一个用于英语);使用 runtime 参数动态加入不同的表
虽然解决方案 1 是可行的,但它效率低下并且涉及大量样板代码。另一方面,我无法为 2-4 提出切实可行的解决方案。
此外,鉴于标签必须由数据库管理 - 这种用例的最佳实践解决方案是什么?
【问题讨论】:
'我的联接需要定位一个仅在运行时在动态变量范围内定义的列' - 我不知道如何。你不是一直加入Label_ID = ID
吗?
附带说明一下,翻译多久会更改一次?除非可以从您的应用程序外部修改它们,否则我会认真考虑将它们缓存在内存中
@crizzis 是的,我们总是加入 Label_ID = ID
。问题在于使用两者(德语/英语)的哪个数据列来填充属性。这些字符串实际上来自我们的应用程序之外,这就是我们需要数据库中的数据的原因。
【参考方案1】:
如果有一个带有某种语言代码的参数,我假设这个问题可以用CASE
子句来解决,类似这样:
SELECT t0.id, t0.location, CASE WHEN (?1 = 1) THEN t1.english ELSE t1.german END AS label
FROM Location t0 INNER JOIN Translation t1 ON (t0.label_id = t1.id)
并且可以使用FluentJPA构建查询:
public List<TranslatedLocation> getTranslatedLocations(int langCode)
FluentQuery query = FluentJPA.SQL((Location l,
Translation t) ->
String trans = CASE(WHEN(langCode == 1).THEN(t.getEnglish())
.ELSE(t.getGerman())).END();
String label = alias(trans, TranslatedLocation::getLabel);
SELECT(l.getId(), l.getLocation(), label);
FROM(l).JOIN(t).ON(l.getTranslation() == t);
);
return query.createQuery(em, TranslatedLocation.class).getResultList();
生成的 SQL:
SELECT t0.id, t0.location,
CASE WHEN (?1 = 1) THEN t1.english ELSE t1.german END AS label
FROM Location t0 INNER JOIN Translation t1 ON (t0.label_id = t1.id)
实体声明:
@Entity
@Data //lombok
public static class Location
@Id
private int id;
private String location;
@ManyToOne
@JoinColumn(name = "label_id")
private Translation translation;
@Entity
@Data //lombok
public static class Translation
@Id
private int id;
private String english;
private String german;
@Tuple
@Getter //lombok
public static class TranslatedLocation
@Id
private int id;
private String location;
private String label;
【讨论】:
以上是关于Java Persistence:根据运行时参数连接不同的列的主要内容,如果未能解决你的问题,请参考以下文章
关于 keepalived+lvs 中参数 persistence_timeout 的说明
创建没有 persistence.xml 配置文件的 JPA EntityManager
休眠 5 - java.lang.NoSuchMethodError: javax.persistence.Table.indexes()