我有一个扩展Admin
的对象User
。默认情况下,两个对象都在我的Derby数据库的表User_
中(包含Admin
中的字段)。通常我会选择User
这样的:{/ p>
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
。
我的问题是,如何使用具有相同结果的本机查询选择User
作为第一个示例(包括@LOB
和@ManyToOne
的相同值(等等)因为JPQL查询会返回)?
答案 0 :(得分:47)
您可能想尝试以下方法之一:
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
定义的
注释,或<named-native-query>
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()
的使用,请参阅Why you should never use getSingleResult()
in JPA。
答案 1 :(得分:2)
请参阅JPA : How to convert a native query result set to POJO class collection
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);
答案 2 :(得分:0)
接受的答案不正确。
createNativeQuery
将始终返回Query
:
public Query createNativeQuery(String sqlString, Class resultClass);
在getResultList
上调用Query
返回List
:
List getResultList()
向List<MyEntity>
分配(或强制转换)时,会产生未经检查的分配警告。
createQuery
将返回TypedQuery
:
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass);
在getResultList
上调用TypedQuery
会返回List<X>
。
List<X> getResultList();
此输入正确,不会发出警告。
对于createNativeQuery
,使用ObjectMapper
似乎是消除警告的唯一方法。就我个人而言,我选择不显示警告,因为我认为这是库中的缺陷,而我不必担心。
答案 3 :(得分:0)
当您的本机查询基于联接时,在这种情况下,您可以将结果作为对象列表进行处理。
一个简单的例子。
@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
}
答案 4 :(得分:-1)
首先创建一个模型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
}
控制器
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<StdUser> actionIndex() {
EntityManager em = emf.createEntityManager(); // Without parameter
List<StdUser> arr_cust = (List<StdUser>)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;
}
}