JPA命名查询语句的定义和调用(附带实例)
除了使用 @Query 注解外,还可以使用 @NamedQuery 与 @NameQueries 等注解定义命名查询。
JPA 的命名查询实际上就是给 SQL 查询语句起一个名字,执行查询时就是直接使用起的名字,避免重复写 JPQL 语句,使得查询方法能够复用。
如果要定义多个命名查询方法,则需要使用 @NamedQueries 注解:

图 1 已命名查询的运行结果
定义的已命名查询 findUserWithName 的单元测试运行成功,并输出了相应的查询结果,说明使用 JPA 实现了自定义的已命名查询的功能。
除了使用 @NamedQuery 注解的方式之外,Spring Data JPA 提供的 Named 查询可以支持将 SQL 语句写至 XML 文件中,实现 SQL 与 Java 代码的分离。
在 resources/META-INF 目录下创建 orm.xml 文件并定义命名方法,参考配置如下:
JPA 的命名查询实际上就是给 SQL 查询语句起一个名字,执行查询时就是直接使用起的名字,避免重复写 JPQL 语句,使得查询方法能够复用。
JPA定义命名查询
在实体类中,@NamedQuery 注解定义一个命名查询语句,示例代码如下:@Entity @Table(name="t_user") @NamedQuery(name="findAllUser",query="SELECT u FROM User u") public class User { // Entity实体类相关定义 }在上面的示例中,@NamedQuery 中的 name 属性指定命名查询的名称,query 属性指定命名查询的语句。
如果要定义多个命名查询方法,则需要使用 @NamedQueries 注解:
@Entity @Table(name="users") @NamedQueries({ @NamedQuery(name="findAllUser",query="SELECT u FROM User u"), @NamedQuery(name="findUserWithId",query="SELECT u FROM User u WHERE u.id = ?1"), @NamedQuery(name="findUserWithName",query="SELECT u FROM User u WHERE u.name = :name") }) public class User { // Entity实体类相关定义 }在上面的示例中,在 User 实体类中定义了 findAllUser()、findUserWithId()、findUserWithName() 三种方法。
JPA调用命名查询
定义命名查询后,可以使用 EntityManager 类中的 createNamedQuery() 方法传入命名查询的名称来创建查询:@Resource EntityManagerFactory emf; @Test public void testNamedQuery() { EntityManager em = emf.createEntityManager(); Query query = em.createNamedQuery("findUserWithName");// 根据User实体中定义的命名查询 query.setParameter("name", "weiz"); List<User> users = query.getResultList(); for (User u : users){ System.out.println("name:"+u.getName()+",age:"+u.getAge()); } }在上面的示例中,使用 createNamedQuery 创建对应的查询,JPA 会先根据传入的查询名查找对应的 NamedQuery,然后通过调用 getResultList() 方法执行查询并返回结果。
运行验证
单击 Run Test 或在方法上右击,选择 Run 'testNamedQuery',运行全部测试方法,结果如下图所示:
图 1 已命名查询的运行结果
定义的已命名查询 findUserWithName 的单元测试运行成功,并输出了相应的查询结果,说明使用 JPA 实现了自定义的已命名查询的功能。
除了使用 @NamedQuery 注解的方式之外,Spring Data JPA 提供的 Named 查询可以支持将 SQL 语句写至 XML 文件中,实现 SQL 与 Java 代码的分离。
在 resources/META-INF 目录下创建 orm.xml 文件并定义命名方法,参考配置如下:
<?xml version="1.0" encoding="UTF-8"?> <entity-mappings version="2.0" xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/orm_2_2.xsd "> <named-native-query name="findUserWithName2" result-class="com.weiz.example01.model.User"> <description>通过name查询用户数据</description> <query>select u.id , u.name , u.password , u.age from users u where u.name = :name</query> </named-native-query> </entity-mappings>在 orm.xml 文件中使用 <named-native-query> 标签定义 queryByName 的命名查询,使用 XML 的方式与使用 @NamedQuery 注解方式的效果是一样的。只是将 SQL 语句写至 XML 文件中,实现 SQL 与 Java 代码的分离,使得定义的 Java 实体类看起来不那么复杂、臃肿。