我正在寻找一种使用Spring Data JPA动态构建查询的解决方案。我有一个GameController,它有一个RESTful服务终结点/ games,它带有4个可选参数:体裁,平台,年份,标题。可能不传递任何API,而是传递所有4种,以及之间的每种组合。如果未传递任何参数,则默认为null。我需要在存储库中使用一种方法来构建适当的查询,并且理想情况下还允许Spring Data JPA Paging,尽管我不确定这是否可行。
我找到了这篇文章,但是除非我有误解,否则这似乎并不是我所需要的。http://spring.io/blog/2011/04/26/advanced- spring-data-jpa-specifications-and- querydsl/
我知道JPA有一个Query Criteria API,但实际上不知道如何实现这一点。
我意识到我可以为每种可能的情况创建一个方法,但这似乎是一种非常糟糕的做法,并且有很多不必要的代码。
游戏库:
package net.jkratz.igdb.repository; import net.jkratz.igdb.model.Game; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; public interface GameRepository extends JpaRepository<Game, Long> { @Query("select g from Game g, GamePlatformMap gpm, Platform p where g = gpm.game and gpm.platform = p and p.id = :platform") Page<Game> getGamesByPlatform(@Param("platform") Long platformId, Pageable pageable); @Query("select g from Game g where g.title like :title") Page<Game> getGamesByTitle(@Param("title") String title, Pageable pageable); @Query("select g from Game g, GameGenreMap ggm, Genre ge where g = ggm.game and ggm.genre = ge and ge.id = :genreId") Page<Game> getGamesByGenre(@Param("genre") Long genreId, Pageable pageable); }
我想说,使用QueryDSL是您想要做的一种方式。
例如,我有一个定义如下的存储库:
public interface UserRepository extends PagingAndSortingRepository<User, Long>, QueryDslPredicateExecutor<User> { public Page<User> findAll(Predicate predicate, Pageable p); }
我可以使用任何参数组合调用此方法,如下所示:
public class UserRepositoryTest{ @Autowired private UserRepository userRepository; @Test public void testFindByGender() { List<User> users = userRepository.findAll(QUser.user.gender.eq(Gender.M)); Assert.assertEquals(4, users.size()); users = userRepository.findAll(QUser.user.gender.eq(Gender.F)); Assert.assertEquals(2, users.size()); } @Test public void testFindByCity() { List<User> users = userRepository.findAll(QUser.user.address.town.eq("Edinburgh")); Assert.assertEquals(2, users.size()); users = userRepository.findAll(QUser.user.address.town.eq("Stirling")); Assert.assertEquals(1, users.size()); } @Test public void testFindByGenderAndCity() { List<User> users = userRepository.findAll(QUser.user.address.town.eq("Glasgow").and(QUser.user.gender.eq(Gender.M))); Assert.assertEquals(2, users.size()); users = userRepository.findAll(QUser.user.address.town.eq("Glasgow").and(QUser.user.gender.eq(Gender.F))); Assert.assertEquals(1, users.size()); } }