我对使用Jhispter生成的QueryService不熟悉,我正在尝试使用它们来过滤实体列表。
当我过滤这个实体的字段时,它工作得很好,但是现在我必须做一些更复杂的事情。
我有这个数据集:
- 儿童〈-----我上面所说的实体
- 父级〈-----其中包含子级列表
- 祖父母〈-----它有一个
我要做的是:
- 通过www.example.com过滤查尔兹Parent.name
- 通过www.example.com过滤查尔兹GrandParent.name
所以到目前为止我所做的是:
private Specification<Child> createSpecification(ChildCriteria criteria) {
Specification<Child> specification = Specification.where(null);
if (criteria != null) {
if (criteria.getParentName() != null) {
speficiation = specification.and(buildReferringEntitySpecification(criteria.getParentName(), Child_.parent, Parent_.name));
}
if (criteria.getGrandParentName() != null) {
specification.and(buildJoinSpecification(criteria.getGrandParentName(), Child_.parent, Parent_.grandParent, GrandParent_.name));
}
}
}
子项、父项、祖父母和子项标准的摘录:
@Entity
@Table(name = "Child")
public class Child extends EntityObject {
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnoreProperties("childs")
@QueryInit("GrandParent")
private Parent parent;
}
@Entity
@Table(name = "Parent")
public class Parent extends EntityObject {
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnoreProperties("parents")
private GrandParent grandParent;
@OneToMany(mappedBy = "Parent", fetch = FetchType.LAZY)
private Set<Child> childs = new HashSet<>();
}
@Entity
@Table(name = "GrandParent")
public class GrandParent extends EntityObject {
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "GrandParent", fetch = FetchType.LAZY)
private Set<Parent> parrents = new HashSet<>();
}
public class ChildCriteria implements Serializable {
private StringFilter parentName;
private StringFilter grandParentName;
public StringFilter getParentName() {
return parentName;
}
public void setParentName(StringFilter parentName) {
this.parentName= parentName;
}
public StringFilter getGrandParentName() {
return grandParentName;
}
public void setGrandParentName(StringFilter grandParentName) {
this.grandParentName= grandParentName;
}
}
父名字的过滤器是有效的,我也想对祖父名字做同样的过滤。对于这个,我尝试了一些我在this上找到的技巧,但是没有任何效果。
通过这个链接,我目前得到的信息如下:
public class ExtendedQueryService<ENTITY> extends QueryService<ENTITY>{
protected <REFERENCE, JOIN, FILTER extends Comparable<? super FILTER>> Specification<ENTITY> buildJoinSpecification(StringFilter filter, SingularAttribute<? super ENTITY, REFERENCE> reference, SingularAttribute<REFERENCE, JOIN> joinField, SingularAttribute<JOIN, FILTER> valueField) {
Specification<ENTITY> result = Specification.where((Specification) null);
if (filter.getContains() != null) {
result = this.containsSpecification(reference, joinField, valueField, filter.getContains());
}
return result;
}
protected <REFERENCE, JOIN, FILTER> Specification<ENTITY> containsSpecification(SingularAttribute<? super ENTITY, REFERENCE> reference, SingularAttribute<REFERENCE, JOIN> joinField, SingularAttribute<JOIN, FILTER> idField, String value) {
return (root, query, builder) ->
builder.equal(root.join(reference).join(joinField).get(idField), value);
}
}
我在我的ChildQueryService中扩展了这个类,其中我使用了buildJoinSpecification方法。
如果我尝试用它过滤,它会返回一个空列表。
2条答案
按热度按时间q8l4jmvw1#
好的,我在Jhipster文档中找到了一些东西。问题是我使用了一个StringFilter,当我理解了这一点,我修改了Jhipster函数中的一些东西,如下所示:
扩展查询服务:
这样我就可以在我的ChildQueryService中执行此操作:
现在它工作得很好!看起来你可以用连接去你想要的深度,尽管我没有测试它超过2级的深度。
为了记录在案,这是我在Jhipster doc中找到的,也是我的函数所基于的:
它是这样使用的,例如:
同时使用这两种方法可以处理StringFilter和其他Filter。不过,您可能需要为某些Filter类执行特定的函数。
zphenhs42#
tech.jhipster.service.QueryService
可能很快变得复杂。我在6个月后查看我的代码,我不再明白我做了什么,不得不重新思考东西,只是因为我想添加一点东西。因此:如果可以避免,就不要使用它。对于复杂的过滤,我建议在数据库中创建一个视图,将我想要过滤的内容Map到一个String或Boolean,在Spring中创建一个实体(注意ID是非空的,并与原始实体匹配,因此只需通过视图添加字段,不要过滤掉内容或意外复制实体),然后过滤它。
SQL比使用位于hibernates
Criteria
API之上的API要简单得多,后者本身也比SQL复杂一些。在我的例子中,我想一次根据多个属性进行过滤-在
QueryService
中没有简单的方法来实现这一点,但是case
...when
...输出一个枚举,然后可以通过QuerySerivice
进行过滤是足够简单的(我将在一年内理解我所做的)。