欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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相关文章