小妹花了一天的时间,终于研究出点结果,很是高兴啊,但是还有好几个问题不明白,现在来交代一下事情经过:领导要求通过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;
        }
在这里我要注意以下几点:   1. 不管是HQLorNativeSQL查询一个类型为char的column,它的value都包含空格,得trim()
   2. join方式的连接,是依靠hbm配置文件的。没有配置one-many和many-one,只能使用NativeSQL去写join语句
   3. 使用Query query = arg0.createSQLQuery(queryString),执行query.iterate()会报错:使用原生sql时候,query不支持直接迭代!
   4. 不管NativeSQL,select出多少个columns,只要使用了addScalar()方法,就只会显示出注册了的字段,所以如果想要得到更多的字段,就得把更多的字段addScalar()

几点疑问:   1. 使用NativeSQL后,各种类型的columns所返回的java对象类型,由什么决定?数据库的驱动?
   2. 我在oracle上做过测试,Integer类型的column,返回的是java.math.BigDecimal;可是在sqlserver2005上,则是Integer?!

解决方案 »

  1.   

    1.NativeSQL表示不懂。
    2.不同的DB可能定义该字段的类型不一样吧,或许精度不同。问题:
    1.NativeSQL返回的结果集是什么样的?ResultSet?
      

  2.   

    刚没看代码,addScalar("planId", Hibernate.LONG);
    Hibernate.LONG对应的是java.lang.Long吗?
      

  3.   


    NativeSQL就是原生sql。
    因为我希望planId,返回的类型是java.lang.Long。所以才注册了。
    默认给我返回的是Integer类型。
      

  4.   

    貌似hibernate配置文件有java类型和DB类型的映射吧。
      

  5.   

    大哥你看没看我的帖子啊?
    NativeSQL时候,不会读取hibernate的hbm配置文件!!!
      

  6.   

    没仔细看没关系啊,他不读取配置文件,你自己写个读取配置文件的方法。解析个dom不难吧。