当前位置: 首页 > 面试题库 >

Spring Data JPA中的动态查询

何峰
2023-03-14
问题内容

我正在寻找一种使用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());
    }
}


 类似资料:
  • SpringDataJpa中 Specification怎样使用in查询 实体类Menu.java如下 想通过roles属性做in查询,代码如下 错误如下: Parameter value [com.appmtce.pojo.entity.role.Role@20f81e2a] did not match expected type [java.util.Collection (n/a)] 我的S

  • 我有一个这样的SQL问题 根据用户输入,我想将botcode='r1'更改为给定输入。在不重新启动作业的情况下说出botcode='r10'。有没有办法做到这一点。我在flink 1.7上使用stream env。我尝试配置流来读取输入。但仍停留在如何动态更改查询上。有人能帮我吗?提前谢谢

  • 问题内容: 我正在与后端的Mongodb一起开发nodejs / express应用程序。在我的一个API调用中,根据是否存在特定的querystring参数,我想使用$ gt或$ lt向Mongodb发出查询。 在某些情况下,我们想要的所有内容都比使用$ lt少,但在其他情况下,我们希望所有的内容都比使用$ lt大。我们如何做到这一点而不重复查询? 这是一个示例查询: 有没有一种方法可以动态创建

  • 问题内容: 我们正在使用Postgres / PostGis连接来获取通过地理服务器发布的数据。 目前查询看起来像这样: 在我们的数据库中,仅将有效的shapefile导入每个表中,因此使UNION ALL零件动态化(遍历每个表并执行UNION ALL语句)是有意义的。有没有一种方法可以以标准的Postgres方式执行?还是我需要编写一个函数,语法看起来如何?我对SQL很陌生。 shapefile

  • 我正在尝试创建一个简单的Spring项目,餐厅可以在共享数据库中添加菜单项,用户可以使用html表单根据一系列标准搜索菜肴,尤其是饮食要求 表格示例: 示例SQL命令 然后,符合他们标准的菜肴列表将返回给用户。 表单中的任何字段都可以留空,不勾选框(例如,“素食主义者”并不意味着条件应设置为“假”,而是不包括在查询中)。因此,处理该问题的最佳方法似乎是使用JpaSpecificationExecu