使用 entityManager.createNativeQuery(query,foo.class)

Posted

技术标签:

【中文标题】使用 entityManager.createNativeQuery(query,foo.class)【英文标题】:use of entityManager.createNativeQuery(query,foo.class) 【发布时间】:2011-01-07 19:45:34 【问题描述】:

我想从

返回一个整数列表

javax.persistence.EntityManager.createNativeQuery电话

为什么下面的不正确?

entityManager.createNativeQuery("Select P.AppID From P", Integer.class);

具体为什么我会得到“...未知实体:java.lang.Integer”

我是否必须创建一个具有单个字段的实体类,它是一个整数?

谢谢

【问题讨论】:

【参考方案1】:

您所做的称为投影。那时您只返回一个属于一个实体的 标量 值。您可以使用 JPA 执行此操作。见scalar value。

我认为在这种情况下,完全省略实体类型是可能的:

   Query query = em.createNativeQuery(  "select id from users where username = ?");  
   query.setParameter(1, "lt");  
   BigDecimal val = (BigDecimal) query.getSingleResult(); 

示例取自here。

【讨论】:

是的,我的疏忽我不需要第二个参数。仍然对为什么它不起作用感到困惑。我必须解决这个问题。谢谢 最好使用命名参数而不是"?"【参考方案2】:

这不起作用,因为第二个参数应该是一个映射实体,当然 Integer 不是一个持久类(因为它上面没有 @Entity 注释)。

对你来说,你应该做到以下几点:

Query q = em.createNativeQuery("select id from users where username = :username");
q.setParameter("username", "lt");
List<BigDecimal> values = q.getResultList();

或者如果你想使用 HQL,你可以这样做:

Query q = em.createQuery("select new Integer(id) from users where username = :username");
q.setParameter("username", "lt");
List<Integer> values = q.getResultList();

问候。

【讨论】:

对于 JPA,有没有办法在使用本机查询时指定您希望如何转换标量值?我想在不循环和创建新整数的情况下使用List&lt;Integer&gt; values = q.getResultList(); 在 Hibernate 中,您可以定义自己的方言来将 SQL 类型映射到 Java 类型,看看 org.hibernate.dialect 接口,但这不是标准的 JPA。 阅读此问题的人知道 Oracle 驱动程序不支持命名参数很重要。如果我正在寻找答案,我将不胜感激。 “命名参数的使用未定义为本机查询。” ***.com/questions/3144235/… 命名参数不适用于本机查询(使用 Postgresql 尝试),您应该改用位置参数。【参考方案3】:

这是一个接收参数的 DB2 存储过程

SQL

CREATE PROCEDURE getStateByName (IN StateName VARCHAR(128))
DYNAMIC RESULT SETS 1
P1: BEGIN
    -- Declare cursor
    DECLARE State_Cursor CURSOR WITH RETURN for
    -- #######################################################################
    -- # Replace the SQL statement with your statement.
    -- # Note: Be sure to end statements with the terminator character (usually ';')
    -- #
    -- # The example SQL statement SELECT NAME FROM SYSIBM.SYSTABLES
    -- # returns all names from SYSIBM.SYSTABLES.
    -- ######################################################################
    SELECT * FROM COUNTRY.STATE
    WHERE PROVINCE_NAME LIKE UPPER(stateName);
    -- Cursor left open for client application
    OPEN Province_Cursor;
END P1

Java

//Country is a db2 scheme

//Now here is a java Entity bean Method

public List<Province> getStateByName(String stateName) throws Exception 

    EntityManager em = this.em;
    List<State> states= null;
    try 
        Query query = em.createNativeQuery("call NGB.getStateByName(?1)", Province.class);
        query.setParameter(1, provinceName);
        states= (List<Province>) query.getResultList();
     catch (Exception ex) 
        throw ex;
    

    return states;

【讨论】:

【参考方案4】:

假设您的查询是“select id,name from users where rollNo = 1001”。

这里查询将返回一个带有 id 和 name 列的对象。 您的 Response 类如下所示:

public class UserObject
        int id;
        String name;
        String rollNo;

        public UserObject(Object[] columns) 
            this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
            this.name = (String) columns[1];
        

        public int getId() 
            return id;
        

        public void setId(int id) 
            this.id = id;
        

        public String getName() 
            return name;
        

        public void setName(String name) 
            this.name = name;
        

        public String getRollNo() 
            return rollNo;
        

        public void setRollNo(String rollNo) 
            this.rollNo = rollNo;
        
    

这里UserObject 构造函数将获取一个对象数组并使用对象设置数据。

public UserObject(Object[] columns) 
            this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
            this.name = (String) columns[1];
        

您的查询执行功能如下所示:

public UserObject getUserByRoll(EntityManager entityManager,String rollNo) 

        String queryStr = "select id,name from users where rollNo = ?1";
        try 
            Query query = entityManager.createNativeQuery(queryStr);
            query.setParameter(1, rollNo);

            return new UserObject((Object[]) query.getSingleResult());
         catch (Exception e) 
            e.printStackTrace();
            throw e;
        
    

这里你必须导入波纹管包:

import javax.persistence.Query;
import javax.persistence.EntityManager;

现在你的主类,你必须调用这个函数。 首先,您必须获取 EntityManager 并调用此 getUserByRoll(EntityManager entityManager,String rollNo) 函数。调用过程如下:

@PersistenceContext
private EntityManager entityManager;

UserObject userObject = getUserByRoll(entityManager,"1001");

现在你在这个 userObject 中有数据了。

这里是进口

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

注意:

query.getSingleResult() 返回一个数组。您必须维护列位置和数据类型。

select id,name from users where rollNo = ?1 

查询返回一个数组,它是[0] --&gt; id and [1] -&gt; name

欲了解更多信息,请访问this Answer

谢谢:)

【讨论】:

【参考方案5】:

JPA 旨在提供对象和关系数据库之间的自动映射。由于 Integer 不是持久实体,为什么需要使用 JPA ?一个简单的 JDBC 请求就可以正常工作。

【讨论】:

以上是关于使用 entityManager.createNativeQuery(query,foo.class)的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)