• 利用反射操作bean的属性和方法


    今天在开发中碰到这样一个场景:当请求添加项目下的目录时,传过来的是一个IndexModel,这个Model里有关于这个目录字段的详细信息,包括基础报表,实时,漏斗等信息(这些字段类型都是boolean),对应于页面上生成目录的多选框。现要将这些配置存入数据库,在数据库中存的是这个项目下的目录,比如说在页面勾选了基础报表这个选择框,就会在数据库中的menu表插入一条数据记录这个配置。这样一来,就需要对传递过来的这个IndexModel类的属性值进行判断,再决定插入数据库的信息。

        下面是IndexModel这个model的基本属性:

     1 public class IndexModel {
     2     private Boolean basic_report;  //基础报表
     3     private Boolean realtime;   //实时
     4     private Boolean event; //事件
     5     private Boolean retain;// 留存
     6     private Boolean funnel; //漏斗
     7     private Boolean explore; //探索
     8     private Boolean grouping; //分组
     9     private Boolean user_portrait; //用户画像
    10     private Boolean log; //日志
    11 
    12     //setters and getters ..
    13 }

    当某个属性为true时,则就会将这个属性配置进数据库,当这个属性为false时,则不会进行任何操作。

    由此,我想到了利用Java反射,遍历这个类的属性,然后获取到这个属性的名字和值判断,再映射成数据库表的字段,插入到数据库中去。

     我们先上解决方案代码:

     1  Field[] fields = IndexModel.class.getDeclaredFields();
     2             for (int i = 0; i < fields.length; i++) {
     3                     Field f = fields[i];
     4                     f.setAccessible(true); // 设置这些属性是可以访问的
     5                     try {
     6                        if(f.getGenericType().toString().endsWith("Boolean") && (Boolean) f.get(indexModel) == true) { // 得到此属性的值
     7                             IndexDto indexDto = parseIndexModelToDto(indexModel, f.getName());
     8                             projectService.addIndex(indexDto);
     9                         }
    10                     } catch (IllegalAccessException e) {
    11                         logger.error("属性类型转换异常");
    12                     }
    13                 }

    在代码中先是利用反射获取类的所有对象成员的字段值,在这里由于IndexModel中的属性字段值都是private的,所以,只能使用 getDeclaredFields()获取到这些字段,至于getFields()方法,只能获取到类(及其父类)中的公有成员,这两个方法返回的都是Field类型的数组。

    在获取私有成员值之前,必须调用setAccessible(true),否则的话,将会抛出异常:java.lang.IllegalAccessException:  class... can not access ,显示不能获取字段值。

    另外,在需要获取成员的类型时,需要调用相应的field的getType()方法,获取field的类型有如下几种方法

    1  Class<?> type = field.getType();        // 通过这种方式只对普通类型的Field有效,如果该Field的类型是有泛型限制的类型,如Map<String,Integer>类型,则不能准确得到该Field的泛型参数。
    2 
    3  Type type = field.getGenericType();  // 为了获得指定Field的泛型类型,应该使用这个方法来获取指定Field的泛型类型

    如果要获取上面对应field的被泛型限制的方法,就需要将上面的type对象强制类型转换成ParameterizedType对象,ParameterizedType代表被参数化的类型,也就是增加了泛型限制的类型,ParameterizedType类提供了两个方法:

        getRawType();                            返回被泛型限制的类型;

        getActualTypeArguments();        返回泛型参数类型。   

    然后,要获取成员变量的名称直接使用field.getName(),但是属性值则是field.get(Object),这个object是该field所属的!

    最后,要是想为这个成员变量设置值,则需要调用set:field[i].set(indexModel , true);

  • 相关阅读:
    pageControl点击白点时会变
    valueForKeyPath获取对象数组的属性
    探讨:通过循环数组或者集合,插入数据库中没有的数据
    Mybatis 中 Oracle 的拼接模糊查询
    Spring boot 中 Mybatis Plus 在 Oracle 新增数据时,主键自增问题
    在IntelliJ IDEA中,SpringBoot项目通过devtools实现热部署
    在 Mybatis 中遇到的那些坑
    华硕飞行堡垒耳机插进去之后再拔出来,电脑就没有声音了
    nyoj 776 删除元素
    nyoj 14 会场安排问题(贪心专题)java
  • 原文地址:https://www.cnblogs.com/jy107600/p/7150976.html
Copyright © 2020-2023  润新知