使用 spring-boot 内部 @Controllers 和 @RequestParam 来提供搜索方法
use spring-boot internal @Controllers with @RequestParam to provide search method
我正在用 spring 引导构建后端休息 api。
实体:
@Entity
public class Club {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
@Column(unique=true)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
存储库:
@RepositoryRestResource
public interface ClubRepository extends JpaRepository<Club, Long>, JpaSpecificationExecutor<Club> {
}
仅此一项就在 http://host/clubs
处公开了一个休息端点,太棒了。现在,我想允许 url 中的一些参数用于搜索目的,所以我开始按照 http://www.baeldung.com/rest-api-search-language-spring-data-specifications 的说明进行操作。
但他们最终创建了自定义 @Controller
来传递请求参数:
@Controller
public class ClubController {
@Autowired
private ClubRepository repo;
@RequestMapping(method = RequestMethod.GET, value = "/clubs")
@ResponseBody
public List<Club> search(@RequestParam(value = "search") String search) {
/* ... */
return repo.findAll(spec);
}
}
所以你看,他们最终调用了存储库的 findAll 方法,只是传递了他们基于查询参数构建的规范。很简单,但我真的很想不必为我的每个域对象创建额外的控制器。换句话说,有没有办法通过直接注释(例如)@Entity
或覆盖存储库中的方法(如 findAll
方法)来提供此搜索功能?
更好的方法是使用 QueryDsl 而不是标准 API。 Spring Data 和扩展的 Spring Data Rest 将为您提供许多出色的功能 'for free' 除了一些基本配置。
https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#spring-data-rest
https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
一个配置你的存储库接口简单地变成:
@RepositoryRestResource
public interface ClubRepository extends JpaRepository<Club, Long>, QueryDslPredicateExecutor<Club> {
}
然后可以使用参数的动态组合查询端点:
例如
http://host/clubs?name=someName
http://host/clubs?name=someName&otherProperty=X&sort=name,desc
不需要进一步的代码,即没有自定义控制器,没有规范,也没有查询方法。
要配置 Maven,只需将以下内容添加到包含实体的模块中的 POM:这将生成必要的 'query' 类.
<dependencies>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
我正在用 spring 引导构建后端休息 api。
实体:
@Entity
public class Club {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
@Column(unique=true)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
存储库:
@RepositoryRestResource
public interface ClubRepository extends JpaRepository<Club, Long>, JpaSpecificationExecutor<Club> {
}
仅此一项就在 http://host/clubs
处公开了一个休息端点,太棒了。现在,我想允许 url 中的一些参数用于搜索目的,所以我开始按照 http://www.baeldung.com/rest-api-search-language-spring-data-specifications 的说明进行操作。
但他们最终创建了自定义 @Controller
来传递请求参数:
@Controller
public class ClubController {
@Autowired
private ClubRepository repo;
@RequestMapping(method = RequestMethod.GET, value = "/clubs")
@ResponseBody
public List<Club> search(@RequestParam(value = "search") String search) {
/* ... */
return repo.findAll(spec);
}
}
所以你看,他们最终调用了存储库的 findAll 方法,只是传递了他们基于查询参数构建的规范。很简单,但我真的很想不必为我的每个域对象创建额外的控制器。换句话说,有没有办法通过直接注释(例如)@Entity
或覆盖存储库中的方法(如 findAll
方法)来提供此搜索功能?
更好的方法是使用 QueryDsl 而不是标准 API。 Spring Data 和扩展的 Spring Data Rest 将为您提供许多出色的功能 'for free' 除了一些基本配置。
https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#spring-data-rest
https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
一个配置你的存储库接口简单地变成:
@RepositoryRestResource
public interface ClubRepository extends JpaRepository<Club, Long>, QueryDslPredicateExecutor<Club> {
}
然后可以使用参数的动态组合查询端点:
例如
http://host/clubs?name=someName
http://host/clubs?name=someName&otherProperty=X&sort=name,desc
不需要进一步的代码,即没有自定义控制器,没有规范,也没有查询方法。
要配置 Maven,只需将以下内容添加到包含实体的模块中的 POM:这将生成必要的 'query' 类.
<dependencies>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>