【发布时间】:2014-10-06 10:17:03
【问题描述】:
我有一个 MVC 控制器,它以 JSON 形式返回联系人列表。在前端,我使用 jquery 数据表插件。前端有一个搜索栏来过滤实体列表。
我的实体:
@Entity
public class Contact implements Serializable {
protected final static Logger LOGGER = LoggerFactory.getLogger(Contact.class);
private static final long serialVersionUID = -3691953100225344828L;
@Id
@GeneratedValue(generator = "hibernate-uuid")
@Column(length = 36, unique = true)
private String id;
@Version
@JsonIgnore
private int version;
private String firstname;
private String lastname;
@ManyToOne
private Company company;
... GETTER/SETTER ...
}
和
@Entity
public class Company implements Serializable {
protected final static Logger LOGGER = LoggerFactory.getLogger(Company.class);
private static final long serialVersionUID = -7863930456400256944L;
@Id
@GeneratedValue(generator = "hibernate-uuid")
@Column(length = 36, unique = true)
private String id;
private String companyName;
private String companyName1;
private String companyName2;
... GETTER/SETTER ...
}
我对搜索字段使用服务器端处理,在服务器端我使用规范。
public class ContactSpecifications {
public static Specification<Contact> contactFirstnameLike(final String needle) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.like(cb.lower(root.<String> get(Contact_.firstname)), needle != null ? needle.toLowerCase() : null);
}
};
}
public static Specification<Contact> contactLastnameLike(final String needle) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.like(cb.lower(root.<String> get(Contact_.lastname)), needle != null ? needle.toLowerCase() : null);
}
};
}
public static Specification<Contact> contactFullnameLike(final String needle) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.or(cb.like(cb.lower(root.<String> get(Contact_.lastname)), needle != null ? needle.toLowerCase() : null), cb.like(cb.lower(root.<String> get(Contact_.firstname)), needle != null ? needle.toLowerCase() : null));
}
};
}
public static Specification<Contact> contactCompanyCompanyNameLike(final String needle) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Path<Company> company = root.<Company> get(Contact_.company);
return cb.like(cb.lower(company.<String> get(Company_.companyName)), needle != null ? needle.toLowerCase() : null);
}
};
}
}
我的数据库查询
contactRepository.findAll(specifications, new PageRequest(0,100));
规格是
specifications = Specifications.where(ContactSpecifications.contactFullnameLike(needle)).or(ContactSpecifications.contactCompanyCompanyNameLike(needle));
needle 是来自前端的搜索键,并带有周围的 % 掩码(例如“%asdf%”)
我的问题是,如果联系人没有公司,则说明无法按预期工作。
例如我有 3 个联系人:
- 姓:Schmitz,名字:Max,公司:(null)
- 姓:Schmitz,名字:Moritz,公司:XY
-
姓:Muster,名字:Max,公司:XY
- 如果我现在输入 Schmitz 作为搜索键,则只返回联系人 2,不返回联系人 1。
- 如果我输入 max 作为搜索键,则只返回联系人 3,不返回联系人 1
- 仅当搜索键为 null/空时,才会返回所有联系人
我错过了什么?
亲切的问候 里齐
【问题讨论】:
标签: spring-data-jpa specifications many-to-one