我的任务是使用Spring Data REST进行高级搜索。 我该如何实施呢?
我设法制作了一个方法来进行简单的搜索,如下所示:
def test_connect_fetch_profiles(self):
driver = self.driver
search_data = driver.find_element_by_id("main-search-box")
search_data.clear()
search_data.send_keys("Selenium Python")
search_submit = driver.find_element_by_name("search")
search_submit.click()
noprofile = driver.find_elements_by_xpath("//*[text() = 'Sorry, no results containing all your search terms were found.']")
self.assertFalse(noprofile)
while True:
wait = WebDriverWait(driver, 150)
try:
profile_links = wait.until(EC.presence_of_all_elements_located((By.XPATH,"//*[contains(@href,'www.linkedin.com/profile/view?id=')][text()='LinkedIn Member'or contains(@href,'Type=NAME_SEARCH')][contains(@class,'main-headline')]")))
for each_link in profile_links:
page_links = each_link.get_attribute('href')
print(page_links)
driver.implicitly_wait(15)
appendFile = open("C:\\Users\\jayaramb\\Documents\\profile-links.csv", 'a')
appendFile.write(page_links + "\n")
appendFile.close()
driver.implicitly_wait(15)
next = wait.until(EC.visibility_of(driver.find_element_by_partial_link_text("Next")))
if next.is_displayed():
next.click()
else:
print("End of Page")
break
except ValueError:
print("It seems no values to fetch")
except NoSuchElementException:
print("No Elements to Fetch")
except StaleElementReferenceException:
print("No Change in Element Location")
else:
break
如果我必须简单地访问网址,那么此示例的效果非常好:
public interface ExampleRepository extends CrudRepository<Example, UUID>{
@RestResource(path="searchByName", rel="searchByName")
Example findByExampleName(@Param("example") String exampleName);
}
但如果要搜索多个字段,我该怎么做?
例如,如果我的Example类有5个字段,那么我应该使用所有可能的文件来进行高级搜索?
考虑一下这个:
.../api/examples/search/searchByName?example=myExample
和这一个:
.../api/examples/search/searchByName?filed1=value1&field2=value2&field4=value4
我必须采取哪些措施才能以适当的方式实施此搜索?
感谢。
答案 0 :(得分:7)
在Spring reference documentation和大量技术博客中广泛记录的查询方法的实现虽然相当多,但已经过时了。
由于您的问题可能是&#34;如何在不声明大量findBy *方法的情况下使用任何字段组合执行多参数搜索?&#34;,答案为Querydsl,由Spring支持。
答案 1 :(得分:7)
Spring Data Rest已将QueryDSL与Web支持集成在一起,您可以将其用于高级搜索要求。您需要更改存储库以实现QueryDslPredicateExecutor
,并且开箱即用。
以下是有关该功能的blog文章的示例:
$ 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
}
}
答案 2 :(得分:3)
我找到了一个有效的解决方案。
@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);
}
使用此解决方案,使用此基本URL:
http://localhost:8080/api/examples/search/advancedSearch
我们可以使用我们需要的所有字段进行高级搜索。
一些例子:
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"
答案 3 :(得分:0)
我想你可以试试以下:
List<Person> findDistinctPeopleByLastnameOrFirstname(@Param("lastName")String lastname, @Param("firstName")String firstname);
和examples/search/searchByLastnameOrFirstname?firstName=value1&lastName=value2
答案 4 :(得分:0)
我设法使用Query by Example来实现。
假设您有以下型号:
@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> {
}
(请注意,JpaRepository实现了QueryByExampleExecutor)。
现在,您实现一个自定义控制器:
@RepositoryRestController
@RequiredArgsConstructor
public class CompanyCustomController {
private final CompanyRepository repository;
@GetMapping("/companies/filter")
public ResponseEntity<?> filter(
Company company,
Pageable page,
PagedResourcesAssembler assembler,
PersistentEntityResourceAssembler entityAssembler
){
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnoreCase()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);
Example example = Example.of(company, matcher);
Page<?> result = this.repository.findAll(example, page);
return ResponseEntity.ok(assembler.toResource(result, entityAssembler));
}
}
然后您可以进行如下查询:
localhost:8080/companies/filter?name=google&address=NY
您甚至可以查询嵌套实体,例如:
localhost:8080/companies/filter?name=google&department.name=finances
为简洁起见,我省略了一些细节,但是我在Github上创建了working example。