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 实体类看起来不那么复杂、臃肿。
ICP备案:
公安联网备案: