【问题标题】:How to use createQuery with spring boot如何在 Spring Boot 中使用 createQuery
【发布时间】: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;注入实体管理器。

标签: java spring hibernate spring-data spring-data-jpa


【解决方案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 注释

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 2021-06-19
    • 2020-11-15
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多