因为现有的entity没有关联关系,所以采用原生sql查询多表的数据并返回给dto/vo;
现在个人做法是:
String sql = "select t1.id id1 , t2.id id2,t1.bookName bookName from...." //假设sql如上,然后对应dto就那几个字段。特别:dto的字段是驼峰式的 SQLQuery q = ....; //q.addScalar("id1",StringType.INSTANCE); //... q.setResultTransformer(Transformers.aliasToBean(Dto.class)); /* dto中定义的属性命名和alias是一样的。 但现在的问题是: 如果不定义q.addScalar 那么hibernate在 AliasToBeanResultTransformer.transformTuple(...) 中利用反射的时,得到的别名并不是id1 而是ID1,导致can not find setter */ public Object transformTuple(Object[] tuple, String[] aliases) { Object result; try { if ( ! isInitialized ) { initialize( aliases );//exception } else { check( aliases ); } result = resultClass.newInstance(); for ( int i = 0; i < aliases.length; i++ ) { if ( setters[i] != null ) { setters[i].set( result, tuple[i], null ); } } } catch ( InstantiationException e ) { throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() ); } catch ( IllegalAccessException e ) { throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() ); } return result; } private void initialize(String[] aliases) { PropertyAccessor propertyAccessor = new ChainedPropertyAccessor( new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor( resultClass, null ), PropertyAccessorFactory.getPropertyAccessor( "field" ) } ); this.aliases = new String[ aliases.length ]; setters = new Setter[ aliases.length ]; for ( int i = 0; i < aliases.length; i++ ) { String alias = aliases[ i ]; if ( alias != null ) { this.aliases[ i ] = alias; setters[ i ] = propertyAccessor.getSetter( resultClass, alias ); //exception } } isInitialized = true; }
请问有大神知道怎么较好的解决吗?
1、不要大量的写addScalar。
2、dto不用全部大写。
ps: 自己baidu了下,貌似有人说重写oracle的dialect,或者重写Transforms(感觉重写transform得不到sql中的别名啊)。
在stackoverflow找到的解决:http://stackoverflow.com/questions/37420401/mapping-hibernate-query-results-to-custom-class/37423885#37423885
ta就是通过重写transformers,主要是通过反射找set/get的时候忽略其大小写。
(ps: 之前觉得应该是小工程,但怎么感觉还是蛮多东西的)