使用 JPA Criteria API 到 return 集合 属性 包含特定值的所有对象
Using JPA Criteria API to return all object where a Collection property contains a certain value
我正在尝试为我的 Spring-data-jpa 项目动态创建一个 Specification
这是我目前的规格:
public class DemandsSpecs implements Specification<SvDem> {
private static final Logger LOG = LogManager.getLogger();
private final DemandsCritera critera;
private final List<Predicate> predicateList;
public DemandsSpecs(final DemandsCritera critera) {
this.critera = critera;
this.predicateList = new ArrayList<>();
}
@Override
public Predicate toPredicate(final Root<SvDem> root,
final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
this.predicateList.add(cb.between(root.get(SvDem_.hdCreation), critera.getBegin(), critera.getEnd()));
if (critera.getSoc() != null) {
LOG.debug("socId {}", critera.getSoc());
this.predicateList.add(cb.equal(root.get(SvDem_.socId), critera.getSoc()));
}
if (critera.getManagementAct() != null) {
LOG.debug("actgesId {}", critera.getManagementAct());
this.predicateList.add(cb.equal(root.get(SvDem_.actgesId), critera.getManagementAct()));
}
if (critera.getStatus() != null) {
LOG.debug("statutId {}", critera.getStatus());
this.predicateList.add(cb.equal(root.get(SvDem_.statutId), critera.getStatus()));
}
if (!StringUtils.isBlank(critera.getId())) {
LOG.debug("id {}", critera.getId());
this.predicateList.add(cb.like(root.get(SvDem_.id), '%' + critera.getId() + '%'));
}
return query.where(cb.and(predicateList.toArray(new Predicate[predicateList.size()])))
.orderBy(cb.desc(root.get("hdCreation")))
.getRestriction();
}
}
DemandsCritera
还有一个String
属性metadata
.
public class DemandsCritera implements Serializable {
private static final Long serialVersionUID = 1L;
private Date begin;
private Date end;
private RfActges managementAct;
private String metadata;
private RfStatut status;
private RfSoc soc;
private String id;
/* getters and setters */
}
SvDem 有一个 属性 svMetaCollection
,这是一个 Collection<SvMeta>
。
@Entity
@Table(name = "sv_dem")
public class SvDem implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
private String id;
@Basic(optional = false)
@Column(name = "HD_CREATION")
@Temporal(TemporalType.TIMESTAMP)
private Date hdCreation;
@Lob
private String user;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "svDem")
@JsonManagedReference
private Collection<SvMeta> svMetaCollection;
@JoinColumn(name = "ACTGES_ID", referencedColumnName = "ID")
@ManyToOne(optional = false)
private RfActges actgesId;
@JoinColumn(name = "STATUT_ID", referencedColumnName = "ID")
@ManyToOne(optional = false)
private RfStatut statutId;
@JoinColumn(name = "SOC_ID", referencedColumnName = "ID")
@ManyToOne(optional = false)
private RfSoc socId;
/* getters, setters and other irrelevant properties */
}
SvMeta 对象有一个 String
属性 value
@Entity
@Table(name = "sv_meta")
public class SvMeta implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected SvMetaPK svMetaPK;
@Basic(optional = false)
@Lob
private String value;
@JoinColumn(name = "META_ID", referencedColumnName = "ID", insertable = false, updatable = false)
@ManyToOne(optional = false)
private RfMeta rfMeta;
@JoinColumn(name = "DEM_ID", referencedColumnName = "ID", insertable = false, updatable = false)
@ManyToOne(optional = false)
@JsonBackReference
private SvDem svDem;
}
我想 return 所有 SvDem
其中任何 SvMeta
有一个 value
等于 DemandsCritera.metadata
。
我怎样才能做到这一点?
我只需要将其添加到 DemandsSpecs
的 toPredicate
方法中:
if (!StringUtils.isBlank(critera.getMetadata())) {
LOG.debug("metadata {}", critera.getMetadata());
Join<SvDem, SvMeta> metas = root.join(SvDem_.svMetaCollection);
this.predicateList.add(cb.equal(metas.get(SvMeta_.value), critera.getMetadata()));
}
我正在尝试为我的 Spring-data-jpa 项目动态创建一个 Specification
这是我目前的规格:
public class DemandsSpecs implements Specification<SvDem> {
private static final Logger LOG = LogManager.getLogger();
private final DemandsCritera critera;
private final List<Predicate> predicateList;
public DemandsSpecs(final DemandsCritera critera) {
this.critera = critera;
this.predicateList = new ArrayList<>();
}
@Override
public Predicate toPredicate(final Root<SvDem> root,
final CriteriaQuery<?> query,
final CriteriaBuilder cb) {
this.predicateList.add(cb.between(root.get(SvDem_.hdCreation), critera.getBegin(), critera.getEnd()));
if (critera.getSoc() != null) {
LOG.debug("socId {}", critera.getSoc());
this.predicateList.add(cb.equal(root.get(SvDem_.socId), critera.getSoc()));
}
if (critera.getManagementAct() != null) {
LOG.debug("actgesId {}", critera.getManagementAct());
this.predicateList.add(cb.equal(root.get(SvDem_.actgesId), critera.getManagementAct()));
}
if (critera.getStatus() != null) {
LOG.debug("statutId {}", critera.getStatus());
this.predicateList.add(cb.equal(root.get(SvDem_.statutId), critera.getStatus()));
}
if (!StringUtils.isBlank(critera.getId())) {
LOG.debug("id {}", critera.getId());
this.predicateList.add(cb.like(root.get(SvDem_.id), '%' + critera.getId() + '%'));
}
return query.where(cb.and(predicateList.toArray(new Predicate[predicateList.size()])))
.orderBy(cb.desc(root.get("hdCreation")))
.getRestriction();
}
}
DemandsCritera
还有一个String
属性metadata
.
public class DemandsCritera implements Serializable {
private static final Long serialVersionUID = 1L;
private Date begin;
private Date end;
private RfActges managementAct;
private String metadata;
private RfStatut status;
private RfSoc soc;
private String id;
/* getters and setters */
}
SvDem 有一个 属性 svMetaCollection
,这是一个 Collection<SvMeta>
。
@Entity
@Table(name = "sv_dem")
public class SvDem implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
private String id;
@Basic(optional = false)
@Column(name = "HD_CREATION")
@Temporal(TemporalType.TIMESTAMP)
private Date hdCreation;
@Lob
private String user;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "svDem")
@JsonManagedReference
private Collection<SvMeta> svMetaCollection;
@JoinColumn(name = "ACTGES_ID", referencedColumnName = "ID")
@ManyToOne(optional = false)
private RfActges actgesId;
@JoinColumn(name = "STATUT_ID", referencedColumnName = "ID")
@ManyToOne(optional = false)
private RfStatut statutId;
@JoinColumn(name = "SOC_ID", referencedColumnName = "ID")
@ManyToOne(optional = false)
private RfSoc socId;
/* getters, setters and other irrelevant properties */
}
SvMeta 对象有一个 String
属性 value
@Entity
@Table(name = "sv_meta")
public class SvMeta implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected SvMetaPK svMetaPK;
@Basic(optional = false)
@Lob
private String value;
@JoinColumn(name = "META_ID", referencedColumnName = "ID", insertable = false, updatable = false)
@ManyToOne(optional = false)
private RfMeta rfMeta;
@JoinColumn(name = "DEM_ID", referencedColumnName = "ID", insertable = false, updatable = false)
@ManyToOne(optional = false)
@JsonBackReference
private SvDem svDem;
}
我想 return 所有 SvDem
其中任何 SvMeta
有一个 value
等于 DemandsCritera.metadata
。
我怎样才能做到这一点?
我只需要将其添加到 DemandsSpecs
的 toPredicate
方法中:
if (!StringUtils.isBlank(critera.getMetadata())) {
LOG.debug("metadata {}", critera.getMetadata());
Join<SvDem, SvMeta> metas = root.join(SvDem_.svMetaCollection);
this.predicateList.add(cb.equal(metas.get(SvMeta_.value), critera.getMetadata()));
}