JPA注解如何基于已完成的关联实现二次表关联?
JPA跨表关联解决方案(LoginsActive -> Logins -> Profiles)
方案一:通过中间实体间接获取(最省事)
先检查你的LoginEntity是不是已经配好了和ProfileEntity的关联,比如:
public class LoginEntity ... { ... @OneToOne @JoinColumn(name = "profileUUID", updatable = false, insertable = false) private ProfileEntity profileEntity; ... }
要是已经配了,那LoginsActiveEntity里根本不用加额外的JPA注解,直接写个getter方法就行:
public class LoginsActiveEntity ... { ... @OneToOne @JoinColumn(name = "loginUUID", updatable = false, insertable = false) private LoginEntity loginEntity; // 直接从关联的loginEntity里拿profile public ProfileEntity getProfileEntity() { return loginEntity != null ? loginEntity.getProfileEntity() : null; } ... }
这种方式逻辑直白,JPQL里想查的话直接写la.loginEntity.profileEntity就行,完全够用。
方案二:直接用JPA注解映射跨表关联
要是你非得把profileEntity做成LoginsActiveEntity的直接持久化属性(比如要直接在实体上写查询条件),可以用@JoinFormula实现:
public class LoginsActiveEntity ... { ... private String loginUUID; @OneToOne @JoinColumn(name = "loginUUID", updatable = false, insertable = false) private LoginEntity loginEntity; // 通过子查询拿到对应profileUUID,再关联Profiles表 @OneToOne(fetch = FetchType.LAZY) @JoinFormula(value = "(SELECT l.profileUUID FROM logins l WHERE l.loginUUID = loginUUID)") @JoinColumn(name = "profileUUID", referencedColumnName = "profileUUID", insertable = false, updatable = false) private ProfileEntity profileEntity; ... }
这里@JoinFormula会生成一个子查询,根据当前loginsActive的loginUUID去logins表里找对应的profileUUID,再用这个ID关联profiles表。注意logins表的loginUUID得是唯一的,不然一对一关联会出问题。
注意点
- 必须保证
logins表的loginUUID是唯一键,不然一对一关联会数据混乱。 - 方案二建议加
fetch = FetchType.LAZY,避免每次查LoginsActive都顺带把Profile也查出来,浪费性能。 - 两种方案都不用改数据库,全靠JPA注解搞定。
内容的提问来源于stack exchange,提问作者Telegard
相关产品推荐
相关产品推荐

