如何在JPA中使用Plural Attributes进行条件查询?
How to use Plural Attributes in JPA for criteria query?
这是我要从中生成查询的根实体 ArticleType
。我想获取一个集合 articleTypeVarianteOptionCollection
并为该集合添加一些条件。
public class ArticleType extends BaseEntity implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "art_typ_index")
private Integer artTypIndex;
@Column(name = "art_typ_code", nullable = false)
private String artTypCode;
@OneToMany(mappedBy = "atvoIndexArticleType", fetch = FetchType.LAZY)
private Set<ArticleTypeVarianteOption> articleTypeVarianteOptionCollection;
public Integer getArtTypIndex()
{
return artTypIndex;
}
public void setArtTypIndex(Integer artTypIndex)
{
this.artTypIndex = artTypIndex;
}
public String getArtTypCode()
{
return artTypCode;
}
public void setArtTypCode(String artTypCode)
{
this.artTypCode = artTypCode;
}
@XmlTransient
public Set<ArticleTypeVarianteOption> getArticleTypeVarianteOptionCollection()
{
return articleTypeVarianteOptionCollection;
}
public void setArticleTypeVarianteOptionCollection(Set<ArticleTypeVarianteOption> articleTypeVarianteOptionCollection)
{
this.articleTypeVarianteOptionCollection = articleTypeVarianteOptionCollection;
}
}
这是我的 OptionArticle
实体:
public class ArticleTypeOption extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ato_index")
private Integer atoIndex;
@Column(name = "ato_isremoved")
private Integer atoIsremoved;
@JoinColumn(name = "ato_index_art_type", referencedColumnName = "art_typ_index")
@ManyToOne(fetch = FetchType.LAZY)
private ArticleType atoIndexArtType;
@JoinColumn(name = "ato_index_option", referencedColumnName = "opt_art_index")
@ManyToOne(fetch = FetchType.LAZY)
private OptionArticle atoIndexOption;
public ArticleTypeOption() {
}
public ArticleTypeOption(Integer atoIndex) {
this.atoIndex = atoIndex;
}
public Integer getAtoIndex() {
return atoIndex;
}
public void setAtoIndex(Integer atoIndex) {
this.atoIndex = atoIndex;
}
public Integer getAtoIsremoved() {
return atoIsremoved;
}
public void setAtoIsremoved(Integer atoIsremoved) {
this.atoIsremoved = atoIsremoved;
}
public ArticleType getAtoIndexArtType() {
return atoIndexArtType;
}
public void setAtoIndexArtType(ArticleType atoIndexArtType) {
this.atoIndexArtType = atoIndexArtType;
}
public OptionArticle getAtoIndexOption() {
return atoIndexOption;
}
public void setAtoIndexOption(OptionArticle atoIndexOption) {
this.atoIndexOption = atoIndexOption;
}
}
我的查询是:
SELECT
articleType
FROM ArticleType articleType
LEFT JOIN articleType.articleTypeVarianteOptionCollection atOption
where atOption.atoIsremoved = 0;
我已经在 jpa 的 where 子句中尝试过这个:-
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQry = criteriaBuilder.createQuery(entityClass);
Root<T> root = criteriaQry.from(entityClass);
criteriaQry.select(root).distinct(true);
for (PluralAttribute<? super T, ?, ?> pa : root.getModel().getPluralAttributes())
{
System.out.println(pa.getName());
System.out.println(pa.getCollectionType());
}
现在如何使用此 PluralAttribute 添加 where 子句?
提前致谢。
首先,让我们从 SQL 查询开始:
SELECT
articleType
FROM ArticleType articleType
LEFT JOIN articleType.articleTypeVarianteOptionCollection atOption
where atOption.atoIsremoved = 0;
每当您在 WHERE
条件中使用 LEFT JOIN
table 时,JOIN 的行为将类似于 INNER JOIN
.
所以,这就是您将此 SQL 查询转换为标准的方式:
Integer atoIsremoved = ...;
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<ArticleType> criteria = criteriaBuilder.createQuery(ArticleType.class);
Root<ArticleType> root = criteria.from(ArticleType.class);
criteria.select(root).distinct(true);
Join<ArticleType, ArticleTypeVarianteOption> joinOptions = root.join(
"articleTypeVarianteOptionCollection",
JoinType.LEFT
);
criteria.where(
criteriaBuilder.or(
criteriaBuilder.isNull(
joinOptions.get("id")
),
criteriaBuilder.equal(
joinOptions.get("atoIsremoved"), atoIsremoved
)
)
);
TypedQuery<ArticleType> query = entityManager.createQuery(criteria);
List<ArticleType> resultList = query.getResultList();
要添加 where
子句(条件),我必须使用下面指定的联接作为 joinOptions
。
为了检索数据,我必须将这些数据作为 fetch Relation 来获取。
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<ArticleType> criteria = criteriaBuilder.createQuery(ArticleType.class);
Root<ArticleType> root = criteria.from(ArticleType.class);
criteria.select(root).distinct(true);
Join<ArticleType, ArticleTypeVarianteOption> joinOptions = root.join("articleTypeVarianteOptionCollection");
if (fetchRelations != null)
{
for (String fetchReln : fetchRelations)
{
FetchParent<ArticleType, ArticleType> fetch = root;
for (String reln : fetchReln.split("\."))
{
FetchParent<ArticleType, ArticleType> originalFetch = fetch;
for (String childReln : reln.split(":"))
{
fetch = originalFetch.fetch(childReln, JoinType.LEFT);
}
originalFetch = fetch;
}
}
}
Predicate[] predArray = new Predicate[2];
predArray[0] = criteriaBuilder.equal(joinOptions.get("atvoIndexConfig"), configId);
predArray[1] = criteriaBuilder.equal(joinOptions.get("atvoIndexArticleType"), articleTypeId);
criteria.where(predArray);
TypedQuery<ArticleType> typedQry = entityManager.createQuery(criteria);
ArticleType articleTypeResult;
try
{
articleTypeResult = typedQry.getSingleResult();
}
catch (NoResultException ex)
{
articleTypeResult = null;
}
return articleTypeResult;
使用 JPQL 可以实现您的需求。该查询类似于条件解决方案,但对我来说更具可读性:
SELECT distinct a FROM ArticleType a
LEFT JOIN FETCH a.articleTypeViarianteOptionCollection atOption
WHERE atOption is null OR atOption.atoIsremoved=0
你可以这样使用:
Fetch artTypeFetch = root.fetch("atoIndexArtType", JoinType.LEFT);
artTypeFetch.fetch("articleTypeVarianteOptionCollection", JoinType.LEFT);
这是我要从中生成查询的根实体 ArticleType
。我想获取一个集合 articleTypeVarianteOptionCollection
并为该集合添加一些条件。
public class ArticleType extends BaseEntity implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "art_typ_index")
private Integer artTypIndex;
@Column(name = "art_typ_code", nullable = false)
private String artTypCode;
@OneToMany(mappedBy = "atvoIndexArticleType", fetch = FetchType.LAZY)
private Set<ArticleTypeVarianteOption> articleTypeVarianteOptionCollection;
public Integer getArtTypIndex()
{
return artTypIndex;
}
public void setArtTypIndex(Integer artTypIndex)
{
this.artTypIndex = artTypIndex;
}
public String getArtTypCode()
{
return artTypCode;
}
public void setArtTypCode(String artTypCode)
{
this.artTypCode = artTypCode;
}
@XmlTransient
public Set<ArticleTypeVarianteOption> getArticleTypeVarianteOptionCollection()
{
return articleTypeVarianteOptionCollection;
}
public void setArticleTypeVarianteOptionCollection(Set<ArticleTypeVarianteOption> articleTypeVarianteOptionCollection)
{
this.articleTypeVarianteOptionCollection = articleTypeVarianteOptionCollection;
}
}
这是我的 OptionArticle
实体:
public class ArticleTypeOption extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ato_index")
private Integer atoIndex;
@Column(name = "ato_isremoved")
private Integer atoIsremoved;
@JoinColumn(name = "ato_index_art_type", referencedColumnName = "art_typ_index")
@ManyToOne(fetch = FetchType.LAZY)
private ArticleType atoIndexArtType;
@JoinColumn(name = "ato_index_option", referencedColumnName = "opt_art_index")
@ManyToOne(fetch = FetchType.LAZY)
private OptionArticle atoIndexOption;
public ArticleTypeOption() {
}
public ArticleTypeOption(Integer atoIndex) {
this.atoIndex = atoIndex;
}
public Integer getAtoIndex() {
return atoIndex;
}
public void setAtoIndex(Integer atoIndex) {
this.atoIndex = atoIndex;
}
public Integer getAtoIsremoved() {
return atoIsremoved;
}
public void setAtoIsremoved(Integer atoIsremoved) {
this.atoIsremoved = atoIsremoved;
}
public ArticleType getAtoIndexArtType() {
return atoIndexArtType;
}
public void setAtoIndexArtType(ArticleType atoIndexArtType) {
this.atoIndexArtType = atoIndexArtType;
}
public OptionArticle getAtoIndexOption() {
return atoIndexOption;
}
public void setAtoIndexOption(OptionArticle atoIndexOption) {
this.atoIndexOption = atoIndexOption;
}
}
我的查询是:
SELECT
articleType
FROM ArticleType articleType
LEFT JOIN articleType.articleTypeVarianteOptionCollection atOption
where atOption.atoIsremoved = 0;
我已经在 jpa 的 where 子句中尝试过这个:-
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQry = criteriaBuilder.createQuery(entityClass);
Root<T> root = criteriaQry.from(entityClass);
criteriaQry.select(root).distinct(true);
for (PluralAttribute<? super T, ?, ?> pa : root.getModel().getPluralAttributes())
{
System.out.println(pa.getName());
System.out.println(pa.getCollectionType());
}
现在如何使用此 PluralAttribute 添加 where 子句?
提前致谢。
首先,让我们从 SQL 查询开始:
SELECT
articleType
FROM ArticleType articleType
LEFT JOIN articleType.articleTypeVarianteOptionCollection atOption
where atOption.atoIsremoved = 0;
每当您在 WHERE
条件中使用 LEFT JOIN
table 时,JOIN 的行为将类似于 INNER JOIN
.
所以,这就是您将此 SQL 查询转换为标准的方式:
Integer atoIsremoved = ...;
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<ArticleType> criteria = criteriaBuilder.createQuery(ArticleType.class);
Root<ArticleType> root = criteria.from(ArticleType.class);
criteria.select(root).distinct(true);
Join<ArticleType, ArticleTypeVarianteOption> joinOptions = root.join(
"articleTypeVarianteOptionCollection",
JoinType.LEFT
);
criteria.where(
criteriaBuilder.or(
criteriaBuilder.isNull(
joinOptions.get("id")
),
criteriaBuilder.equal(
joinOptions.get("atoIsremoved"), atoIsremoved
)
)
);
TypedQuery<ArticleType> query = entityManager.createQuery(criteria);
List<ArticleType> resultList = query.getResultList();
要添加 where
子句(条件),我必须使用下面指定的联接作为 joinOptions
。
为了检索数据,我必须将这些数据作为 fetch Relation 来获取。
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<ArticleType> criteria = criteriaBuilder.createQuery(ArticleType.class);
Root<ArticleType> root = criteria.from(ArticleType.class);
criteria.select(root).distinct(true);
Join<ArticleType, ArticleTypeVarianteOption> joinOptions = root.join("articleTypeVarianteOptionCollection");
if (fetchRelations != null)
{
for (String fetchReln : fetchRelations)
{
FetchParent<ArticleType, ArticleType> fetch = root;
for (String reln : fetchReln.split("\."))
{
FetchParent<ArticleType, ArticleType> originalFetch = fetch;
for (String childReln : reln.split(":"))
{
fetch = originalFetch.fetch(childReln, JoinType.LEFT);
}
originalFetch = fetch;
}
}
}
Predicate[] predArray = new Predicate[2];
predArray[0] = criteriaBuilder.equal(joinOptions.get("atvoIndexConfig"), configId);
predArray[1] = criteriaBuilder.equal(joinOptions.get("atvoIndexArticleType"), articleTypeId);
criteria.where(predArray);
TypedQuery<ArticleType> typedQry = entityManager.createQuery(criteria);
ArticleType articleTypeResult;
try
{
articleTypeResult = typedQry.getSingleResult();
}
catch (NoResultException ex)
{
articleTypeResult = null;
}
return articleTypeResult;
使用 JPQL 可以实现您的需求。该查询类似于条件解决方案,但对我来说更具可读性:
SELECT distinct a FROM ArticleType a
LEFT JOIN FETCH a.articleTypeViarianteOptionCollection atOption
WHERE atOption is null OR atOption.atoIsremoved=0
你可以这样使用:
Fetch artTypeFetch = root.fetch("atoIndexArtType", JoinType.LEFT);
artTypeFetch.fetch("articleTypeVarianteOptionCollection", JoinType.LEFT);