zoukankan      html  css  js  c++  java
  • java反射保存

    前言

    代码是我师父的,代码是我师父的,代码是我师父的,如有需要拿走的时候请标注  copyright by 山人Wu  记录这篇是为了加深理解,前段时间只是当做工具类来用,才有时间好好看一下,加深理解。

    背景

    项目中涉及到从excel表导入,很多模块都涉及到了,从excel里面拿到的值都是字符串,运用起来比较麻烦,所以师父写了一个工具类,可以将excel得到的数据直接映射成对象。得到的excel里面的值第一行是列标题,以下是数据,大概如下图所示↓

    代码

    新建一个类用来接受excel里面你想要的值,将你想要接受的字段设置Annotation属性,这里的名字一定要和excel里面的列标题一样,方法是匹配[类]中的某一列的Annotation和excel里面的列标题,所以双方都可以冗余。

    public class DEnterpriseForExcel {
    
        /**
         * 企业全称
         */
        @ExcelAnnotation(exportName = "FULLNAME")
        private String fullname;
        
        /**
         * 企业全称
         */
        private String test;
    }
    接收类
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface ExcelAnnotation {
        // excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入
        public String exportName();
    
    }
    添加字段名称

    如果有需要特殊处理的字段,类似日期之类的,可以通过注入方法来特殊处理那一列

    /**
     * 反射保存
     * 
     * @author wulin
     *
     */
    public class ReflectionUtils<T> {
        Class<T> clazz;
    
        private ReflectionUtilsCallback callback = null;
    
        public ReflectionUtils(Class<T> clazz) {
            this.clazz = clazz;
        }
    
        public void setCallback(ReflectionUtilsCallback callback) {
            this.callback = callback;
        }
    
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    
        public List<T> stringsToClass(List<String[]> lstData) throws Exception {
            List<T> rtn = new ArrayList<T>();
            int colNum = 0;
            try {
                /**
                 * 类反射得到调用方法
                 */
                // 得到目标目标类的所有的字段列表
                Field filed[] = clazz.getDeclaredFields();
                // 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
                Map<String, Method> fieldmap = new HashMap<String, Method>();
    
                // 循环读取所有字段
                // 自定义Class中的所有变量 都要用 注释
                for (int i = 0; i < filed.length; i++) {
                    Field f = filed[i];
                    // 得到单个字段上的Annotation
    
                    ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
                    // 如果标识了Annotationd的话
                    if (exa != null) {
                        // 构造设置了Annotation的字段的Setter方法
                        String fieldname = f.getName();
                        String setMethodName = "set" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1);
                        // 构造调用的method,
                        Method setMethod = clazz.getMethod(setMethodName, new Class[] { f.getType() });
                        // 将这个method以Annotaion的名字为key来存入。
                        fieldmap.put(exa.exportName(), setMethod);
                    }
                }
    
                // 将标题的文字内容放入到一个map中。
                Map<Integer, String> titlemap = new HashMap<Integer, String>();
                // 第一行是标题
                String[] dataTitle = lstData.get(0);
                for (int i = 0; i < dataTitle.length; i++) {
                    String value = dataTitle[i].replace(""", "").trim();
                    titlemap.put(i, value);
                }
    
                // 从第2行往下是数据区
                for (int nLp = 1; nLp < lstData.size(); nLp++) {
    
                    // 标题下的第一行
                    String[] row = lstData.get(nLp);
                    // 行的所有列
                    // 得到传入类的实例
                    T tObject = clazz.newInstance();
    
                    int k = 0;
                    int nFlushCnt = 0;
                    // 列遍历(遍历一行的所有列)
                    colNum = 0;
                    for (String rec : row) {
    
                        if (nFlushCnt >= 1000) {
                            System.gc();
                        }
                        colNum++;
    
                        // 取得-列标题
                        String titleString = (String) titlemap.get(k);
                        // 如果[列标题]和[类]中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
                        if (fieldmap.containsKey(titleString)) {
                            // 获得 set方法
                            Method setMethod = (Method) fieldmap.get(titleString);
    
                            if (null != callback) {
                                if (callback.isCallbackColumn(colNum)) {
                                    Object objVal = callback.getCellValue(colNum, rec);
                                    setMethod.invoke(tObject, objVal);
                                    k = k + 1;
                                    continue;
                                }
                            }
    
                            // 得到setter方法的参数
                            Type[] ts = setMethod.getGenericParameterTypes();
                            // 获得参数类型[java.lang.String]
                            String xclass = ts[0].toString();
    
                            if (xclass.equals("class java.lang.String")) {
                                setMethod.invoke(tObject, rec == null ? null : rec.replace(""", ""));
    
                            } else if (xclass.equals("class java.lang.Integer")) {
    
                                setMethod.invoke(tObject,
                                        (rec == null || " ".equals(rec)) ? null : Integer.parseInt(rec.replace(""", "")));
                            } else if (xclass.equals("class java.math.BigDecimal")) {
    
                                setMethod.invoke(tObject,
                                        (rec == null || " ".equals(rec)) ? null : new BigDecimal(rec.replace(""", "")));
                            } else if (xclass.equals("int")) {
    
                                int temp = Integer
                                        .parseInt((rec == null || " ".equals(rec)) ? null : rec.replace(""", ""));
                                setMethod.invoke(tObject, temp);
                            } else if (xclass.equals("class java.util.Date")) {
    
                                setMethod.invoke(tObject,
                                        (rec == null || 0 == rec.length()) ? null : sdf.parse(rec.replace(""", "")));
                            } else if (xclass.equals("class java.lang.Short")) {
                                setMethod.invoke(tObject,
                                        (rec == null || " ".equals(rec)) ? null : Short.parseShort(rec.replace(""", "")));
                            }
    
                        }
                        // 下一列
                        k = k + 1;
                    }
                    rtn.add(tObject);
    
                }
    
            } catch (Exception e) {
                //System.out.println("colNum::" + colNum);
                e.printStackTrace();
                // 将异常抛出去
                throw e;
            }
    
            return rtn;
        }
    }
    工具类
    public interface ReflectionUtilsCallback {
        public boolean isCallbackColumn(int column);
        public Object getCellValue(int column, String strVal);
    }
    特殊处理
  • 相关阅读:
    USB设备驱动之设备初始化(设备枚举)
    clCreateCommandQueue&#39;: was declared deprecated
    Struts2 Result Type
    IOS屏幕旋转
    VMware Workstation 集群仲裁磁盘和数据共享磁盘的创建
    UNIX环境高级编程之第3章:文件I/O
    poj 1068 Parencodings(模拟)
    使用oracle数据库和MySQL数据库时hibernate的映射文件.hbm.xml的不同
    线程池的实现
    zoj 1648 Circuit Board
  • 原文地址:https://www.cnblogs.com/chanmao--/p/5893353.html
Copyright © 2011-2022 走看看