如何在 Spring Boot 中使用 createQuery

Posted

技术标签:

【中文标题】如何在 Spring Boot 中使用 createQuery【英文标题】:How to use createQuery with spring boot 【发布时间】:2016-12-03 15:44:29 【问题描述】:

通常我使用注释:@Query("SELECT c FROM Country c")JpaRepository 或预定义的方法,如 findAll

但就我而言,我想生成动态查询。

String baseQuery =SELECT c FROM Country c`

if(age!=null)
  baseQuery+="WHERE c.age=20"

我需要像这样从代码级别执行相同的查询:

Query q1 = em.createQuery("SELECT c FROM Country c");

但我在 Spring Boot 中不使用 EntityManager

如何从代码级别生成查询?

【问题讨论】:

抱歉,是什么阻止您调用存储库的 findAll() 方法?您是否在问不使用 Spring Data JPA 时如何执行 JPA 查询?如果是这样,您尝试过什么,您面临的具体问题是什么? 我不能使用 findAll() 因为我想生成动态查询。查询必须依赖于输入值 你面临什么问题?您是否阅读过 spring-data-jpa 文档以了解如何创建自定义存储库方法? docs.spring.io/spring-data/jpa/docs/1.7.2.RELEASE/reference/… 我不知道如何访问 EntityManager,但我认为 anwser 是创建新类 MyRepositoryImpl 并在那里定义 EntityManager entityManage。我说的对吗? 可以使用@PersistenceContext private EntityManager em;注入实体管理器。 【参考方案1】:

如果您想从代码创建动态查询,您可以利用 Spring 的JdbcTemplate。使用 spring boot 就像将 JdbcOperations bean 注入到您的存储库类一样简单(假设您已经为您的项目提供了 spring-boot-starter-jdbc 模块)。

但请记住!此解决方案使用 SQL,而不是 JPQL。这就是为什么您必须在查询中使用正确的表和列名称并将结果正确映射到对象(即使用RowMapper)

这个简单的例子对我来说很好用(使用不同的实体,但方式相同 - 我已经根据你的例子进行了调整):

@Repository
public class CountryRepository 

    @Autowired
    private JdbcOperations jdbcOperations;

    private static String BASIC_QUERY = "SELECT * FROM COUNTRY";

    public List<Country> selectCoutry(Long age)
        String query = BASIC_QUERY;
        if (age != null)
            query += " WHERE AGE = ";
            query += age.toString();
        

        //let's pretend that Country has constructor Conutry(String name, int age)
        return jdbcOperations.query(query, (rs, rowNum) -> 
             return new Country(rs.getString("NAME"), rs.getInt("AGE");
        );
    ;


然后在服务或任何你注入 CountryRepository 和调用方法。

【讨论】:

【参考方案2】:

由于您使用的是 Spring Boot,因此您可以使用 Spring Data 在您的存储库中创建查询:

@Repository
public interface CountryRepository extends JpaRepository<Country, Long> 


不是 100% 的语法,但应该是类似的。 现在你可以autowire这个类了:

@Autowired
public CountryRepository countryRepo;

所有基本方法都已经可以使用了,比如:

countryRepo.findOne(id);
countryRepo.find();

如果你想进行更高级的查询,你可以使用 Spring Data 例如:

@Repository
public interface CountryRepository extends JpaRepository<Country, Long> 

    public Country findByNameAndContinent(String name, String continent);

当然,这只是一个示例(一个愚蠢的示例),并假设您的 Country 类具有字段名称“名称”和“大陆”,两者都是字符串。更多信息可在此处获得: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ 更具体的第 5.3 节。

PS:确保您的 Country 类具有 @Entity 注释

【讨论】:

很抱歉,我的问题表述得很糟糕,问题是如何创建自定义查询。现在我知道我可以通过实现自定义存储库功能来做到这一点:docs.spring.io/spring-data/jpa/docs/1.7.2.RELEASE/reference/…

以上是关于如何在 Spring Boot 中使用 createQuery的主要内容,如果未能解决你的问题,请参考以下文章

[Spring Boot ] Creating the Spring Boot Project : Demo: Creating a REST Controller

@WebMvcTest 在 Spring Boot 测试中为不同服务提供“Error Creating bean with name”错误

Spring Boot报错:Error creating bean with name 'sqlSessionFactory' ...

Spring Boot JPA:如何查询表中的 JSON 列

Creating a Multi Module Spring Boot Project

无法在本机查询 Spring Boot 中使用“LIKE”