没事就学学 2009-09-03 11:32
浏览 383
已采纳

[极品难]关于hibernate如何把原生sql查出的结果转化为对象

例如我们有一个照片的PO

Java code
//照片po
class Photo
{
   int id;
   string title;
   double avgScore;//平均分,这个字段在数据库中是没有映射的,也就是 非持久化属性
}

//投票po ,每张照片对应多个vote记录
class Vote
{
   int id;
   int photoId;
   int score;
}



用sql = "select {p.*,avg(v.score) as p.avgScore} from photo p left join vote v on p.id = v.photoId ";
单纯的sql结果很满意,包含照片的信息和每张照片的平均分数。

代码如下:
Query query = session.createSQLQuery(sql.toString()).addEntity(Photo.class);

运行后,没有错误,但是在SQL语句中的avg(v.score) as p.avgScore} 这一部分,没有被像我们预期的那样set进photo的avgScore属性中。


问题:
我们如果遇到要用原生sql进行查询,并要将结果set进一个po中,其中set进po中的属性,不完全是被可持久化的,例如本例
中的avgScore属性。

期待大家来解答这个疑惑~谢谢! thanks a lot !

PS: 请别和我说完全可以用hql等方式,这只是个简单的示例,目前是想研究原生sql对象映射问题。

问题补充:
首先谢谢yangtao309您的回答!~

我仔细看了那篇文章,addScalar这个的意思似乎只是把查出来的非属性结果进行类型绑定,我现在的困惑是如果把这个值自动绑定进po中~~

就像上面的例子,select出一个po,然后这个po中要有那个avgScore的属性值,目前我试过即使用addScalar明确avgScore的类型,还是不会自动set进po中。。

是不是我哪弄错了,还是什么原因,希望大家再帮我看看
问题补充:
谢谢您 walsh 的回答,我觉得您说的很有道理 ,我现在用的MYSQL5,按您的提示,运行后,控制台打出下样异常,繁请帮忙看下,谢谢!



打印出的SQL:
sql:  select {p.id,p.user_id,p.url,p.state,avg(v.score) as p.avgScore} from photos p  where p.user_id = :userId and p.state in ( 0, 1 )  group by p.id  order by  p.id desc





报了个这个错:
44187 [http-8080-1] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1064, SQLState: 42000
44187 [http-8080-1] ERROR org.hibernate.util.JDBCExceptionReporter - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from photos p  where p.user_id = 13 and p.state in ( 0, 1 )  group by p.id  orde' at line 1
2009-9-3 12:04:39 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet default threw exception
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from photos p  where p.user_id = 13 and p.state in ( 0, 1 )  group by p.id  orde' at line 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)

问题补充:
为什么要对所有字段字组??这原因和自动set进po应该没直接关系吧?

问题补充:
改成group by p.id, p.user_id,p.url,p.state仍然是之前的错误。

如果不加{}那么就报在数据库找不到p.avgScore这列,因为p.avgScore是一个虚似的临时变量,非持久化属性。

谢谢,再帮忙想想~~~
问题补充:
谢谢,WALSH再次的回答。

我提问题时只是简单写的示例,省略了几个字段,
sql = "select p.id,avg(v.score) from photo p , vote v where p.id = v.photoId  group by p.id";  

这么写是可以,但不会被自动绑定进PO,我来问就是想知道在不调用SET方法的情况下能否自动把非字段属性绑定进PO。

如果是单调set方法,我是知道的~~有没有自动的方式,谢谢walsh不遗余力的帮我解决这个问题。谢谢!

您看看有没有自动的方式绑定进PO的。。

问题补充:
您好walsh,我也知道hibernate会找set方法,但有可能还会只限制在*.hbm.xml文件中声明,或者只被@Cloumn注解的属性字段。。

因为我返回avg(v.score) as p.avgScore,其实在p这个po中是有setAvgScore()这个方法的,可是终始不会被调用 。。。

我甚至做过这个测试,把avgScore()设成@Cloumn(insertable=false,updateable=false),还是不会自动set进po中。。


对这个问题看来基本明确了。。可能就是不行,只能返回object[]来一个个的set了吧?

  • 写回答

10条回答

  • walsh_bupt 2009-09-03 15:26
    关注

    [quote]avg(v.score) as p.avgScore[/quote]

    前面我不是给你说过了吗,你这样写,只是为平均分avg(v.score)起了一个名字是p.avgScore,这个名只是字符串,和你所谓的引用变量没有任何关系,明白吗

    你这个地方主要是这样写了,如果你换为

    [quote]avg(v.score) as 平均分[/quote]

    这样也是对的,as后面只是一个别名,和属性还有引用变量p没有任何关系。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(9条)

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题