Spring JPA EntityManager查询方法详解

作者: zhaochenxi 分类: Java 发布时间: 2015-11-14 18:21

在Spring的文档中我们可以看到EntityManager下面有几个create开头的方法createQuery,createNamedQuery,createNativeQuery,这三个方法是查询的主要方法。这三个方法的区别是什么,他们分别怎么用呢?

1.createQuery

Query createQuery(java.lang.String qlString)
<T> TypedQuery<T> createQuery(java.lang.String qlString,java.lang.Class<T> resultClass)

该方法用户执行用户编写的jpql语句,不能用于执行SQL语句,执行SQL则报异常.下面是一段实例代码:

public List<Writer> queryByMajor(int majorId) {
		// TODO Auto-generated method stub
		String jpql = "select w from Writer w where w.majorId=:majorId";
		String sql = "select * from writer where majorId=?1";
		//Query query=entityManager.createNativeQuery(jpql);
		//Query query=entityManager.createQuery(jpql,Writer.class);
		Query query=entityManager.createQuery(jpql);
		//query.setParameter(1,majorId);
		query.setParameter("majorId",majorId);
		return query.getResultList();
	}

以上代码中createQuery(jpql,Writer.class)和entityManager.createQuery(jpql);执行的结果是一样的,不同的是前者指定了返回的结果集的类型,后者没有制定,当然这两种查询得到的结果集是一样的,但是建议在使用的时候制定结果集。

2.createNativeQuery

Query createNativeQuery(java.lang.String sqlString,java.lang.Class resultClass)
Query createNativeQuery(java.lang.String sqlString)
Query createNativeQuery(java.lang.String sqlString,java.lang.String resultSetMapping)

以上方法用于执行SQL语句,不能用于执行jpql语句,个人觉得jpql适用于简单查询,复杂查询还是应该使用SQL编写。在尝试去执行jpql的时候出现了如下异常:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table ‘article.Writer’ doesn’t exist,在数库中找不到表article.Writer。
以上前面两个方法中一个指定了结果集一个没有制定,但是其执行结果是不一样的。
我们看看之前贴出的queryByMajor方法使用Query query=entityManager.createNativeQuery(sql)的返回结果:

{
json: {
returnMsg: "succes",
returnCode: 1,
data: [[7,"sb",0,"2014-05-23","doctor",5],[9,"cxzhao",1,"2015-11-08","doctor",5],[10,"cxzhao2",1,"2015-11-10","benke",5]]
}
}

从上面的结果中我们可以看到,在返回的结果中由于没有指定结果集的类型,返回结果中只有结果,没有结果对应的字段名。我们在看看如果指定结果集的类型Query query=entityManager.createNativeQuery(sql,Writer.class)之后的返回值:

{
json: {
returnMsg: "succes",
returnCode: 1,
data: [
{birthday: 1400828400000,edu: "doctor",majorId: 5,sex: 0,name: "sb",id: 7},
{birthday: 1446969600000,edu: "doctor",majorId: 5,sex: 1,name: "cxzhao",id: 9},
{birthday: 1447142400000,edu: "benke",majorId: 5,sex: 1,name: "cxzhao2",id: 10}
]}}

对比两个不同的结果发现返回值中每一个结果对应有一个字段名,也就是说在指定结果集意味着原生查询的结果集中的栏将完全匹配实体的O/R映射,第三个方法使用一个字符串来指定结果集,和第一个使用类来指定有所不同。
最后一个方法主要应用于复杂的查询,返回的结果不能被实体一一映射。

转载请注明出处

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注