如何获取命名查询的JPQL?如何编程获取命名查询定义?
如何编程获取JPA命名查询的定义?
假设你有如下实体定义:
@Entity @NamedQueries({ @NamedQuery(name = "name1", query = "SELECT n FROM SomeEntity n where n.name= :name"), @NamedQuery(name = "name2", query = "SELECT n FROM SomeEntity n where n.name <> :name") }) public class SomeEntity ......
你想要在代码里动态获取像name1这样的命名查询的定义字符串对吧?这里有几种实用的方法,分通用标准JPA方式和特定实现(比如Hibernate)的方式来给你讲解:
标准JPA通用方法(兼容所有JPA实现)
这种方法完全遵循JPA规范,不依赖任何特定的JPA提供商,适合需要跨实现兼容的场景:
- 首先获取
EntityManagerFactory实例——如果你已经有EntityManager对象,可以直接通过em.getEntityManagerFactory()拿到;如果没有,就从持久化单元创建:
// 从持久化单元创建EntityManagerFactory EntityManagerFactory emf = Persistence.createEntityManagerFactory("你的持久化单元名称"); // 或者从已有的EntityManager获取 // EntityManagerFactory emf = em.getEntityManagerFactory();
- 借助JPA的元模型API,找到对应实体的所有命名查询,遍历筛选出你需要的那一个:
EntityType<SomeEntity> entityType = emf.getMetamodel().entity(SomeEntity.class); for (NamedQuery namedQuery : entityType.getNamedQueries()) { if ("name1".equals(namedQuery.getName())) { String queryString = namedQuery.getQuery(); System.out.println(queryString); // 这里会输出:SELECT n FROM SomeEntity n where n.name= :name break; } }
基于Hibernate的快捷方法(项目用Hibernate作为JPA实现时)
如果你的项目底层用的是Hibernate,那可以用更直接的方式获取,不需要遍历查询集合:
方法一:通过SessionFactory获取
// 从EntityManagerFactory中解包出Hibernate的SessionFactory SessionFactory sessionFactory = emf.unwrap(SessionFactory.class); // 获取指定名称的命名查询定义 NamedQueryDefinition queryDef = sessionFactory.getNamedQueryRepository().getNamedQueryDefinition("name1"); String queryString = queryDef.getQueryString(); System.out.println(queryString);
方法二:通过Query对象解包获取
// 创建JPA命名查询对象 Query jpaQuery = emf.createNamedQuery("name1"); // 解包成Hibernate的Query实例,获取查询字符串 String queryString = jpaQuery.unwrap(org.hibernate.query.Query.class).getQueryString(); System.out.println(queryString);
需要注意的是,这两种Hibernate专属的方法虽然快捷,但如果以后切换到其他JPA实现(比如EclipseLink),这些代码就需要调整了,所以如果项目有跨实现的需求,优先选择标准JPA的方法哦。
内容的提问来源于stack exchange,提问作者krokodilko
相关产品推荐
相关产品推荐

