xskow's road.

做好自己,做好一切。
数据加载中……
关于Hibernate Native sql query的诡异问题
        当要做连表查询时,比如a和b,如果a1和b1都有一个name字段,使用下面的sql语句:
        select a.name, b.name from a1 a, b1 b
        假设不作任何处理,毫无疑问返回的是object[]的List,object[0]是a.name, object[1]是b.name。但是,咋们想错了。。。object[0]和object[1]一样是a.name,开始认为是hibernate调用jdbc的resultset时使用了如getString("name")这样的东东,所以得到的都是第0个值。好吧,加个别名试试:
        select a.name as name1, b.name as name2 from a1 a, b1 b
        这好像可以呀。。。但是却报错,找不到name列。。。
        好吧,来个ResultTransformer吧!假设转换目标类为TestDTO.class:
public class TestDTO{
    
private String name1;
    
private String name2;

    
//getters and setters

}
        这回应该好了吧?还是一样的错误。。。
        注意:使用ResultTransformer的时候,别名注射不能用{name1}这种形式的,这种形式只适用于addEntity的情况!
        为什么我要用sql查询?由于特殊情况,我使用一些和数据库有依赖的函数,以后转数据库要是知道不兼容也肯定是sql那块的,而不是hql,解决问题就方便多了。(注:hql一样可以用特定数据库的函数)而且我连的是多个表,每个表字段十来个,如果用实体查询的话,每一行就是三个对象,而我需要的只是5个字段而已。而且如果可以用ResultTransformer的话,操作起来也十分方便。
        不知道有谁也遇到过同样问题?还是说大家都不用hibernate进行sql查询,不管是什么情况?
        得再次研究hibernate官方文档了。。。从文档的那一章中,完全没有找到有同名字段然后又使用ResultTransformer的情况。。。


posted on 2009-06-11 09:57 xskow! 阅读(969) 评论(4)  编辑  收藏 所属分类: SSH探索

评论

# re: 关于Hibernate Native sql query的诡异问题 2009-12-17 21:54 动动

碰到了同样的问题 没解决 ,你的解决了吗?如果解决了 可以告知吗?
先谢过。
我的邮箱:xiangdong.liu@kvect.com
  回复  更多评论    

# re: 关于Hibernate Native sql query的诡异问题 2009-12-19 12:19 Mickey.Shao

@动动
我估计要是你连表的时候有字段名字相同就不行了,最后我还是用了hql解决的。如果连表时候要查的字段名字不一样就不会有问题。哎。。。
  回复  更多评论    

# re: 关于Hibernate Native sql query的诡异问题 2012-09-04 22:59 双方

哎,我来回答下。这个需要增加别名来回避。为了后人
String sql1 = "select l.pos_id,l.id as add2 from launch l where l.id=2734837";
Object list1 = baseDao.createSQLQuery(sql1).addScalar("add2").uniqueResult(); // 失败
System.out.println(list1);

注意一点是别名不能是mysql 关键字,否则会报错

Caused by: com.mysql.jdbc.exceptions.jdbc4.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 'add from launch l where l.id=2734837' at line 1
  回复  更多评论    

# re: 关于Hibernate Native sql query的诡异问题 2012-09-04 23:01 双方

@双方
注意要增加这个 addScalar("add2")
http://blog.csdn.net/wfm0105/article/details/6567476

1.1标量查询
最基本的SQL查询就是获得一个标量(数值)的列表。
1sess.createSQLQuery("SELECT * FROM CATS").list();
2sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
将返回一个Object数组(Object[])组成的List,数组每个元素都是CATS表的一个字段值。Hibernate会使用ResultSetMetadata来判定返回的标量值的实际顺序和类型。
如果要避免过多的使用ResultSetMetadata,或者只是为了更加明确的指名返回值,可以使用addScalar()。

1sess.createSQLQuery("SELECT * FROM CATS")
2 .addScalar("ID", Hibernate.LONG)
3 .addScalar("NAME", Hibernate.STRING)
4 .addScalar("BIRTHDATE", Hibernate.DATE)
这个查询指定了:SQL查询字符串,要返回的字段和类型.它仍然会返回Object数组,但是此时不再使用ResultSetMetdata,而是明确的将ID,NAME和BIRTHDATE按照Long, String和Short类型从resultset中取出。同时,也指明了就算query是使用*来查询的,可能获得超过列出的这三个字段,也仅仅会返回这三个字段。

对全部或者部分的标量值不设置类型信息也是可以的。

1sess.createSQLQuery("SELECT * FROM CATS")
2 .addScalar("ID", Hibernate.LONG)
3 .addScalar("NAME")
4 .addScalar("BIRTHDATE")
基本上这和前面一个查询相同,只是此时使用ResultSetMetaData来决定NAME和BIRTHDATE的类型,而ID的类型是明确指出的。

关于从ResultSetMetaData返回的java.sql.Types是如何映射到Hibernate类型,是由方言(Dialect)控制的。假若某个指定的类型没有被映射,或者不是你所预期的类型,你可以通过Dialet的registerHibernateType调用自行定义.
  回复  更多评论    

只有注册用户登录后才能发表评论。


网站导航:
 
links:shaojiahao's blog