Java泛型反射实践

最近项目中刚好有个机会尝试反射的使用,因为项目时间紧没花太多时间去做优化,毕竟优化后又得一轮大测试,写下来也是为了方便以后使用时能又个参考;

贴代码

   /**
     * @Author: xiaoyao  
     * @Description: 将model实体转成example
     * @DateTime: 2020/5/22 11:58
     * @Param: model 传入的实体对象
     * @Param: exampleClazz 要转换的example类模板
     * @Param: isPage 是否使用分页
     */
    private static <T, S extends AbstractExample> S modelToExample(T model, Class<S> exampleClazz, Boolean isPage){
        S example = null;
        try {
            example = exampleClazz.newInstance();
            example.setOrderByClause(" create_time desc ");
            Class<? extends Object> clazz = model.getClass();
            // 得到实体泛型所有属性
            Field[] field = clazz.getDeclaredFields();
            // 创建 Criteria
            Method mCriteria = exampleClazz.getDeclaredMethod("createCriteria");
            GeneratedCriteria criteria = (GeneratedCriteria)mCriteria.invoke(example);
            for(int i=0;i<field.length;i++){
                // 设置可以访问私有变量
                field[i].setAccessible(true);
                // 获取属性的名字
                String name = field[i].getName();
                // 实体类中的序列化属性没有Get方法
                if(name.equals("serialVersionUID"))
                    continue;
                // 将属性名字的首字母大写
                name = name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
                // 组装Get方法
                Method m = clazz.getDeclaredMethod("get" + name);
                // 调用Get方法
                Object o = m.invoke(model);
                // 判断属性值是否为空
                if(o == null){
                    continue;
                }
                if(!isPage && ("PageSize".equals(name))){
                    continue;
                }
                if(!isPage && ("PageStart".equals(name))){
                    continue;
                }

                if ("PageSize".equals(name)) {
                    example.setPageSize(Integer.parseInt(o.toString()));
                    continue;
                }
                if ("PageStart".equals(name)) {
                    example.setPageStart(Integer.parseInt(o.toString()));
                    continue;
                }

                Method mEqualTo = null;
                if ("Id".equals(name)){
                    criteria.andIdEqualTo(Long.parseLong(o.toString()));
                } else
                    // 判断自定义注解,这里是判断实体类里的自定义注解,从而判断使用何种Where条件
                if (field[i].isAnnotationPresent(Like.class)) {
                    mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "Like", Class.forName(o.getClass().getTypeName()));
                    o = "%" + o + "%";
                } else if (field[i].isAnnotationPresent(Less.class)) {
                    mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "LessThan", Class.forName(o.getClass().getTypeName()));
                } else if (field[i].isAnnotationPresent(Greater.class)) {
                    mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "GreaterThan", Class.forName(o.getClass().getTypeName()));
                } else if (field[i].isAnnotationPresent(LessOrEqual.class)) {
                    mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "LessThanOrEqualTo", Class.forName(o.getClass().getTypeName()));
                } else if (field[i].isAnnotationPresent(GreaterOrEqual.class)) {
                    mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "GreaterThanOrEqualTo", Class.forName(o.getClass().getTypeName()));
                } else {
                    mEqualTo = criteria.getClass().getDeclaredMethod("and" + name + "EqualTo", Class.forName(o.getClass().getTypeName()));
                }
                // 调用构建的criteria方法,将实体类的值设置到criteria里
                mEqualTo.invoke(criteria, o);
            }
        } catch (Exception e) {
            return example;
        }
        return example;
    }

    /**
     * @Author: xiaoyao
     * @Description: 将model实体转成example
     * @DateTime: 2020/5/22 11:58
     * @Param: model 传入的实体对象
     * @Param: exampleClazz 要转换的example类模板
     */
    public static <T, S extends AbstractExample> S modelToExample(T model, Class<S> exampleClazz){
        return modelToExample(model, exampleClazz, false);
    }

    /**
     * @Author: xiaoyao
     * @Description: 将model实体转成example,带分页
     * @DateTime: 2020/5/22 11:58
     * @Param: model 传入的实体对象
     * @Param: exampleClazz 要转换的example类模板
     */
    public static <T, S extends AbstractExample> S modelToExamplePage(T model, Class<S> exampleClazz){
        return modelToExample(model, exampleClazz, true);
    }

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

那一年,我也变成了光!!