栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何编写Hibernate Criteria以通过投影列表获取嵌套对象?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何编写Hibernate Criteria以通过投影列表获取嵌套对象?

我已经经历过这种要求。我尝试使用来将嵌套对象作为嵌套对象获取

Transformers.aliasToBean
,这将无法正常工作。默认情况下,
Transformers.aliasToBean
没有能力选择嵌套对象作为嵌套对象。

要将嵌套对象作为嵌套对象,您需要一个能够执行此操作的自定义变压器。

这是samiandoni撰写的Custom Transformer

https://github.com/samiandoni/AliasToBeanNestedResultTransformer

从该链接中提供的自述文件中

class Person {  private Long id;  private String name;  private Car car;  // getters and setters}class Car {  private Long id;  private String color;  // getters and setters}List<Person> getPeople() {  ProjectionList projections = Projections.projectionList()    .add(Projections.id().as("id"))    .add(Projections.property("name").as("name"))    .add(Projections.property("c.id").as("car.id"))    .add(Projections.property("c.color").as("car.color"));  Criteria criteria = getCurrentSession().createCriteria(Person.class)    .createAlias("car", "c")    .setProjection(projections)    .setResultTransformer(new AliasToBeanNestedResultTransformer(Person.class));  return (List<Person>) criteria.list();}// each car of Person will be populated

上面的转换器能够将一级嵌套对象作为嵌套对象来获取,并且不支持进一步的深层嵌套对象。因此,在进行一些挖掘之后,我找到了另一个自定义转换器,该转换器可以将深层嵌套对象作为嵌套对象进行提取

注意:

作者:

Miguel Resendiz

import java.lang.reflect.Field;import java.lang.reflect.ParameterizedType;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.HashSet;import java.util.linkedList;import java.util.List;import java.util.Map;import java.util.Set;import org.hibernate.HibernateException;import org.hibernate.property.PropertyAccessor;import org.hibernate.property.PropertyAccessorFactory;import org.hibernate.property.Setter;import org.hibernate.transform.AliasToBeanResultTransformer;import org.hibernate.transform.AliasedTupleSubsetResultTransformer;import org.hibernate.transform.ResultTransformer;public class AliasToBeanNestedResultTransformer extendsAliasedTupleSubsetResultTransformer {    private static final long serialVersionUID = -8047276133980128266L;    private static final int TUPE_INDEX = 0;    private static final int ALISES_INDEX = 1;    private static final int FIELDNAME_INDEX = 2;    private static final PropertyAccessor accessor = PropertyAccessorFactory .getPropertyAccessor("property");    private final Class<?> resultClass;    private Object[] entityTuples;    private String[] entityAliases;    private Map<String, Class<?>> fieldToClass = new HashMap<String, Class<?>>();    private Map<String, List<?>> subEntities = new HashMap<String, List<?>>();    private List<String> nestedAliases = new ArrayList<String>();    private Map<String, Class<?>> listFields = new HashMap<String, Class<?>>();    public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) {        return false;    }    public AliasToBeanNestedResultTransformer(Class<?> resultClass) {        this.resultClass = resultClass;    }    public Object transformTuple(Object[] tuple, String[] aliases) {        handleSubEntities(tuple, aliases);        cleanParams(tuple, aliases);        ResultTransformer rootTransformer = new AliasToBeanResultTransformer(     resultClass);        Object root = rootTransformer.transformTuple(entityTuples,     entityAliases);        loadSubEntities(root);        cleanMaps();        return root;    }    private void handleSubEntities(Object[] tuple, String[] aliases) throws HibernateException {        String fieldName = "";        String aliasName = "";        try { for (int i = 0; i < aliases.length; i++) {     String alias = aliases[i];     if (alias.contains(".")) {         String[] sp = alias.split("\.");         StringBuilder aliasBuilder = new StringBuilder();         for (int j = 0; j < sp.length; j++) {  if (j == 0) {      fieldName = sp[j];  } else {      aliasBuilder.append(sp[j]);      aliasBuilder.append(".");  }         }         aliasName = aliasBuilder.substring(0,      aliasBuilder.length() - 1);         nestedAliases.add(alias);         manageEntities(fieldName, aliasName, tuple[i]);     } }        } catch (NoSuchFieldException e) { throw new HibernateException("Could not instantiate resultclass: "         + resultClass.getName() + " for field name: " + fieldName         + " and alias name:" + aliasName);        }    }    private Class<?> findClass(String fieldName) throws NoSuchFieldException,    SecurityException {        if (fieldToClass.containsKey(fieldName)) { return fieldToClass.get(fieldName);        } else { Class<?> subclass = resultClass.getDeclaredField(fieldName)         .getType(); if (subclass.equals(List.class) || subclass.equals(Set.class)) {     if (subclass.equals(List.class)) {         listFields.put(fieldName, linkedList.class);     } else {         listFields.put(fieldName, HashSet.class);     }     Field field = resultClass.getDeclaredField(fieldName);     ParameterizedType genericType = (ParameterizedType) field  .getGenericType();     subclass = (Class<?>) genericType.getActualTypeArguments()[0]; } fieldToClass.put(fieldName, subclass); return subclass;        }    }    @SuppressWarnings("unchecked")    private void manageEntities(String fieldName, String aliasName, Object tuplevalue) throws NoSuchFieldException, SecurityException {        Class<?> subclass = findClass(fieldName);        if (!subEntities.containsKey(fieldName)) { List<Object> list = new ArrayList<Object>(); list.add(new ArrayList<Object>()); list.add(new ArrayList<String>()); list.add(FIELDNAME_INDEX, subclass); subEntities.put(fieldName, list);        }        ((List<Object>) subEntities.get(fieldName).get(TUPE_INDEX))        .add(tuplevalue);        ((List<String>) subEntities.get(fieldName).get(ALISES_INDEX))        .add(aliasName);    }    private void cleanParams(Object[] tuple, String[] aliases) {        entityTuples = new Object[aliases.length - nestedAliases.size()];        entityAliases = new String[aliases.length - nestedAliases.size()];        for (int j = 0, i = 0; j < aliases.length; j++) { if (!nestedAliases.contains(aliases[j])) {     entityTuples[i] = tuple[j];     entityAliases[i] = aliases[j];     ++i; }        }    }    @SuppressWarnings({ "unchecked", "rawtypes" })    private void loadSubEntities(Object root) throws HibernateException {        try { for (String fieldName : subEntities.keySet()) {     Class<?> subclass = (Class<?>) subEntities.get(fieldName).get(  FIELDNAME_INDEX);     ResultTransformer subclassTransformer = new AliasToBeanNestedResultTransformer(  subclass);     Object subObject = subclassTransformer.transformTuple(  ((List<Object>) subEntities.get(fieldName).get(0))  .toArray(),  ((List<Object>) subEntities.get(fieldName).get(1))  .toArray(new String[0]));     Setter setter = accessor.getSetter(resultClass, fieldName);     if (listFields.containsKey(fieldName)) {         Class<?> collectionClass = listFields.get(fieldName);         Collection subObjectList = (Collection) collectionClass      .newInstance();         subObjectList.add(subObject);         setter.set(root, subObjectList, null);     } else {         setter.set(root, subObject, null);     } }        } catch (Exception e) { throw new HibernateException(e);        }    }    private void cleanMaps() {        fieldToClass = new HashMap<String, Class<?>>();        subEntities = new HashMap<String, List<?>>();        nestedAliases = new ArrayList<String>();        listFields = new HashMap<String, Class<?>>();    }}

只需将samiandoni的Transformer替换为上述变压器即可。它能够获取更深的嵌套对象作为各自的对象。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/377851.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号