说我有两个实体如下:
@Data
@Entity
@Table(name = "reward")
public class Reward{
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(length = 36)
private String id;
private String sn;
//other fields
}
@Data
@Entity
@Table(name = "strategy_rewards")
public class RewardUserRelation{
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(length = 36)
private String id;
private String uid;
private String rid; //reward id
//other fields;
}
我已经编写了一些其他规范,如下所示,从mysql中过滤我的奖励数据并将其返回给其他服务:
public static Specification<Reward> withSn(String sn) {
return (root, query, builder) -> builder
.like(root.get("sn"), "%" +sn + "%");
}
Page result = rewardRepository.findAll(where(sn == null ? null :
RewardSpecs.withSn(sn)), pageable));
但现在我想完成一个规范,该规范可以过滤其ID未出现在RewardUserRelation表中的奖励,这意味着这些奖励未被使用。我已经搜索了几个规范教程,但仍然无法解决。我应该使用Join Criteria Api吗?但我不知道该怎么做。 :(
更新:不知何故,我设法通过事先从关系表中选择所有并使用Expression.in()来解决这个问题,但仍然想知道是否有更好的方法来执行此操作。
List<String> idList =strategyRewardRelationRepository.getByDeleted(false).stream()
.map(StrategyRewardRelation::getRid).distinct().collect(Collectors.toList());
public static Specification<Reward> withUsed(Boolean used, List<String> idList) {
return (root, query, builder) -> {
return used ? root.get("id").in(idList) : root.get("id").in(idList).not();
};
}
答案 0 :(得分:0)
Specification
中的两次联接可能是解决方法:
case "propertyId":
Join<SourceEntity, Item> itemJoin = root.join("item");
Join<SourceEntity, ItemSourceDetail> itemDetailJoin = itemJoin.join("itemSourceDetail");
try {
filterValue = criteria.getString(key).toString();
filters.add(itemDetailJoin.get("propertyId").in(Long.valueOf(filterValue)));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;