【问题标题】:Playframework How to transform query.ResultList to VOPlay Framework 如何将 query.Result Set 转换为 GO
【发布时间】:2012-08-29 04:38:58
【问题描述】:

Playframework的版本是1.2.x,想把query.ResultList转成VO。

我创建了一个 Part 实体 bean,如下所示:

@Entity
@Table(name="evaluation_part")
public class Part extends Model {

    public String name;  

    public String collegeName;

    public int peopleNum;
}

数据:

id     name     collegeName      peopleNum

1      Jsj1     JJJJ              32
2      Jsj2     JJJJ              23
3      Jsj3     JJJJ              32
4      Tjb1     TTTT              11
5      Tjb2     TTTT              14
6      Tjb3     TTTT              16

我的价值对象类:

public class PartVO {

    public String collegeName;

    public int peopleNum;

}

而我想使用原生查询来获得结果:

String sql="select collegeName,SUM(peopleNum) as peopleNum from evaluation_part group by collegeName";

查询结果为:

      collegeName      peopleNum

        TTTT              41
        JJJJ              87

我试过了:

String sql="select collegeName,SUM(peopleNum) as peopleNum from evaluation_part group by collegeName";

Query query =JPA.em().createNativeQuery(sql);

List<PartVO> partVOs = query.getResultList();
for(int i=0;i<partVOs.size();i++) {      
    System.out.println(partVOs.get(i).collegeName);
}

我得到的是以下错误

ClassCastException occured : [Ljava.lang.Object; cannot be cast to valueobject.PartVO

【问题讨论】:

    标签: jpa playframework transform


    【解决方案1】:

    您不必使用原始 sql 来执行此操作。使用 hql,您可以使用 new 运算符创建您的 VO(请参阅http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-select

    您必须在您的 partVO 类中定义一个两个 arg 构造函数,然后您可以这样做

    select new package.PartVO(collegeName, SUM(peopleNum)) from Part group by collegeName
    

    【讨论】:

    • 我不认为你可以在使用 JPA 的 Play Framework 中使用 HQL(Hibernate 查询语言)。
    • 当然可以,Play 1.2.x 在下面使用休眠。我在我的应用程序中使用这种技术没有任何问题
    【解决方案2】:

    解决方案1:仅在HQL中使用'select new Part()'(在Part类中定义的构造函数),您可以将对象转换为Part。Hibernate使用反射自动注入您需要的所有字段。

    解决方案2:这里返回的结果类型必须是Object[],这样你就可以通过数组的索引从数据库中获取记录的每个字段;

    solution1和solution2的区别:前者在查询中使用构造函数,后者将一条记录转化为Object[]。

    在你的情况下,忽略实体之间的复杂关系,上面的解决方案会起作用。

    此处参考代码:

    package controllers;
    
    import play.*;
    import play.db.jpa.JPA;
    import play.mvc.*;
    import java.util.*;
    
    import models.*;
    
    /**
    * This demo is intended for fetching data from MYSQL.
    * @author dhl@oopsplay.org
    */
    
    public class Application extends Controller {
    
    public static void index() {
        render();
    }
    
    /**
     * Prepare some data to test.
     */
    public static void addPart() {
    
        //Add a part record to database.
        Part newPart=new Part("software","zjut",8).save();
        if(newPart.isPersistent()){
            renderText("Add successfully,there are %s records in the \'evaluation_part\' table.For convenience,please click the back button in the browser to go back previous page.",Part.count());
        }
    }
    
    /**
     * Fetch part entities from database;
     */
    public static void fetchPart() {
    
        //-------------------Solution 1-------------------
        //[Pay attention]:Only use 'select new Part()'(constructor defined in the Part class) in the query that u can  convert object to Part.
        //Hibernate use reflection to automatically inject all the fields u need.
        List<Part> parts1=JPA.em().createQuery("select new Part(name,collegeName,peopleNum) from Part").getResultList();
    
        //For convenience, i output the detail in the console, focus on the change there.
        Logger.info("The name of first record is :%s", parts1.get(0).name);
    
        //-------------------Solution 2-------------------
        //[Pay attention]:Here the returned type of result must be Object[],so that u can got every field of the record fetched from database;
        List<Object[]> parts2=JPA.em().createNativeQuery("select name,collegeName,peopleNum from evaluation_part").getResultList();
        Logger.info("The name of first record is :%s", parts2.get(0)[0]);
    
        for(int i=0;i<parts2.size();i++){
    
            //The difference between solution1 and solution2:the previous use constructor in the query and the later transform a record into Object[].
            Logger.info("Name from parts1 is: %s", parts1.get(i).name);
            Logger.info("Name from parts2 is: %s", parts2.get(i)[0]);
        }
    
        renderText("There are %s record in the \'evaluation_part\' table",parts2.size());
    }
    

    }

    【讨论】:

      【解决方案3】:

      您可以使用 createNativeQuery(...) 方法的版本,该方法也接受结果实例的 Class 作为参数:

      http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#createNativeQuery(java.lang.String, java.lang.Class)。

      但请确保这确实有效,因为 Play Framework 并未在其 API 实现中实现 JPA 的所有功能。

      【讨论】:

        猜你喜欢
        • 2014-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-01
        • 2015-08-20
        • 2013-09-09
        • 2016-07-05
        • 2011-08-24
        相关资源
        最近更新 更多