Using ResultTransformer
gengmzh
2010-7-5
ResultTransformer 是 Hibernate 的查询结果转换器,在 HQL 、 SQL 、 Criteria 等查询方式中都支持,可以将查询结果灵活地转换为需要的对象,如 Map 、 non-entity bean 。
ResultTransformer 列表
Hibernate 本身提供了下列 transformer
ResultTransformer 接口
transformTuple :处理单行查询结果,将其转换为最终对象。 Hibernate 在处理单行查询结果时,最后调用该方法。
transformList :统一处理最终查询结果集,将其转化为最终对象。 Hibernate 在处理查询结果集时,最后会调用该方法。
AliasToBeanConstructorResultTransformer
transformTuple :以单行查询结果为参数,通过构造子实例化最终对象。
transformList :不做处理。
AliasToBeanResultTransformer
transformTuple :以查询时指定的属性别名作为最终对象的属性名,通过反射实例化最终对象,并调用属性的 setter 方法将查询结果值设置到最终对象里。
transformList :不做处理。
BasicTransformerAdapter
ResultTransformer 的空操作实现类,且是抽象的。
AliasToEntityMapResultTransformer
transformTuple :以查询时指定的别名作为 key ,以结果值作为 value ,将单行查询结果组装成一个 Map 。
transformList :不做处理。
DistinctResultTransformer
transformTuple :不做处理。
transformList :剔除重复的对象,按照 == 判断查询结果是否相同。
PassThroughResultTransformer
transformTuple : 如果单行结果只有一个元素则直接返回该元素值,否则不做处理。
transformList :不做处理。
RootEntityResultTransformer
transformTuple :返回最后一个元素,也就是根实体对象。
transformList :不做处理。
ToListResultTransformer
transformTuple :将单行查询结果由数组转换为 List 。
transformList :不做处理。
DistinctRootEntityResultTransformer
DistinctResultTransformer 和 RootEntityResultTransformer 的组合。
transformTuple :返回最后一个元素,也就是根实体对象。
transformList :剔除重复的对象,按照 == 判断查询结果是否相同。
应用示例
以 AliasToBeanResultTransformer 为例
设若我们有简单的视图层广告物料 Bean ViewAd ,对应复杂的广告物料实体 Ad , ViewAd 的 id 对应 Ad 的 adId ,如下:
通过 AliasToBeanResultTransformer 可以直接将查询结果转换为 ViewAd (当然在只需查询 ViewAd 属性的情况下)。
Criteria 查询
public List<ViewAd> queryAd(Integer userId, String keyword) {
Criterion res = Restrictions.eq("this.userId", userId);
Criteria crit = adDao.createCriteria(res);
crit.add(Restrictions.like("this.name", keyword, MatchMode.ANYWHERE));
ProjectionList pl = Projections.projectionList();
pl.add(Property.forName("adId"), "id"); // 注:别名需与 ViewAd 中的属性名一致
pl.add(Property.forName("name"), "name");
pl.add(Property.forName("width"), "width");
pl.add(Property.forName("height"), "height");
pl.add(Property.forName("type"), "type");
pl.add(Property.forName("status"), "status");
crit.setProjection(pl).setResultTransformer(new AliasToBeanResultTransformer(ViewAd.class));
return crit.list();
}
HQL 查询
public List<ViewAd> queryAd(Integer userId, String keyword) {
StringBuffer hql = new StringBuffer();
hql.append("select ad.adId as id, "); // 注:需通过 as 指定别名
hql.append("ad.name as name, ");
hql.append("ad.width as width, ");
hql.append("ad.height as height, ");
hql.append("ad.type as type, ");
hql.append("ad.status as status ");
hql.append("from Ad ad ");
hql.append("where ad.userId=? and ad.name like ? ");
Query query = adDao.createQuery(hql.toString(), userId, "%" + keyword + "%");
query.setResultTransformer(new AliasToBeanResultTransformer(ViewAd.class));
return query.list();
}
SQL 查询
public List<ViewAd> queryAd(Integer userId, String keyword) {
StringBuffer sql = new StringBuffer();
sql.append("select ad_id as id, "); // 注:需通过 as 指定别名
sql.append("name as name, ");
sql.append("width as width, ");
sql.append("height as height, ");
sql.append("type as type, ");
sql.append("status as status ");
sql.append("from ad ");
sql.append("where user_id=:userId and name like :keyword ");
Map<String, Object> pars = new HashMap<String, Object>();
pars.put("userId", userId);
pars.put("keyword", "%" + keyword + "%");
SQLQuery query = (SQLQuery) adDao.createSQLQuery(sql.toString(), pars);
query.addScalar("id", Hibernate.INTEGER); // 注:并将 as 的别名声明为一个查询项,并指定类型
query.addScalar("name", Hibernate.STRING);
query.addScalar("width", Hibernate.INTEGER);
query.addScalar("height", Hibernate.INTEGER);
query.addScalar("type", Hibernate.INTEGER);
query.addScalar("status", Hibernate.INTEGER);
query.setResultTransformer(new AliasToBeanResultTransformer(ViewAd.class));
return query.list();
}
自定义 ResultTransformer : KeyValueResultTransformer
在某些情况下,我们需要获取某个对象的 id 和 name ,而且要组成一个 Map 。
没有 ResultTransformer 时
public Map<Integer, String> queryAdIdAndName(Integer userId, String keyword) {
Criterion res = Restrictions.eq("this.userId", userId);
Criteria crit = adDao.createCriteria(res);
crit.add(Restrictions.like("this.name", keyword, MatchMode.ANYWHERE));
ProjectionList pl = Projections.projectionList();
pl.add(Property.forName("adId"), "id");
pl.add(Property.forName("name"), "name");
List<Object[]> ol=crit.setProjection(pl).list();
Map<Integer,String> map=new HashMap<Integer,String>();
for(Object[] obj:ol){
if(obj[0]!=null){
map.put((Integer)obj[0], (String)obj[1]);
}
}
return map;
}
使用自定义 KeyValueResultTransformer
public Map<Integer, String> queryAdIdAndName(Integer userId, String keyword) {
Criterion res = Restrictions.eq("this.userId", userId);
Criteria crit = adDao.createCriteria(res);
crit.add(Restrictions.like("this.name", keyword, MatchMode.ANYWHERE));
ProjectionList pl = Projections.projectionList();
pl.add(Property.forName("adId"), "id");
pl.add(Property.forName("name"), "name");
crit.setProjection(pl).setResultTransformer(new KeyValueResultTransformer<Integer, String>());
return (Map<Integer, String>) crit.uniqueResult();
}
KeyValueResultTransformer的实现
transformTuple:不做处理。
transformList:将查询结果集组装成一个Map,实现代码如下:
public class KeyValueResultTransformer<K, V> extends BasicTransformerAdapter {
private static final long serialVersionUID = 5603955993685930635L;
@SuppressWarnings("unchecked")
public List transformList(List list) {
Map<K, V> kvs = new HashMap<K, V>();
for (Object[] obj : (List<Object[]>) list) {
if (obj.length != 2) {
throw new IllegalArgumentException("one row must have two tuples");
}
if (obj[0] != null) {
kvs.put((K) obj[0], (V) obj[1]);
}
}
List<Map<K, V>> ml = new ArrayList<Map<K, V>>();
ml.add(kvs);
return ml;
}
}
转载自原文链接, 如需删除请联系管理员。
原文链接:hibernate ResultTransformer (转),转载请注明来源!