其他分享
首页 > 其他分享> > 反射结合泛型实现任意对象的创建

反射结合泛型实现任意对象的创建

作者:互联网

一、反射及泛型

反射可以通过Class创建对象,而泛型则可以创建程序模板。

二、Mybatis中的应用

2.1定义mapper

定义一个通用的sql,允许传入表名table,以及查询条件where,返回值List<Map<String,Object>>。

public interface CommonMapper {

    @Select("select * from ${table} where ${where}")
    List<Map<String,Object>> GetList(@Param(value="table") String table, @Param(value="where") String where);
}

2.1定义service

我们使用通配符接收Class,然后通过Class.getDeclaredConstructor().newInstance()创建一个新对象,然后使用 BeanUtils.populate()填充对象。其实我们这里也就是相当于实现了Mybatis-plus自带的功能,不建议这样做,因为反射的消耗也挺大的。

 public <E> List<E> GetList(Class<?> resultType, String where) throws Exception {
        ArrayList<E> results = new ArrayList<E>();
       
        ConvertUtils.register(new MyConverter(), LocalDateTime.class);
        List<Map<String,Object>>result= commonMapper.GetList(resultType.getSimpleName(),where);
        for(Map<String,Object> m:result){
            E e= (E) resultType.getDeclaredConstructor().newInstance();
            m=formateMapKey(m);
            BeanUtils.populate(e, m);
            results.add(e);
        }
        return results;
    }
 /**
     * 将数据库返回的键值修改为符合java Bean的规范,前两个字母要么大写要么小写
     * @param orgMap
     * @return
     */
    public  Map<String, Object> formateMapKey(Map<String, Object> orgMap) {
        Map<String, Object> resultMap = new HashMap<>();
        if (orgMap == null || orgMap.isEmpty()) {
            return resultMap;
        }
        Set<String> keySet = orgMap.keySet();
        for (String key : keySet) {
            String newKey= formatJavaBeanName(key);
            resultMap.put(newKey, orgMap.get(key));
        }
        return resultMap;
    }

三、WebService中的应用

3.1 解析对象构建xml

传入对象T,获取到CLass对象,再拿到相应的Field对象,遍历每个属性,获取到相应的get方法然后获取属性值,最后组装xml字符串。获取属性值,还可以使用Field.get方法。

   public static <T> String Analysis(T m_Value) throws Exception {
        String m_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
        m_XML += "<DBSET>\n";
        m_XML += "<ROW>\n";
        Field[] fields = m_Value.getClass().getDeclaredFields();
        for (var property : fields) {
            //获取属性的名字
            String name = property.getName();
            //将属性名字的首字母大写
            name = name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
            //整合出 getId() 属性这个方法
            Method m = m_Value.getClass().getMethod("get" + name);
            //调用这个整合出来的get方法,强转成自己需要的类型
            Object obj = m.invoke(m_Value);
            if (obj == null) {
                obj = "";
            }
            m_XML += "<" + property.getName() + ">";
            switch (property.getType().getName()) {
                case "LocalDateTime":
                    m_XML += DateUtil.format((LocalDateTime) obj, "yyyy-MM-dd HH:mm:s");
                    break;
                default:
                    m_XML += obj.toString();
                    break;
            }
            m_XML += "</" + property.getName() + ">\n";
        }
        m_XML += "</ROW>";
        m_XML += "</DBSET>";
        logger.info(m_XML);
        return m_XML;
    }

3.1 解析XML字符串转换为对象

特别注意使用到了PropertyDescriptor

    public static <T> T ResolveXML(T o, String sXml) throws Exception {
        String Result = "";
        Document document = DocumentHelper.parseText(sXml);

        Element rootElement = document.getRootElement();
       // rootElement = rootElement.element("DBSET");
        rootElement = rootElement.element("ROW");
        Class cls = o.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (var property : fields) {
            //获取属性的名字
            String columnName = property.getName();
            Element node = rootElement.element(columnName);
            if (node == null || StringUtils.isBlank(node.getText()))
                continue;
            Result = node.getTextTrim();
            //使用反射或者内省,根据数据库表和实体的对应关系,完成封装
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, cls);
            Method writeMethod = propertyDescriptor.getWriteMethod();
            writeMethod.invoke(o, Result);
        }
        return o;
    }

标签:XML,反射,return,String,任意,rootElement,泛型,where,name
来源: https://blog.csdn.net/jiqiren1994/article/details/118877745