【问题标题】:using HQL queries in Spring Boot在 Spring Boot 中使用 HQL 查询
【发布时间】:2018-06-02 08:15:32
【问题描述】:
我有一个包含多个模型类的 Spring Boot 项目
我想在我的 DAO 实现中使用多个模型类。
谁能在这里解释一下如何使用 HQL 查询。
我看到的大多数示例都使用 CRUDRepository。但据我了解,这将我们限制在一个模型类(如果我的理解有误,请纠正我)。
其次,使用 CRUDRepository 将我限制在非常具体的方法上。但我需要的 HQL 查询可能更复杂,例如:
Query query = session.createQuery(from Employee where name=:name and place=:place and phone=:phone and gender=:gender);
即使对于像这样的 HQL 查询也使用 CRUDRepository 是标准做法吗?
否则我怎么能使用这样的 HQL 查询。 (如果可能,还请添加我需要添加的所有依赖项和注释)。我正在使用 Hibernate 和 postgres。
【问题讨论】:
标签:
spring
postgresql
hibernate
spring-boot
hibernate-mapping
【解决方案1】:
如果您希望在不使用存储库等的情况下执行 动态 HQL 查询,这对我来说非常有用:
@Autowired
EntityManager entityManager;
@RequestMapping("/query")
@ResponseBody
public String testQuery() {
Query query = entityManager.createQuery("select u from User u");
List<User> users = query.getResultList();
users.forEach(u -> System.out.println(u.getFirstname()));
return "See Console";
}
它的好处是,如果您很快想要测试查询,并且您正在使用 Spring LiveReload、JRebel、DCEVM 或 HotSwap 等 Hybris,您可以更改查询并保存和刷新。
【解决方案2】:
CRUD 存储库是编写 DAO 的标准方法。如果您查看文档,您会发现您可以使用实体的字段进行复杂查询(这可能非常复杂,我鼓励您在查询方法部分查看here - 4.3),如果您想要更复杂的方法,可以在方法上使用注解@Query:
@Repository
interface MyRepo implements JpaRepository<MyEntity,Long> {
@Query("your custom query here")
MyEntity findByFeature(String a)
}
现在您可以在查询中插入查询并访问您的String a(例如Select u where u.name="blabla",其中blabla 是您的输入字符串)
@Query 与存储库具有相同的依赖关系(我认为spring-boot-starter-data-jpa 就足够了)
【解决方案3】:
JpaRepository 使用起来确实很棒,但对于必须使用复杂 HQL 查询的人(由于贵组织的建议等),我是这样做的:
-
通过在您的配置中注入以下 bean 来获取会话工厂:
@豆
公共 SessionFactory sessionFactory(@Qualifier("entityManagerFactory") EntityManagerFactory emf)
{
返回 emf.unwrap(SessionFactory.class);
}
-
将 EntityScan 和 ComponentScan 添加到您的配置类
@EntityScan(basePackages = { "com.app.persistence" })
@ComponentScan(basePackages = { "com.app" })
-
继续使用任何 HQL 查询:
@自动连线
SessionFactory 工厂;
@Override
public String check() {
Session session = null;
try {
session = factory.openSession();
Query query = session.createQuery("from Test");
List<Test> res = query.list();
Test sing = res.get(0);
return sing.getName();
} catch (Exception e) {
System.out.println("Exception in Dao");
e.printStackTrace();
throw e;
} finally {
if (session != null) {
session.close();
}
}
}
注意:我假设配置 DataSource 等其他事情都已经处理好了。
如果我的理解或方式有误,任何人都可以随时纠正我。
但是这种方式对我来说效果很好! :)