由将SQL查询结果转化为pojo的想到的
2009-10-26 11:52
357 查看
今天在网上上看见一篇“将SQL查询结果转化为pojo对象的”博客,博主自定义做了一个类如下:
import java.lang.reflect.Field;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.property.ChainedPropertyAccessor;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.Setter;
import org.hibernate.transform.ResultTransformer;
/**
* 完成native sql查询数据(数组)到pojo对象的转化
* @author warison
*
* Oct 26, 2009
*/
public class PojoTransformer implements ResultTransformer {
private static final long serialVersionUID = 1L;
private Class<? extends BaseModel> resultClass;
private Setter[] setters;
private PropertyAccessor propertyAccessor;
public PojoTransformer(Class<? extends BaseModel> resultClass) {
if(resultClass==null)
throw new IllegalArgumentException("resultClass cannot be null");
this.resultClass = resultClass;
propertyAccessor = new ChainedPropertyAccessor(new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor(resultClass,null), PropertyAccessorFactory.getPropertyAccessor("field")});
}
//结果转换时,HIBERNATE调用此方法
public Object transformTuple(Object[] tuple, String[] aliases) {
Object result;
try {
if(setters==null) {//首先初始化,取得目标POJO类的所有SETTER方法
setters = new Setter[aliases.length];
for (int i = 0; i < aliases.length; i++) {
String alias = aliases[i];
if(alias != null) {
//我的逻辑主要是在getSetterByColumnName方法里面,其它都是HIBERNATE的另一个类中COPY的
//这里填充所需要的SETTER方法
setters[i] = getSetterByColumnName(alias);
}
}
}
result = resultClass.newInstance();
//这里使用SETTER方法填充POJO对象
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;
}
//根据数据库字段名在POJO查找J***A属性名,参数就是数据库字段名,如:USER_ID
private Setter getSetterByColumnName(String alias) {
//取得POJO所有属性名
Field[] fields = resultClass.getDeclaredFields();
if(fields==null || fields.length==0){
throw new RuntimeException("实体"+resultClass.getName()+"不含任何属性");
}
//把字段名中所有的下杠去除
String proName = alias.replaceAll("_", "").toLowerCase();
for (Field field : fields) {
if(field.getName().toLowerCase().equals(proName)){//去除下杠的字段名如果和属性名对得上,就取这个SETTER方法
return propertyAccessor.getSetter(resultClass, field.getName());
}
}
throw new RuntimeException("找不到数据库字段 :"+ alias + " 对应的POJO属性或其getter方法,比如数据库字段为USER_ID或USERID,那么J***A属性应为userId");
}
@SuppressWarnings("unchecked")
public List transformList(List collection) {
return collection;
}
}
public class PojoUser extends BaseModel {
private String pwd;
private String userName;
private String userId;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
测试方法:
String queryString="select user_id userId,user_name userName from oa_user";
SQLQuery query = sessionFactory.openSession().createSQLQuery(queryString);
query.setResultTransformer(new PojoTransformer(pojoClass));
query.list();
看到这里,容易想到,hiernate3.2以后好像已经支持这种方法
SQLQuery query = sessionFactory.openSession().createSQLQuery(queryString);
query.addScalar("userName", Hibernate.STRING);
query.setResultTransformer(Transformers.aliasToBean(pojoClass));
System.out.println(((PojoUser)list.get(0)).getUserName());
结果发现如果query.addScalar("userName", Hibernate.STRING);定义为
query.addScalar("userId", Hibernate.STRING);
打印的结果就是null(实际上是存在值的),不尽感动hiernate的愚蠢,难道没有设置全部属性(或当前查询对应属性的方法吗),如果像hiernate的做,岂不是要将所有查询的属性都设置一次query.addScalar。
看到这里可能你会用query.addEntity(PojoUser.class);反驳我,可以使用query.addEntity(PojoUser.class);前提是PojoUser.class已经做了映射。
相比下,上面博主的方法还算是可行。
类似问题,很容易让我想到ibtatis的处理方式,弄过ibatis的人都晓得,累世的问题简直就是小菜。
到这里不尽想说一句“不要迷恋Hibernate,Hibernate只是一传说。。。” 。毕竟hiernate的最终目标是hql查询支持,对于sql的支持可能还是存在一定的缺陷。o(∩_∩)o...哈哈
import java.lang.reflect.Field;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.property.ChainedPropertyAccessor;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.Setter;
import org.hibernate.transform.ResultTransformer;
/**
* 完成native sql查询数据(数组)到pojo对象的转化
* @author warison
*
* Oct 26, 2009
*/
public class PojoTransformer implements ResultTransformer {
private static final long serialVersionUID = 1L;
private Class<? extends BaseModel> resultClass;
private Setter[] setters;
private PropertyAccessor propertyAccessor;
public PojoTransformer(Class<? extends BaseModel> resultClass) {
if(resultClass==null)
throw new IllegalArgumentException("resultClass cannot be null");
this.resultClass = resultClass;
propertyAccessor = new ChainedPropertyAccessor(new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor(resultClass,null), PropertyAccessorFactory.getPropertyAccessor("field")});
}
//结果转换时,HIBERNATE调用此方法
public Object transformTuple(Object[] tuple, String[] aliases) {
Object result;
try {
if(setters==null) {//首先初始化,取得目标POJO类的所有SETTER方法
setters = new Setter[aliases.length];
for (int i = 0; i < aliases.length; i++) {
String alias = aliases[i];
if(alias != null) {
//我的逻辑主要是在getSetterByColumnName方法里面,其它都是HIBERNATE的另一个类中COPY的
//这里填充所需要的SETTER方法
setters[i] = getSetterByColumnName(alias);
}
}
}
result = resultClass.newInstance();
//这里使用SETTER方法填充POJO对象
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;
}
//根据数据库字段名在POJO查找J***A属性名,参数就是数据库字段名,如:USER_ID
private Setter getSetterByColumnName(String alias) {
//取得POJO所有属性名
Field[] fields = resultClass.getDeclaredFields();
if(fields==null || fields.length==0){
throw new RuntimeException("实体"+resultClass.getName()+"不含任何属性");
}
//把字段名中所有的下杠去除
String proName = alias.replaceAll("_", "").toLowerCase();
for (Field field : fields) {
if(field.getName().toLowerCase().equals(proName)){//去除下杠的字段名如果和属性名对得上,就取这个SETTER方法
return propertyAccessor.getSetter(resultClass, field.getName());
}
}
throw new RuntimeException("找不到数据库字段 :"+ alias + " 对应的POJO属性或其getter方法,比如数据库字段为USER_ID或USERID,那么J***A属性应为userId");
}
@SuppressWarnings("unchecked")
public List transformList(List collection) {
return collection;
}
}
public class PojoUser extends BaseModel {
private String pwd;
private String userName;
private String userId;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
测试方法:
String queryString="select user_id userId,user_name userName from oa_user";
SQLQuery query = sessionFactory.openSession().createSQLQuery(queryString);
query.setResultTransformer(new PojoTransformer(pojoClass));
query.list();
看到这里,容易想到,hiernate3.2以后好像已经支持这种方法
SQLQuery query = sessionFactory.openSession().createSQLQuery(queryString);
query.addScalar("userName", Hibernate.STRING);
query.setResultTransformer(Transformers.aliasToBean(pojoClass));
System.out.println(((PojoUser)list.get(0)).getUserName());
结果发现如果query.addScalar("userName", Hibernate.STRING);定义为
query.addScalar("userId", Hibernate.STRING);
打印的结果就是null(实际上是存在值的),不尽感动hiernate的愚蠢,难道没有设置全部属性(或当前查询对应属性的方法吗),如果像hiernate的做,岂不是要将所有查询的属性都设置一次query.addScalar。
看到这里可能你会用query.addEntity(PojoUser.class);反驳我,可以使用query.addEntity(PojoUser.class);前提是PojoUser.class已经做了映射。
相比下,上面博主的方法还算是可行。
类似问题,很容易让我想到ibtatis的处理方式,弄过ibatis的人都晓得,累世的问题简直就是小菜。
到这里不尽想说一句“不要迷恋Hibernate,Hibernate只是一传说。。。” 。毕竟hiernate的最终目标是hql查询支持,对于sql的支持可能还是存在一定的缺陷。o(∩_∩)o...哈哈
相关文章推荐
- SQL将查询的结果转化为XML格式数据
- Hibernate自定义SQL查询结果自动反射到POJO
- Hibernate3.2.6 原生sql 查询使用方法,将查询结果直接转换为POJO,不必非要指定属性大写
- SQL 查询结果出现问号
- sql语句查询结果合并unionall用法
- 内部类解析sql查询获取的数据结果
- Oracle查询Sql语句中的时间格式转化
- SQL SERVER 2000 的企业管理器与查询分析器对于同一SQL语句有两个不同查询结果!
- 数据库-使用查询到的不同字段的两条SQL的结果进行筛选查询
- 为什么数据可以从pl/sql查出来而使用ado.net查询,结果却是空?
- SQL 多条件查询多结果
- SQL技巧(2) 查询结果排序
- mybatis如何直接 执行传入的任意sql语句 并按照顺序取出查询的结果集
- sql 查询结果 excel
- SQL之查询结果排序
- 多表查询语句写法、数据库数字如何转化为汉子、Sql语句拼接
- sql语句查询结果合并union 和union all用法
- SQL Server 中的XML支持,查询返回XML,Web访问SQL取XML形式结果
- PL/SQL DEVELOPER中查询结果复制出来中文乱码的解决方案
- oracle sql 查询结果 翻转