【发布时间】:2020-02-29 21:52:11
【问题描述】:
我有实体 A 与实体 B 相关的 1-1。
实体 B 与实体 C 1-1 相关。
- 用户实体
- 徽章实体
- BadgeTypEntity
- 徽章实体
我想使用规范实现复杂的过滤搜索。 此外,我将配置从 UserEntity 到 BadgeEntity 以及从 BadgeEntity 到 BadgeTypEntity 的 JOIN FETCH,以在单个查询中检索 UserEntity 及其“BadgeType”。
无需规范,直接使用条件 API,很容易解决在需要的地方配置所需的提取。
我第一次尝试: https://github.com/tkaczmarzyk/specification-arg-resolver#enabling-spec-annotations-in-your-spring-app 但似乎可以只配置一级获取(UserEntity --> BadgeEntity)
所以,我尝试提供一个“假”规范,只是将所需的 JOIN FETCH 添加到查询中,但我认为这是一个不好的解决方法。
用户实体
public class UserEntity
{
private String name;
private String email;
@Fetch(FetchMode.JOIN)
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "BADGE_ID")
private BadgeEntity badge;
...
}
徽章实体
public class BadgeEntity
{
@Fetch(FetchMode.JOIN)
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "BADGE_TYPE_ID")
private BadgeTypeEntity badgeType;
...
}
BadgeType 实体
public class BadgeTypeEntity
{
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "BADGE_TYPE_ID")
private Integer badgeTypeId;
@Column(name = "CODE")
private String code;
}
EMAIL 过滤器规范
public class UsersEmailSpec implements Specification<UserEntity>
{
private String email;
public UsersEmailSpec(String email)
{
this.email = email;
}
@Override
public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
{
Predicate result = null;
if(StringUtils.isNotEmpty(this.email))
{
result = criteriaBuilder.like(root.get(UserEntity_.email),this.email);
}
return result;
}
}
名称过滤器规范
public class UsersNameSpec implements Specification<UserEntity>
{
private String name;
public UsersNameSpec(String name)
{
this.name = name;
}
@Override
public Predicate toPredicate(Root<UserEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
{
Predicate result = null;
if(StringUtils.isNotEmpty(this.name))
{
result = criteriaBuilder.like(root.get(UserEntity_.name),this.name);
}
return result;
}
}
配置 FETCH JOIN 的 FAKE 规范
Specification conjunctionSpec = new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
Fetch fetch = root.fetch(UserEntity_.badge, JoinType.INNER).fetch(BadgeEntity_.badgeType, JoinType.INNER);
return null;
}
};
有没有办法使用规范巧妙地解决这个问题?
【问题讨论】:
-
嘿,你做到了吗?
标签: hibernate jpa spring-data-jpa dsl criteria-api