java 查询转对象_关于Java:JPA本机查询选择和转换对象

我有一个扩展了User的对象Admin。 默认情况下,两个对象都在我的Derby数据库的表User_中(Admin中包含的字段)。 通常,我会选择这样的User:

CriteriaBuilder cb = em.getCriteriaBuilder();

CriteriaQuery 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中的任何字段所致。

我的问题是,如何使用本机查询选择一个具有相同结果的User作为第一个示例(包括与JPQL查询返回的值相同的@LOB和@ManyToOne(等等)的值)?

是什么使查询对于JPQL而言过于复杂?

@damo这是一个简化的示例,实际查询包含许多子查询,SUM,COALESCENSE,CASE等。

检查此答案。 它具有完整的答案:stackoverflow.com/a/50365522/3073945

您可能想尝试以下方法之一:

使用方法createNativeQuery(sqlString, resultClass)

还可以使用EntityManager.createNativeQuery() API动态定义本机查询。

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();

使用注释@NamedNativeQuery

本地查询是通过@NamedNativeQuery和@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();

您可以在精美的开放书《 Java Persistence》(PDF格式)中阅读更多内容。

────────

注意:关于getSingleResult()的使用,请参阅为什么不应该在JPA中使用getSingleResult()。

第一个成功了! 谢谢 :)

@PaulVargas如果结果是整数而不是实体,该怎么办

@PaulVargas,我建议做这样的事情:Integer val =(Integer)query.getSingleResult(); 但是,我通常建议不要使用query.getSingleResult(),因为它会引发许多已检查的异常。 如果您以列表的形式获得结果,那么您将无法处理任何结果,因此不能处理多个结果。

嘿,@ Joe。 谢谢! -我继续使用query.getSingleResult(),因为OP。 :)

接受的答案不正确。

createNativeQuery将始终返回Query:

public Query createNativeQuery(String sqlString, Class resultClass);

在Query上调用getResultList会返回List:

List getResultList()

当将(或强制转换)分配给List时,将产生未经检查的分配警告。

而createQuery将返回TypedQuery:

public < T > TypedQuery< T > createQuery(String qlString, Class< T > resultClass);

在TypedQuery上调用getResultList返回List。

List getResultList();

输入正确,不会发出警告。

对于createNativeQuery,使用ObjectMapper似乎是摆脱警告的唯一方法。就我个人而言,我选择不显示警告,因为我认为这是库中的不足,而我不必担心。

请参考JPA:如何将本机查询结果集转换为POJO类集合

对于Postgres 9.4,

List 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);

当您的本机查询基于联接时,在这种情况下,您可以将结果作为对象列表进行处理。

一个简单的例子。

@Autowired

EntityManager em;

String nativeQuery ="select name,age from users where id=?";

Query query = em.createNativeQuery(nativeQuery);

query.setParameter(1,id);

List list = query.getResultList();

for(Object[] q1 : list){

String name = q1[0].toString();

//..

//do something more on

}

First of all create a model POJO

import javax.persistence.*;

@Entity

@Table(name ="sys_std_user")

public class StdUser {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

@Column(name ="class_id")

public int classId;

@Column(name ="user_name")

public String userName;

//getter,setter

}

Controller

import com.example.demo.models.*;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;

import javax.persistence.PersistenceUnit;

import java.util.List;

@RestController

public class HomeController {

@PersistenceUnit

private EntityManagerFactory emf;

@GetMapping("/")

public List actionIndex() {

EntityManager em = emf.createEntityManager(); // Without parameter

List arr_cust = (List)em

.createQuery("SELECT c FROM StdUser c")

.getResultList();

return arr_cust;

}

@GetMapping("/paramter")

public List actionJoin() {

int id = 3;

String userName ="Suresh Shrestha";

EntityManager em = emf.createEntityManager(); // With parameter

List arr_cust = em

.createQuery("SELECT c FROM StdUser c WHERE c.classId = :Id ANd c.userName = :UserName")

.setParameter("Id",id)

.setParameter("UserName",userName)

.getResultList();

return arr_cust;

}

}

来源:oracle.com/technetwork/articles/vasiliev-jpql-087123.html

在rest控制器内部编写数据访问代码不是一个好习惯。 将数据访问代码存储在@ Repository类中。 从@服务类调用存储库。 从@ RestController访问@ Service类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值