Java 如何使用Spring数据REST进行高级搜索?
我的任务是使用SpringDataREST进行高级搜索。 我如何实现它 我找到了一个简单的搜索方法,如下所示:Java 如何使用Spring数据REST进行高级搜索?,java,spring,java-8,spring-data-rest,Java,Spring,Java 8,Spring Data Rest,我的任务是使用SpringDataREST进行高级搜索。 我如何实现它 我找到了一个简单的搜索方法,如下所示: public interface ExampleRepository extends CrudRepository<Example, UUID>{ @RestResource(path="searchByName", rel="searchByName") Example findByExampleName(@Param("example") String
public interface ExampleRepository extends CrudRepository<Example, UUID>{
@RestResource(path="searchByName", rel="searchByName")
Example findByExampleName(@Param("example") String exampleName);
}
.../api/examples/search/searchByName?filed1=value1&field2=value2&field4=value4
.../api/examples/search/searchByName?filed1=value1&field3=value3
但是如果要搜索的字段不止一个,我该怎么办呢
例如,如果我的示例类有5个字段,我应该用什么实现对所有可能的文件进行高级搜索
考虑一下这一点:
public interface ExampleRepository extends CrudRepository<Example, UUID>{
@RestResource(path="searchByName", rel="searchByName")
Example findByExampleName(@Param("example") String exampleName);
}
.../api/examples/search/searchByName?filed1=value1&field2=value2&field4=value4
.../api/examples/search/searchByName?filed1=value1&field3=value3
还有这个:
public interface ExampleRepository extends CrudRepository<Example, UUID>{
@RestResource(path="searchByName", rel="searchByName")
Example findByExampleName(@Param("example") String exampleName);
}
.../api/examples/search/searchByName?filed1=value1&field2=value2&field4=value4
.../api/examples/search/searchByName?filed1=value1&field3=value3
要以适当的方式实现此搜索,我必须做些什么
谢谢。查询方法的实现在很多技术博客中都有广泛的文档记录,尽管有很多已经过时了
由于您的问题可能是“如何在不声明大量findBy*方法的情况下对任何字段组合执行多参数搜索?”答案是,这一点得到了。我想您可以尝试以下内容:
列出FindDistinctPeopleByLastName或firstName(@Param(“lastName”)字符串lastName,@Param(“firstName”)字符串firstName)代码>
和examples/search/searchbylastname或firstName?firstName=value1&lastName=value2
签出:我已找到此任务的有效解决方案
@RepositoryRestResource(excerptProjection=MyProjection.class)
public interface MyRepository extends Repository<Entity, UUID> {
@Query("select e from Entity e "
+ "where (:field1='' or e.field1=:field1) "
+ "and (:field2='' or e.field2=:field2) "
// ...
+ "and (:fieldN='' or e.fieldN=:fieldN)"
Page<Entity> advancedSearch(@Param("field1") String field1,
@Param("field2") String field2,
@Param("fieldN") String fieldN,
Pageable page);
}
我们可以对所有需要的字段进行高级搜索
一些例子:
http://localhost:8080/api/examples/search/advancedSearch?field1=example
// filters only for the field1 valorized to "example"
http://localhost:8080/api/examples/search/advancedSearch?field1=name&field2=surname
// filters for all records with field1 valorized to "name" and with field2 valorized to "surname"
SpringDataREST将QueryDSL与web支持集成在一起,您可以使用它满足高级搜索需求。您需要更改存储库以实现querydsldpredicateexecutor
,一切都将开箱即用
以下是关于该功能的文章示例:
$ http :8080/api/stores?address.city=York
{
"_embedded": {
"stores": [
{
"_links": {
…
},
"address": {
"city": "New York",
"location": { "x": -73.938421, "y": 40.851 },
"street": "803 W 181st St",
"zip": "10033-4516"
},
"name": "Washington Hgts/181st St"
},
{
"_links": {
…
},
"address": {
"city": "New York",
"location": { "x": -73.939822, "y": 40.84135 },
"street": "4001 Broadway",
"zip": "10032-1508"
},
"name": "168th & Broadway"
},
…
]
},
"_links": {
…
},
"page": {
"number": 0,
"size": 20,
"totalElements": 209,
"totalPages": 11
}
}
我成功地实现了这一点
假设您有以下型号:
@Entity
public class Company {
@Id
@GeneratedValue
Long id;
String name;
String address;
@ManyToOne
Department department;
}
@Entity
public class Department {
@Id
@GeneratedValue
Long id;
String name;
}
以及存储库:
@RepositoryRestResource
public interface CompanyRepository extends JpaRepository<Company, Long> {
}
您甚至可以查询嵌套实体,如:
localhost:8080/companies/filter?name=google&department.name=finances
为了简洁起见,我省略了一些细节,但我在Github上创建了一个。看看这里,找到了比您开始使用的更好的方法吗?看看我的答案。我相信我已经完成了您要查找的内容,请检查我的答案。不要认为查询dsl可以与SDR结合。@matr0s看看下面的答案。自从春天小鹅放生以来,它就一直在外面。就我个人而言,我已经使用它好几个月了,我可以谦恭地保证;)从不知道查询dsl已集成到SDR。非常感谢这个链接。是的,这是我在前面的回答中提到的链接之一。最多两个参数,这是可以的,但是如果有三个或更多参数,那么定义所有findBy方法就有点麻烦了。如果您的搜索字段是“A”、“B”和“C”,那么您很快就会得到以下结果:findByA、findByB、findByC、findByAAndBAndC、findByAAndB、findByAAndC、findByBAndC。。。现在,假设A、B、C是有意义的变量名,比如“name、description、createDate”。现在我正在尝试这样的东西:personRepo.findAll(新PersonalAdvancedSearch(name、姓氏、年龄等),PersonalAdvancedSearch在这里实现规范。PersonalAdvancedSearch覆盖预测方法。它似乎可以工作,但如果属性是复杂类型,我仍然会遇到问题。@AlessandroC也许用注释手工创建您的方法可以帮助您更好地处理域对象上的搜索。即使它是这样的。您的资源和存储库位于一个类中。除了在存储库接口中定义一个方法之外,您不需要编写一行sql,并且…得到了一个编译错误,修改如下@查询(“从实体e“+”中选择e,其中(:field1=''或e.field1=:field1)”+“和(:field2=''或e.field2=:field2)”/…+“和(:fieldN=''或e.fieldN=:fieldN)”)页面高级搜索(@Param(“field1”)字符串field1,@Param(“field2”)字符串字段2,@Param(“fieldN”)字符串字段n,可分页页面);