学习记录690@spring data jpa原生查询结果封装工具类

对于复杂的查询,spring data jpa往往需要自己写原生sql,如下:

@Query(value = "select ...; ", nativeQuery = true)
List<Object[]> findAll(String time);

这样的结果需要我们进行封装为实体类,以下给出一个工具类解决。

public class EntityUtils {
    private static Logger logger = LoggerFactory.getLogger(EntityUtils.class);

    /**
     * 将数组数据转换为实体类
     * 此处数组元素的顺序必须与实体类构造函数中的属性顺序一致
     * 不转换数组里面嵌套list类型
     *
     * @param list           数组对象集合
     * @param clazz          实体类
     * @param             实体类
     * @param model          实例化的实体类
     * @return 实体类集合
     */
    @SneakyThrows
    @SuppressWarnings("rawtypes")
    public static <T> List<T> castEntity(List<Object[]> list, Class<T> clazz, Object model) {
        List<T> returnList = new ArrayList<T>();
        if (list.isEmpty()) {
            return returnList;
        }
        //获取每个数组集合的元素个数
        Object[] co = list.get(0);

        //获取当前实体类的属性名、属性值、属性类别
        List<Map> attributeInfoList = getFiledsInfo(model);
        //创建属性类别数组
        Class[] c2 = new Class[attributeInfoList.size()];
        //如果数组集合元素个数与实体类属性个数不一致则发生错误
//        if (attributeInfoList.size() != co.length) {
//            return returnList;
//        }
        //确定构造方法
        for (int i = 0; i < attributeInfoList.size(); i++) {
            c2[i] = (Class) attributeInfoList.get(i).get("type");
        }
        try {
            for (Object[] o : list) {
                Constructor<T> constructor = clazz.getConstructor(c2);
                returnList.add(constructor.newInstance(o));
            }
        } catch (Exception ex) {
            logger.error("实体数据转化为实体类发生异常:异常信息:{}", ex.getMessage());
            throw ex;
        }
        return returnList;
    }

    /**
     * 根据属性名获取属性值
     *
     * @param fieldName 属性名
     * @param modle     实体类
     * @return 属性值
     */
    private static Object getFieldValueByName(String fieldName, Object modle) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = modle.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(modle, new Object[]{});
            return value;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取属性类型(type),属性名(name),属性值(value)的map组成的list
     *
     * @param model 实体类
     * @return list集合
     */
    @SuppressWarnings(value={"unchecked", "rawtypes"})
    private static List<Map> getFiledsInfo(Object model) {
        Field[] fields = model.getClass().getDeclaredFields();
        List<Map> list = new ArrayList(fields.length);
        Map infoMap = null;
        for (int i = 0; i < fields.length; i++) {
            if(!Collection.class.isAssignableFrom(fields[i].getType())){
                infoMap = new HashMap(3);
                infoMap.put("type", fields[i].getType());
                infoMap.put("name", fields[i].getName());
                infoMap.put("value", getFieldValueByName(fields[i].getName(), model));
                list.add(infoMap);
            }
        }
        return list;
    }
}

另外如果你是在代码中使用以下原生查询也可以将结果转换

Query query = entityManager.createNativeQuery(sql);
List<Object[]> resultList = query.getResultList();

你可能感兴趣的:(java)