如何在Spring MVC控制器中应用Spring Data投影?

Bar*_*oss 21 spring spring-security spring-data

是否可以直接指定projection何时调用数据存储库方法?这是存储库代码 - 注意我不想通过REST公开它,而是希望能够从服务或控制器中调用它:

@RepositoryRestResource(exported = false)
public interface UsersRepository extends PagingAndSortingRepository<User, Long> {

    @Query(value = "SELECT u FROM User u WHERE ....")
    public Page<User> findEmployeeUsers(Pageable p);
}
Run Code Online (Sandbox Code Playgroud)

然后在控制器中我这样做:

@PreAuthorize(value = "hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users/employee")
public Page<User> listEmployees(Pageable pageable) {
    return usersRepository.findEmployeeUsers(pageable);
}
Run Code Online (Sandbox Code Playgroud)

有没有什么方法来指定projectionfindEmployeeUsers,当它被称为直接像上面的方法?

我意识到上面的代码对于某些人来说可能看起来很奇怪......可以通过REST公开存储库并将其放入@PreAuthorize存储库中.思想控制器是进行安全检查的最佳位置 - 测试更自然,更简单.

那么,可以projection以某种方式将事物传递到直接调用的存储库方法中吗?

Oli*_*ohm 54

不,它不是,特别是因为投影通常会根据具体情况应用于查询执行的结果.因此,它们目前被设计为有选择地应用于域类型.

截至最新的Spring Data Fowler发布列车GA版本,可以在Spring MVC控制器中以编程方式使用投影基础架构.只需声明一个Spring bean SpelAwareProxyProjectionFactory:

@Configuration
class SomeConfig {

  @Bean
  public SpelAwareProxyProjectionFactory projectionFactory() {
    return new SpelAwareProxyProjectionFactory();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后将其注入您的控制器并使用它:

@Controller
class SampleController {

  private final ProjectionFactory projectionFactory;

  @Autowired
  public SampleController(ProjectionFactory projectionFactory) {
    this.projectionFactory = projectionFactory;
  }

  @PreAuthorize(value = "hasRole('ROLE_ADMIN')")
  @RequestMapping(value = "/users/employee")
  public Page<?> listEmployees(Pageable pageable) {

    return usersRepository.findEmployeeUsers(pageable).//
      map(user -> projectionFactory.createProjection(Projection.class, user);
  }
}
Run Code Online (Sandbox Code Playgroud)

了解最新版本如何Page具有map(…)可用于动态转换页面内容的方法.我们使用JDK 8 lambda来提供转换步骤ProjectionFactory.

  • 如上例中所示,如何转换存储库查询的结果与使用返回投影本身的存储库查询进行比较?在性能等方面? (4认同)