Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA本机查询选择和转换对象_Java_Sql_Jpa_Jpql - Fatal编程技术网

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)
    还可以使用
    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();
    
  • 使用注释
    @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 
     }