Java JPA本机查询选择和转换对象
我有一个对象Java JPA本机查询选择和转换对象,java,sql,jpa,jpql,Java,Sql,Jpa,Jpql,我有一个对象Admin,它扩展了User。默认情况下,这两个对象都位于my Derby数据库的表User中(包括Admin中的字段)。通常我会选择一个用户,如下所示: CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<User> query = cb.createQuery(User.class); Root user= query.from(User.class); Predicate predicateId =
Admin
,它扩展了User
。默认情况下,这两个对象都位于my Derby数据库的表User
中(包括Admin
中的字段)。通常我会选择一个用户
,如下所示:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root user= query.from(User.class);
Predicate predicateId = cb.equal(category.get("id"), id);
query.select(user).where(predicateId);
return em.createQuery(query).getSingleResult();
Query query = em.createNativeQuery("SELECT USER.* FROM USER_ AS USER WHERE ID = ?");
query.setParameter(1, id);
return (User) query.getSingleResult();
尽管这会引发强制转换异常。我想这是由于Admin
中的任何字段造成的
我的问题是,在第一个示例中(包括与JPQL查询返回的
@LOB
和@ManyToOne
(等等)相同的值),如何使用具有相同结果的本机查询选择用户?
。您可能需要尝试以下方法之一:
- 使用方法
还可以使用createNativeQuery(sqlString,resultClass)
API动态定义本机查询EntityManager.createNativeQuery()
String sql = "SELECT USER.* FROM USER_ AS USER WHERE ID = ?"; Query query = em.createNativeQuery(sql, User.class); query.setParameter(1, id); User user = (User) query.getSingleResult();
- 使用注释
本机查询是通过@namedNativeRequesty
和@NamedNativeQueries
注释,或@NamedNativeQueries
XML元素@NamedNativeQuery( name="complexQuery", query="SELECT USER.* FROM USER_ AS USER WHERE ID = ?", resultClass=User.class ) public class User { ... } Query query = em.createNamedQuery("complexQuery", User.class); query.setParameter(1, id); User user = (User) query.getSingleResult();
注意:关于使用
getSingleResult()
,请参阅
首先,创建一个模型POJO
控制器
导入com.example.demo.models.*;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.web.bind.annotation.GetMapping;
导入org.springframework.web.bind.annotation.RestController;
导入javax.persistence.EntityManager;
导入javax.persistence.EntityManagerFactory;
导入javax.persistence.PersistenceUnit;
导入java.util.List;
@RestController
公共类家庭控制器{
@持久性单位
私人实体管理工厂emf;
@GetMapping(“/”)
公共列表操作索引(){
EntityManager em=emf.createEntityManager();//不带参数
列表arr_cust=(列表)em
.createQuery(“从StdUser c中选择c”)
.getResultList();
返回客户;
}
@GetMapping(“/parameter”)
公共列表actionJoin(){
int-id=3;
字符串userName=“Suresh Shrestha”;
EntityManager em=emf.createEntityManager();//带参数
列表arr_cust=em
.createQuery(“从StdUser c中选择c,其中c.classId=:Id和c.userName=:userName”)
.setParameter(“Id”,Id)
.setParameter(“用户名”,用户名)
.getResultList();
返回客户;
}
}
请参阅
对于Postgres 9.4
List<String> list = em.createNativeQuery("select cast(row_to_json(u) as text) from myschema.USER_ u WHERE ID = ?")
.setParameter(1, id).getResultList();
User map = new ObjectMapper().readValue(list.get(0), User.class);
List List=em.createNativeQuery(“从myschema.USER中选择cast(行到json(u)作为文本)u,其中ID=?”)
.setParameter(1,id).getResultList();
User map=new ObjectMapper().readValue(list.get(0),User.class);
接受的答案不正确
createNativeQuery
将始终返回一个查询
:
public Query createNativeQuery(String sqlString, Class resultClass);
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass);
对查询调用getResultList
,返回列表
:
List getResultList()
当分配(或强制转换)到列表
时,将生成未选中的分配警告
然而,createQuery
将返回TypedQuery
:
public Query createNativeQuery(String sqlString, Class resultClass);
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass);
这是正确键入的,不会发出警告
使用createNativeQuery
,使用ObjectMapper
似乎是消除警告的唯一方法。就我个人而言,我选择不显示警告,因为我认为这是库中的一个缺陷,我不必担心。当您的本机查询基于联接时,在这种情况下,您可以将结果作为对象列表获得并处理它
一个简单的例子
@Autowired
EntityManager em;
String nativeQuery = "select name,age from users where id=?";
Query query = em.createNativeQuery(nativeQuery);
query.setParameter(1,id);
List<Object[]> list = query.getResultList();
for(Object[] q1 : list){
String name = q1[0].toString();
//..
//do something more on
}
@Autowired
实体管理器;
String nativeQuery=“从id=?”的用户中选择名称、年龄”;
Query Query=em.createNativeQuery(nativeQuery);
query.setParameter(1,id);
List=query.getResultList();
对于(对象[]q1:列表){
字符串名称=q1[0]。toString();
//..
//多做点什么
}
是什么使得查询对JPQL来说过于复杂?@damo这是一个简短的示例,实际查询包含许多子查询,SUM
,COALESCENSE
,CASE
等等。请检查此答案。它有完整的答案:@PaulVargas如果结果是一个整数而不是一个整数呢entity@PaulVargas,我建议您这样做:Integer val=(Integer)query.getSingleResult();但是,我通常建议不要使用query.getSingleResult(),因为它会引发许多已检查的异常。如果你把结果列为一个列表,那么你就可以不处理任何结果,而是相应地处理多个结果。嘿,@Joe。谢谢我继续使用query.getSingleResult()
,因为操作:)在rest控制器中编写数据访问代码不是一个好的做法。将数据访问代码存储在@Repository类中。从@Service classes调用您的存储库。从@RestController访问@Service类。哪种方式适合传递本机查询?1) 使用EntityManager 2)使用JpaRepository接口
@Autowired
EntityManager em;
String nativeQuery = "select name,age from users where id=?";
Query query = em.createNativeQuery(nativeQuery);
query.setParameter(1,id);
List<Object[]> list = query.getResultList();
for(Object[] q1 : list){
String name = q1[0].toString();
//..
//do something more on
}