package com.bocean.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map; import com.bocean.annotation.Validate;
import com.bocean.entity.healthManage.HealthIndex;
import com.bocean.entity.healthManage.HealthManage;
import com.google.common.collect.Maps; /**
 * 利用反射通过bean之间的对比对属性进行修改/更新等
 *
 * @author only29
 */
public class BeanRefUtil {     /**
     * 复制source -> target (并过滤值为0/0.0/""等置null,以免影响推送)
     * 属性的复制建议采用:Dozer
     * @param source
     * @param destinationClass
     * @param ignoreZero 是否过滤属性值为null/0/""
     * @param <T>
     * @return
     */
    public static <T> T copyBean(Object source, Class<T> destinationClass, Boolean ignoreZero) {
        Map<String, String> valMap = bean2Map(source);
        T t = null;
        try {
            t = copyFieldValue(destinationClass, valMap, ignoreZero);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }     /**
     * 从source(old 实体)对应属性更新到target(从数据库获取的实体)
     * 并判断新老对象属性值是否全是一致(即是否需要更新到数据库)
     * @param source
     * @param target
     * true 需要更新,false 不需要更新
     */
    public static boolean updateBean(Object source, Object target) {
        Map<String, String> valMap = bean2Map(source);
        return updateFieldValue(target, valMap);
    }     /**
     * target 通过与 source 带有自定义的annotation的属性进行比较,只筛选更新的属性保存到数据库,其他为更新的设置NULL
     *
     * @param source
     * @param target
     */
    public static void compareAndUpdateProperty(Object source, Object target, Class annotation) {
        Map<String, String> valMap = bean2Map(source);
        setNoUpdateFieldToNull(target, valMap, annotation);
    }     /**
     * 将相应的bean转化为map(属性->value)
     *
     * @param source
     * @return
     */
    public static Map<String, String> bean2Map(Object source) {
        Class<?> cls = source.getClass();
        Map<String, String> valueMap = Maps.newHashMap();
        Field[] fields = cls.getDeclaredFields();         for (Field field : fields) {
            try {
                String result = getFieldValue(source, field);
                valueMap.put(field.getName(), result);
            } catch (Exception e) {
                continue;
            }
        }
        return valueMap;
    }     /**
     * 将实体source有更新的属性更新到对应的实体target
     *
     * @param target
     * @param valMap
     */
    private static void setNoUpdateFieldToNull(Object target,
                                               Map<String, String> valMap, Class annotation) {
        Class<?> cls = target.getClass();         Field[] fields = cls.getDeclaredFields();         for (Field field : fields) {
            try {
                if(isAppointAnnotation(target, field, annotation)){
                    String o = valMap.get(field.getName());
                    String n = getFieldValue(target, field);
                    if (validNullAndEmptyString(o) && o.equals(n))
                        setFieldValue(target, field, null);
                }
            } catch (Exception e) {
                continue;
            }
        }
    }     /**
     * 将实体source有更新的属性更新到对应的实体target
     * 并判断新老对象值是否是一致(即是否需要更新到数据库)
     * @param target
     * @param valMap
     */
    private static boolean updateFieldValue(Object target,
            Map<String, String> valMap) {
        boolean flag = false;         Class<?> cls = target.getClass();         Field[] fields = cls.getDeclaredFields();         for (Field field : fields) {
            try {
                String o = valMap.get(field.getName());
                String n = getFieldValue(target, field);
                if (validNullAndEmptyString(o) && !o.equals(n)){
                    setFieldValue(target, field, o);
                    flag = true;
                }
            } catch (Exception e) {
                continue;
            }
        }
        return flag;
    }     /**
     * set属性的值到Bean
     * @param cls
     * @param valMap
     * @param ignoreZero 是否过滤属性值为0
     * @param <T>
     * @return
     * @throws Exception
     */
    private static <T> T copyFieldValue(Class<T> cls, Map<String, String> valMap, Boolean ignoreZero) throws Exception{         Field[] fields = cls.getDeclaredFields();         T t = cls.newInstance();         for (Field field : fields) {
            try {
                String value = valMap.get(field.getName());
                if(ignoreZero && !judgeValue(value))
                  setFieldValue(t, field, value);
            } catch (Exception e) {
                continue;
            }
        }         return t;
    }     /**
     * 根据字段获取对应的值
     *
     * @param bean
     * @param field
     * @return
     * @throws Exception
     */
    public static String getFieldValue(Object bean, Field field)
            throws Exception {
        Class<?> cls = bean.getClass();
        String fieldType = field.getType().getSimpleName();// 属性类型
        Method[] methods = cls.getDeclaredMethods();
        String fieldGetName = getMethodName(field.getName());
        String result = null;
        // 判断是否有该属性的get方法,没有返回null
        if (checkGetMethod(methods, fieldGetName)) {
            Method fieldGetMet = cls.getMethod(fieldGetName, new Class[] {});
            Object fieldVal = fieldGetMet.invoke(bean, new Object[] {});
            if ("Date".equals(fieldType)) {
                result = DateUtil.formatDateTime((Date) fieldVal);
            } else {
                if (null != fieldVal) {
                    result = String.valueOf(fieldVal);
                }
            }
        }
        return result;
    }     /**
     * 根据属性设置值,仅支持基本类型
     *
     * @param bean
     * @param field
     * @param value
     * @throws Exception
     */
    public static void setFieldValue(Object bean, Field field, String value)
            throws Exception {
        Class<?> cls = bean.getClass();
        Method[] methods = cls.getDeclaredMethods();
        // 属性set方法名
        String fieldSetName = setMethodName(field.getName());
        if (checkSetMethod(methods, fieldSetName)) {
            Method fieldSetMet = cls.getMethod(fieldSetName, field.getType());// set方法
            if (validNullAndEmptyString(value)) {
                String fieldType = field.getType().getSimpleName();
                if ("String".equals(fieldType)) {
                    fieldSetMet.invoke(bean, value);
                } else if ("Date".equals(fieldType)) {
                    Date temp = DateUtil.parseDate(value);
                    fieldSetMet.invoke(bean, temp);
                } else if ("Short".equalsIgnoreCase(fieldType)) {
                    Short temp = Short.parseShort(value);
                    fieldSetMet.invoke(bean, temp);
                } else if ("Integer".equals(fieldType)
                        || "int".equals(fieldType)) {
                    Integer temp = Integer.parseInt(value);
                    fieldSetMet.invoke(bean, temp);
                } else if ("Float".equalsIgnoreCase(fieldType)) {
                    Float temp = Float.parseFloat(value);
                    fieldSetMet.invoke(bean, temp);
                } else if ("Long".equalsIgnoreCase(fieldType)) {
                    Long temp = Long.parseLong(value);
                    fieldSetMet.invoke(bean, temp);
                } else if ("Double".equalsIgnoreCase(fieldType)) {
                    Double temp = Double.parseDouble(value);
                    fieldSetMet.invoke(bean, temp);
                } else if ("Boolean".equalsIgnoreCase(fieldType)) {
                    Boolean temp = Boolean.parseBoolean(value);
                    fieldSetMet.invoke(bean, temp);
                } else {
                    System.out.println("not supper type" + fieldType);
                }
            } else {//value=null或者""
                fieldSetMet.invoke(bean, value);
            }
        } else {
            System.out.println("not this set method : " + fieldSetName);
        }
    }     /**
     * 判断实体属性值是否全部为null
     * @param bean
     * @return
     */
    public static void zero2Null(Object bean){
        Boolean flag = true;
        try {
            Class<?> srcClass = bean.getClass();
            Field[] fields = srcClass.getDeclaredFields();
            // 比较属性值
            for (Field field : fields) {             }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }     /**
     * 判断实体属性值是否全部为null
     * @param bean
     * @return
     */
    public static boolean isNullSelectProperties(Object bean, Class annotation){
        Boolean flag = true;
        try {
            Class<?> srcClass = bean.getClass();
            Field[] fields = srcClass.getDeclaredFields();
            // 比较属性值
            for (Field field : fields) {
                if(isAppointAnnotation(bean, field, annotation)){
                    // 原属性值
                    Object so = getFieldValue(bean, field);
                    boolean j = judgeValue(so == null?"":so.toString());
                    if(!j){
                        flag = false;
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }     /**
     * 判断某个字段的get方法是否有指定的annotation
     * @param bean
     * @param field
     * @param annotation
     * @return
     * @throws Exception
     */
    public static boolean isAppointAnnotation(Object bean, Field field, Class annotation) throws Exception{
        if(annotation == null) return false;
        Class<?> cls = bean.getClass();
        Method[] methods = cls.getDeclaredMethods();
        String fieldGetName = getMethodName(field.getName());
        // 判断是否有该属性的get方法,没有返回null
        if (checkGetMethod(methods, fieldGetName)) {
            Method fieldGetMet = cls.getMethod(fieldGetName, new Class[] {});
            Annotation clazz = fieldGetMet.getAnnotation(annotation);
            if(clazz != null)
                return true;
        }
        return false;
    }     /**
     * 判断是否存在某属性的 set方法
     *
     * @param methods
     * @param fieldSetMet
     * @return
     */
    public static boolean checkSetMethod(Method[] methods, String fieldSetMet) {
        for (Method met : methods)
            if (fieldSetMet.equals(met.getName()))
                return true;
        return false;
    }     /**
     * 判断是否存在某属性的 get方法
     *
     * @param methods
     * @param fieldGetMet
     * @return
     */
    public static boolean checkGetMethod(Method[] methods, String fieldGetMet) {
        for (Method met : methods)
            if (fieldGetMet.equals(met.getName()))
                return true;
        return false;
    }     /**
     * 拼接某属性的 get方法
     *
     * @param fieldName
     * @return
     */
    public static String getMethodName(String fieldName) {
        if (null == fieldName || "".equals(fieldName)) {
            return null;
        }
        return "get" + fieldName.substring(0, 1).toUpperCase()
                + fieldName.substring(1);
    }     /**
     * 拼接在某属性的 set方法
     *
     * @param fieldName
     * @return
     */
    public static String setMethodName(String fieldName) {
        if (null == fieldName || "".equals(fieldName)) {
            return null;
        }
        return "set" + fieldName.substring(0, 1).toUpperCase()
                + fieldName.substring(1);
    }     /**
     * 判断字段名是否包含id,将其过滤
     * @param fieldName
     * @return
     */
    public static boolean isContainId(String fieldName){
        return (fieldName.contains("id") || fieldName.contains("Id"));
    }     /**
     * 验证null/""
     * @param value
     * @return
     */
    private static boolean validNullAndEmptyString(String value) {
        return (null != value && !"".equals(value));
    }     /**
     * 判断数据类型
     * @param tarValue
     * @return
     */
    private static Boolean judgeValue(String tarValue){
        return ("".equals(tarValue) || "0".equals(tarValue) || "0.0".equals(tarValue));
    }     public static void main(String args[]) {
        HealthManage hm = new HealthManage();
        hm.setPatientId(4942);
        hm.setCalories(25.6f);
        hm.setBloodSugar("220");
        hm.setSpeed(120f);         HealthIndex hi = new HealthIndex();
        hi.setBloodSugar("230");
        hi.setBMI(2.6f);
        hi.setSpeed(120f);         BeanRefUtil.compareAndUpdateProperty(hm,hi, Validate.class);         System.out.println(hi.getSpeed());
    } }

Java反射之Bean修改更新属性值等工具类的更多相关文章

  1. JDK动态代理+反射实现动态修改注解属性值

    这是最近朋友的一个需求,正好闲来无聊有些时间,跟着研究一下,如有不正确的地方,欢迎大家指正~ 一.准备自定义注解 注:如何实现自定义注解,请移步百度. 二.实现 1.实现方式1:通过反射+动态代理动态 ...

  2. Java反射获取对象VO的属性值(通过Getter方法)

    有时候,需要动态获取对象的属性值. 比如,给你一个List,要你遍历这个List的对象的属性,而这个List里的对象并不固定.比如,这次User,下次可能是Company. e.g. 这次我需要做一个 ...

  3. spring 提供的属性值拷贝工具类

    当需要把一个原生的类中属性拷贝到扩展类中时,使用以下类很方便:

  4. 使用java中的反射获得object对象的属性值

    知识点:使用java中的反射获得object对象的属性值 一:场景 这两天开发代码时,调用别人的后台接口,返回值为Object对象(json形式的),我想获得object中指定的属性值,没有对应的ge ...

  5. django 动态更新属性值

    django 动态更新属性值 class TestTime(models.Model): """ 功能说明:指定测试的每一关总用时 """ ...

  6. VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题

    VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题:https://blog.csdn.net/jerrica/article/d ...

  7. spring练习,使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打印输出。

    相关 知识 >>> 相关 练习 >>> 实现要求: 使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打印输出.要求如下: ...

  8. Java中创建操作文件和文件夹的工具类

    Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...

  9. JavaScript 数据值校验工具类

    /** * 数据值校验工具类 */ var checkService = { // 不校验 none: function () { return true; }, //非空校验 isEmpty: fu ...

随机推荐

  1. 团队作业第五次—项目冲刺-Day5

    Day5 part1-SCRUM: 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 hunter--冲刺集合 团队名称 hunte ...

  2. SpringCloud项目中使用Nacos作为配置中心

    参考:https://blog.csdn.net/qq_33619378/article/details/96991237 Nacos-server启动 这里就不说了 新建配置 在Nacos-Serv ...

  3. sql 自动增加排序 并且初始值是000001

    declare @co_num  int,                @CoNum varchar(6) select co_num=count(*)+1 from tab             ...

  4. HTTP之缓存处理步骤

    缓存的处理步骤 =================摘自<HTTP权威指南>===================== 现代的商业化代理缓存相当的复杂.这些缓存构建的非常有效,可以支持HTT ...

  5. MySQL中的 redo 日志文件

    MySQL中的 redo 日志文件 MySQL中有三种日志文件,redo log.bin log.undo log.redo log 是 存储引擎层(innodb)生成的日志,主要为了保证数据的可靠性 ...

  6. 关于预装操作系统的ThinkPad的分区建议

    Think的个人电脑产品大部分预装有正版操作系统,当前新产品出厂时默认都是一个大分区“C”和一个恢复分区“Q”,很多用户都会要求客服人员提供分区服务,在这里我简单说一下关于分区的几点注意事项望各位参考 ...

  7. 《 .NET并发编程实战》阅读指南 - 第12章

    先发表生成URL以印在书里面.等书籍正式出版销售后会公开内容.

  8. 《 .NET并发编程实战》实战习题集 - 2 - 替换算法

    先发表生成URL以印在书里面.等书籍正式出版销售后会公开内容.

  9. 单片机成长之路(51基础篇) - 026 基于stm89c52之单片机看门狗

    基于stc89c52的看门狗,代码如下: main.c #include "stc89c5x_Quick_configuration.h" // 自定义头文件 #include & ...

  10. 安装oracle时出现的问题

    数据库引擎和几个功能安装失败后  ,重新再装还是一样,好不容易全部功能装完成后结果发现登录不了oracle!!!!!!!!!!!!! 气死人,搞了一上午才发现原来是微软账号在搞事,登录本地管理员账户就 ...