我的实体A与实体B的关系为1-1。
实体B与实体C的关系为1-1。
我要使用“规范”实现复杂的过滤搜索。 此外,我将JOIN FETCH配置为从UserEntity到BadgeEntity,从BadgeEntity到BadgeTypEntity,以便在单个查询中检索带有“ BadgeType”的UserEntity。
没有规格,直接使用标准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;
}
电子邮件过滤器规范
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;
}
}
NAME过滤器规范
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;
}
};
是否有办法使用“规范”巧妙地解决此问题?
答案 0 :(得分:0)
您可以实现多级实体子映射。
示例:
criteriaBuilder.like(root.get("badge").get("badgeType").get("email"),this.email);