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. Codeforces 126B Password(Z算法)

    题意 给定一个字符串 \(s\) ,求一个子串 \(t\) 满足 \(t\) 是 \(s\) 的前缀.后缀且在除前缀后缀之外的地方出现过. \(1 \leq |s| \leq 10^6\) 思路 \( ...

  2. Windows10 64位部署odoo12开发环境

    预装Windows10 64位家庭版电脑一台 2019年7月 安装Python,这里的版本选择上有个坑,不要装最新的Python 3.7.x,原因是odoo12依赖pillow 4.0.0库,而这个4 ...

  3. Qt 操作SQLite数据库

    项目中通常需要采用各种数据库(如 Qracle.SQL Server.MySQL等)来实现对数据的存储.查询等功能.下面讲解如何在 Qt 中操作 SQlite 数据库. 一.SQLite 介绍 Sql ...

  4. 读了两章的 How Tomcat Works

    周一发现了一本书.How Tomcat Works 惯例先到豆瓣搜书评.结果书评出奇的好.然后下载了PDF.从简介中看,本书的每个章节都会不断的围绕怎么建造一个Tomcat讲解.我本人比较喜欢这种造轮 ...

  5. 奥展项目笔记01--不同网站,点击工具--开发人员工具F12,显示的页面怎么不一样

    开发人员工具F12,显示的页面不一样: 样式1: 样式2: 解决方案:兼容模式和极速模式的开发者工具不一样,改成极速模式就ok了.

  6. 027 奥展项目涉及的javascipt知识点笔记

    1.获取指定div标签内的所有input标签 let inputs = document.getElementById("inspect-part1").getElementsBy ...

  7. javascript的对象与字符串相互转换

    因为对象不利于网络传输,因此要转换成字符串,转换成字符串之后又要考虑怎么将这个字符串转换回对象,以便取得对象中的属性. 常用的做法是将对象转换为JSON字符串,这里的转换方法也是用的JSON官方提供的 ...

  8. linux服务器的SSH 配置

    远程连接服务器: 就是通过文字或图形接口的方式来远程登陆另外一台服务器系统,让你在远程的终端前面登陆linux 主机以取得可操作主机的接口 主要的远程连接服务器的主要类型: 1)文字接口明文传输 : ...

  9. WPF 精修篇 路径动画

    原文:WPF 精修篇 路径动画 路径动画 是让一个对象围绕指定Path 的运动路径 进行移动的动画 举栗子 路径动画 使用 Blend 来设置 是十分简单的 首先用工具 笔  点出一条线 新建一个圆形 ...

  10. HTML模版大全网

    HTML模版大全网,里面有一部分是后台管理的网站模版,HTML全都有.大家有需要的话,可以自行去下载. http://www.htmlmbdq.com