Java for Web学习笔记(一二一):搜索(3)JPA的动态条件搜索(下)
程序员文章站
2022-04-22 13:39:40
...
例子的具体实现
仓库的实现
使用spring data,增加自定义接口SearchableRepository,具体如下:
public interface PersonRepository extends CrudRepository<Person, Long>, SearchableRepository<Person>{
}
public class PersonRepositoryImpl extends AbstractSearchableJpaRepository<Person>{
}
service的实现
public interface PersonService {
... ...
Page<Person> searchPeople(SearchCriteria searchCriteria, Pageable pageable);
}
@Service
public class DefaultPersonService implements PersonService{
@Inject PersonRepository repository;
......
@Override
@Transactional
public Page<Person> searchPeople(SearchCriteria searchCriteria, Pageable pageable) {
return this.repository.search(searchCriteria, pageable);
}
}
controller的实现
public String find(Map<String, Object> model, SearchForm form,Pageable pageable) throws ParseException{
SearchCriteria criteria = SearchCriteria.Builder.create();
if(form.isIncludeFirstName())
criteria.add(new Criterion("firstName", Criterion.Operator.EQ, form.getFirstName()));
if(form.isIncludeMiddleInitial())
criteria.add(new Criterion("middleInitial", Criterion.Operator.EQ, form.getMiddleInitial()));
if(form.isIncludeLastName())
criteria.add(new Criterion("lastName", Criterion.Operator.EQ, form.getLastName()));
if(form.isIncludeState())
criteria.add(new Criterion("state", Criterion.Operator.EQ, form.getState()));
if(form.isIncludeCountry())
criteria.add(new Criterion("country", Criterion.Operator.EQ, form.getCountry()));
if(form.isIncludeBirthDate())
criteria.add(new Criterion("birthDate", Criterion.Operator.EQ,
new Date(new SimpleDateFormat(dateFormatter).parse(form.getBirthDate()).getTime() )));
if(form.isIncludeGender())
criteria.add(new Criterion("gender", Criterion.Operator.EQ, form.getGender()));
if(form.isIncludeRace())
criteria.add(new Criterion("race", Criterion.Operator.EQ, form.getRace()));
if(form.isIncludeEthnicity())
criteria.add(new Criterion("ethnicity", Criterion.Operator.EQ, form.getEthnicity()));
model.put("searchForm", form);
model.put("results", this.personService.searchPeople(criteria, pageable));
return "people/find";
}
对于OR
我们可以看出通用的Criteria JPA查询功能很强大,但也很危险,用户可能会进行任意的查询,影响了性能。
在例子中,我们只给出了AND的方式,其实OR的方式也是类型。我们看看JPA如何处理AND和OR同时存在的条件。
//【例子1】名字中有n的无论是姓还是名(OR),同时要求生日为b(AND)关系。
criteria.select(root).where(
builder.or(
builder.equal(root.get("lastName"), n),
builder.equal(root.get("firstName"), n)
),
builder.equal(root.get("birthDate"), b)
);
//【例子2】和例子1一样,只要是体现一个AND和OR嵌入的关系
criteria.select(root).where(
builder.and(
builder.or(
builder.equal(root.get("lastName"), n),
builder.equal(root.get("firstName"), n)
),
builder.equal(root.get("birthDate"), b)
)
);
//【例子3】基于嵌入关系,提供的要给复杂的例子
pageCriteria.select(pageRoot).where(
builder.or(
builder.and(
builder.equal(expr),
builder.equal(expr),
pageRoot.get("property").in(expr)
),
builder.or(
builder.lessThan(expr),
builder.greaterThanOrEqualTo(expr)
)
),
builder.and(
builder.equal(expr),
builder.greaterThan(expr)
)
);
相关链接:我的Professional Java for Web Applications相关文章