小妹花了一天的时间,终于研究出点结果,很是高兴啊,但是还有很多问题!现在来交代一下事情经过:
领导要求通过left join 查询实现一个功能——在代码表(dm_ship)里有哪些行,被业务表(t_plan)引用过了,但是要显示所有的(dm_ship)数据,被引用过的数据给做一个标记。
第一次遇到问题(使用HQL时候我发现不能使用left join语法):
因为HQL的left join语法里面没有on关键字,两个表的连接是通过hbm文件里面的one-many和many-one配置实现的,因为HQL里面不需要on关键字。
但是问题来了,我们的项目里面的pojo-hbm配置里面,完全都不使用one-many和many-one(历史项目,小妹也无奈55555555),所以不能修改hbm配置。
第二次遇到问题(使用NativeSQL查询数据发现内容丢失)
那么小妹用NativeSQL实现left join功能,但是发现结果集里面数据都是java的char类型,只有一个字符。这是为什么?!
原来,代码表(dm_ship)里的columns的类型是char(35),NativeSQL查询后,不会读取hbm文件,所以不会返回String类型。
但是也不能返回char类型吧(难道是驱动的原因?!希望哪位大哥帮助)。
第三次遇到问题(我们team无权修改数据库column类型)
我本来打算修改修改column的类型,但是我们team被告知不能修改,因为怕影响到现有的stored procedure...
通过HQL单独查询代码表(dm_ship)发现所有char类型的columns的value都有空格!
第四次终于解决问题(使用NativeSQL时,调用addScalar("code", Hibernate.STRING)方法):
public List<GeneralCode> findShipListByOccupied(){ List<GeneralCode> shipList = null; shipList = this.getHibernateTemplate().executeFind(new HibernateCallback() { @Override public List doInHibernate(Session arg0) throws HibernateException, SQLException { List<GeneralCode> list = new ArrayList<GeneralCode>(); String queryString = "select distinct ship.code,ship.value,plan.planId from dm_ship ship "+ " left join t_plan plan on plan.shipCode = ship.code"; Query query = arg0.createSQLQuery(queryString). addScalar("code", Hibernate.STRING). addScalar("value", Hibernate.STRING). addScalar("planId", Hibernate.LONG); Iterator it = query.list().iterator(); while(it.hasNext()){ GeneralCode item = new GeneralCode(); Object [] obj = (Object [])it.next(); if(obj[0]==null||obj[1]==null)continue; item.setCode(((String)obj[0]).trim()); item.setDesc(((String)obj[1]).trim()); if(obj[2]==null){ }else{ item.setDesc("(occupied)"+item.getDesc()); } System.out.println(item.getCode()+":"+item.getDesc()); list.add(item); } return list; } }); return shipList; }
在这里我要注意以下几点:
- 不管是HQLorNativeSQL查询一个类型为char的column,它的value都包含空格,得trim()
- join方式的连接,是依靠hbm配置文件的。没有配置one-many和many-one,只能使用NativeSQL去写join语句
- 使用Query query = arg0.createSQLQuery(queryString),执行query.iterate()会报错:使用原生sql时候,query不支持直接迭代!
- 不管NativeSQL,select出多少个columns,只要使用了addScalar()方法,就只会显示出注册了的字段,所以如果想要得到更多的字段,就得把更多的字段addScalar()
几点疑问:
- 使用NativeSQL后,各种类型的columns所返回的java对象类型,由什么决定?数据库的驱动?
- 我在oracle上做过测试,Integer类型的column,返回的是java.math.BigDecimal;可是在sqlserver2005上,则是Integer?!