我想在Java中用标准API进行动态搜索。
在我写的代码中,我们需要用JSON编写url栏中的每个实体。我不想写“普拉卡”。
网址:
这里我们需要写出每个实体,即使我们只搜索一个实体。类型实体,它应该为空。
我的代码如下。假设有多个实体,我想做的是使用它想要搜索的单个实体进行搜索。正如你在照片中看到的,我不想写一个我不需要的实体。你能帮我做什么吗?
我在存储库中的代码
public interface CityRepository extends JpaRepository<City, Integer> , JpaSpecificationExecutor<City> {
}
我的服务代码
@Service
public class CityServiceImp implements CityService{
private static final String CITY = "city";
private static final String PLAKA = "plaka";
@Override
public List<City> findCityByNameAndPlaka(String cityName, int plaka) {
GenericSpecification genericSpecification = new GenericSpecification<City>();
if (!cityName.equals("_"))
genericSpecification.add(new SearchCriteria(CITY,cityName, SearchOperation.EQUAL));
if (plaka != -1)
genericSpecification.add(new SearchCriteria(PLAKA,plaka, SearchOperation.EQUAL));
return cityDao.findAll(genericSpecification);
}
@Autowired
CityRepository cityDao;
我在控制器中的代码
@RestController
@RequestMapping("api/city")
public class CityController {
@Autowired
private final CityService cityService;
public CityController(CityService cityService) {
this.cityService = cityService;
@GetMapping("/query")
public List<City> query(@RequestParam String city, @RequestParam String plaka){
String c = city;
int p;
if (city.length() == 0)
c = "_";
if (plaka.length() == 0) {
p = -1;
}
else
p = Integer.parseInt(plaka);
return cityService.findCityByNameAndPlaka(c,p);
}
SearchCriteria中的我的代码
public class SearchCriteria {
private String key;
private Object value;
private SearchOperation operation;
public SearchCriteria(String key, Object value, SearchOperation operation) {
this.key = key;
this.value = value;
this.operation = operation;
}
public String getKey() {
return key;
}
public Object getValue() {
return value;
}
public SearchOperation getOperation() {
return operation;
}
GenericSpecification中的我的代码
public class GenericSpecification<T> implements Specification<T> {
private List<SearchCriteria> list;
public GenericSpecification() {
this.list = new ArrayList<>();
}
public void add(SearchCriteria criteria){
list.add(criteria);
}
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<>();
for (SearchCriteria criteria : list) {
if (criteria.getOperation().equals(SearchOperation.GREATER_THAN)) {
predicates.add(builder.greaterThan(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.LESS_THAN)) {
predicates.add(builder.lessThan(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.GREATER_THAN_EQUAL)) {
predicates.add(builder.greaterThanOrEqualTo(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.LESS_THAN_EQUAL)) {
predicates.add(builder.lessThanOrEqualTo(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.NOT_EQUAL)) {
predicates.add(builder.notEqual(
root.get(criteria.getKey()), criteria.getValue()));
} else if (criteria.getOperation().equals(SearchOperation.EQUAL)) {
predicates.add(builder.equal(
root.get(criteria.getKey()), criteria.getValue()));
} else if (criteria.getOperation().equals(SearchOperation.MATCH)) {
predicates.add(builder.like(
builder.lower(root.get(criteria.getKey())),
"%" + criteria.getValue().toString().toLowerCase() + "%"));
} else if (criteria.getOperation().equals(SearchOperation.MATCH_END)) {
predicates.add(builder.like(
builder.lower(root.get(criteria.getKey())),
criteria.getValue().toString().toLowerCase() + "%"));
}
}
return builder.and(predicates.toArray(new Predicate[0]));
}
我在搜索操作中的代码
public enum SearchOperation {
GREATER_THAN,
LESS_THAN,
GREATER_THAN_EQUAL,
LESS_THAN_EQUAL,
NOT_EQUAL,
EQUAL,
MATCH,
MATCH_END,
}
Criteria API的好处在于,您可以使用CriteriaBuilder基于您拥有的字段构建复杂的SQL语句。您可以使用< code>and和< code>or语句轻松组合多个条件字段。
我过去是如何处理类似的事情的,是使用一个忠告
类,该类接受一个Filter
,该类具有最常见操作的构建器(等于、等于、等于、等于、等于等)。我实际上在我开始的一个开源项目中也有类似的东西:https://gitlab.com/pazvanti/logaritmical/-/blob/master/app/data/dao/GenericDao.javahttps://gitlab.com/pazvanti/logaritmical/-/blob/master/app/data/filter/JPAFilter.java
接下来,隐式DAO类扩展了这个忠告
,当我想做一个操作时(例如:找到一个具有提供的用户名的用户),我在那里创建了一个Filter
。
现在,魔力就在过滤器中。这是创建谓词
的那个。在您的请求中,您将收到如下内容:field1=something
现在,对于请求中的每个字段,使用来自< code>JPAFilter类的helper方法创建一个谓词,并返回结果< code >谓词。在下面的示例中,我假设您没有将它作为地图,而是作为单独的字段(很容易将代码改编为地图):
public class SearchFilter extends JPAFilter {
private Optional<String> field1 = Optional.empty();
private Optional<String> field2 = Optional.empty();
@Override
public Predicate getPredicate(CriteriaBuilder criteriaBuilder, Root root) {
Predicate predicateField1 = field1.map(f -> equals(criteriaBuilder, root, "field1", f)).orElse(null);
Predicate predicateField2 = field2.map(f -> equals(criteriaBuilder, root, "field2", f)).orElse(null);
return andPredicateBuilder(criteriaBuilder, predicateField1, predicateField2);
}
}
现在,我将字段设置为可选字段,因为在这种情况下,我假设您在请求映射中将它们作为可选(Spring 有这个),我知道将 Optional 作为输入参数有点争议,但在这种情况下,我认为这是可以接受的(更多关于这里:https://petrepopescu.tech/2021/10/an-argument-for-using-optional-as-input-parameters/)
< code >和PredicateBuilder()的构造方式是,即使提供的谓词之一为空,它也能正常工作。此外,我制作了一个简单的映射函数,调整为包含< code >
现在,在您的DAO类中,只需提供适当的过滤器:
public class SearchDao extends GenericDAO {
public List<MyEntity> search(Filter filter) {
return get(filter);
}
}
需要进行一些调整(这只是开始代码),比如一种更简单的方法来初始化过滤器(并在DAO中执行此操作),并确保过滤器只能应用于指定的实体(可能使用泛型,<code>JPAFIlter
一个缺点是字段必须与实体类中的变量名称匹配。
问题内容: 我正在使用Hibernate 4和Lucene 3.6。我对构面计数有要求。根据我的要求,我有一个实体“产品”。实体“产品”具有某些属性,例如ID,颜色,品牌。 现在,我的要求是,我想以多维方式获取该实体的商品数,并获取红色(彩色)耐克(品牌)服装的数量。 所以举个例子。我的数据库中保存了以下产品实体。 id品牌颜色 1锐步红 2锐步黑 3锐步绿 4利红 5利黑 6利黑 现在,我希望我
null 我正在寻找一个解决方案,如Groovy GPath语法 store.book-此数组的大小。 store.book[*].category-如何计算数组中的键值。 store.bicycle-如果发现它必须返回true值
是的,我对这个问题非常认真。使用pip搜索是如何工作的? 关键字
在这里,我可以搜索python。 我希望放置负模式,实际上应该不会产生任何结果或不匹配。 当字符串包含python但字符串“在python上工作很容易”中不包含容易时,我喜欢使用re.search。我该怎么做?同时使用正负条件。
我目前正在研究如何在我的项目中实现搜索。我有一个名为users的表,它有两列,firstName和lastName。我希望能够在这两列之间搜索,例如,用户的名字是John,姓是Smith,因此当他们搜索John Smith时,它将返回具有该名称的用户。 或者他们可以只搜索名字等。解决这个问题的方法是什么? 使用PostgreSQL的全文功能是正确的途径吗?我目前正在使用Node w/TypeORM
问题内容: 我有一个对象列表,列表很大。对象是 现在,我必须在列表中搜索对象的特定值。假设 我必须返回那些对象(我的搜索并不总是基于value3) 清单是 有效的方法是什么? 谢谢。 问题答案: 您可以尝试使用Apache Commons Collections。 有一个CollectionUtils类,允许您通过自定义谓词选择或过滤项目。 您的代码将如下所示: 更新: 在 java8中 ,使用