欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java 类动态添加属性字段的操作

程序员文章站 2022-10-18 14:35:17
说明:做项目中遇到一种场景,需要根据查询时间段, 获取时间段中中每个月份对应的金额(费用统计)。如截图中的两列因为列是动态的, 首先想到的就是后天拼接json格式字符串, 然后返回到前台, 组装表头及...

说明:

做项目中遇到一种场景,需要根据查询时间段, 获取时间段中中每个月份对应的金额(费用统计)。

如截图中的两列

Java 类动态添加属性字段的操作

因为列是动态的, 首先想到的就是后天拼接json格式字符串, 然后返回到前台, 组装表头及内容。

但是当前系统中easyui版本为1.2,并不支持 data属性(官方从1.3.2开始支持)。所以只能返回list<t> 格式。

网上一搜相关代码很多, 看客可以自己搜索一下。 我这里记录一下我当时使用场景及用法,已备以后使用。

1.需要引用cglib jar包, 我用的版本是2.2

2.建一个实体对象 dynamicbean.java 。主要用来处理对象。

public class dynamicbean {
 private object object = null; // 动态生成的类 
 private beanmap beanmap = null; // 存放属性名称以及属性的类型 
 public dynamicbean() {
  super();
 }
 
 public dynamicbean(map propertymap) {
  this.object = generatebean(propertymap);
  this.beanmap = beanmap.create(this.object);
 }
 
 /**
  * @param propertymap
  * @return
  */
 private object generatebean(map propertymap) {
  beangenerator generator = new beangenerator();
  set keyset = propertymap.keyset();
  for (iterator<string> i = keyset.iterator(); i.hasnext();) {
   string key = (string) i.next();
   generator.addproperty(key, (class) propertymap.get(key));
  }
  return generator.create();
 }
 
 /**
  * ��bean���Ը�ֵ
  * @param property ������
  * @param value ֵ
  */
 public void setvalue(object property, object value) {
  beanmap.put(property, value);
 }
 
 /**
  * ͨ���������õ�����ֵ
  * @param property ������
  * @return ֵ
  */
 public object getvalue(string property) {
  return beanmap.get(property);
 }
 
 /**
  * 返回新生成的对象
  * @return
  */
 public object getobject() {
  return this.object;
 }
}

3. 原来对象, 及需要拼接到对象中的属性字段集合处理方法。

/**
*参数说明:
* object : 查询结果数组中对象。
* moneymap : 为对象对应所有月份数据集合
* 解释:已经查询出一组账单对象集合list<bill> , 而moneymap为对象中的一个属性 
* map<string,bigdecimal>, 存放了月份及金额
*/
private object dynamicclass(object object, map<string, bigdecimal> moneymap) throws exception {
  // 字段 - 值 集合
  hashmap<string, object> returnmap = new hashmap<string, object>();
  // 字段 - 字段类型 集合
  hashmap<string, object> typemap = new hashmap<string, object>();
  // 获取传入类
  class<? extends object> type = object.getclass();
  beaninfo beaninfo = introspector.getbeaninfo(type);
  propertydescriptor[] propertydescriptors = beaninfo.getpropertydescriptors();
  // 获取对象中已存在的数据
  for (int i = 0; i < propertydescriptors.length; i++) {
   propertydescriptor descriptor = propertydescriptors[i];
   string propertyname = descriptor.getname();
   if (!propertyname.equals("class") && !propertyname.equals("monthmap")) {
    method readmethod = descriptor.getreadmethod();
    object result = readmethod.invoke(object, new object[0]);
    if (result != null) {
     returnmap.put(propertyname, result);
    } else {
     string propertytype = descriptor.getpropertytype().tostring();
     if (propertytype.contains("java.math.bigdecimal")) {
      returnmap.put(propertyname, new bigdecimal(0));
     } else {
      returnmap.put(propertyname, "");
     }
    }
    typemap.put(propertyname, descriptor.getpropertytype());
   }
  }
  // 获取月份数据, 变为字段属性
  set<string> monthkeys = moneymap.keyset();
  for (iterator<string> it = monthkeys.iterator(); it.hasnext();) {
   string key = (string) it.next();
   // 字段类型
   typemap.put(key, class.forname("java.math.bigdecimal"));
   // 字段对应值
   returnmap.put(key, moneymap.get(key));
  }
  // map转换成实体对象
  dynamicbean bean = new dynamicbean(typemap);
  // 赋值
  set<string> keys = typemap.keyset();
  for (iterator<string> it = keys.iterator(); it.hasnext();) {
   string key = (string) it.next();
   bean.setvalue(key, returnmap.get(key));
  }
  object obj = bean.getobject();
  return obj;
 }

做笔记使用, 说不定以后还会用到。

补充:java动态的生成类的属性、并赋值

1、springboot项目中,在build.gradle中,配置jar包

compile("commons-beanutils:commons-beanutils:1.9.3")
compile("cglib:cglib-nodep:3.2.4")

2、创建dynamicbean

import java.util.map; 
import net.sf.cglib.beans.beangenerator;
import net.sf.cglib.beans.beanmap; 
public class dynamicbean {
 
 /**
  * 目标对象
  */
 private object target;
 /**
  * 属性集合
  */
 private beanmap beanmap;
 
 public dynamicbean(class superclass, map<string, class> propertymap){
  this.target = generatebean(superclass, propertymap);
  this.beanmap = beanmap.create(this.target);
 }
 
 /**
  * bean 添加属性和值
  *
  * @param property
  * @param value
  */
 public void setvalue(string property, object value) {
  beanmap.put(property, value);
 }
 
 /**
  * 获取属性值
  *
  * @param property
  * @return
  */
 public object getvalue(string property) {
  return beanmap.get(property);
 }
 
 /**
  * 获取对象
  *
  * @return
  */
 public object gettarget() {
  return this.target;
 }
 
 /**
  * 根据属性生成对象
  *
  * @param superclass
  * @param propertymap
  * @return
  */
 private object generatebean(class superclass, map<string, class> propertymap) {
  beangenerator generator = new beangenerator();
  if (null != superclass) {
   generator.setsuperclass(superclass);
  }
  beangenerator.addproperties(generator, propertymap);
  return generator.create();
 }
}

3、创建reflecutil转换的工具类

import java.beans.propertydescriptor;
import java.util.hashmap;
import java.util.map; 
import org.apache.logging.log4j.logmanager;
import org.apache.logging.log4j.logger; 
import org.apache.commons.beanutils.propertyutilsbean; 
import com.sunxung.factoring.entity.dynamicbean;
import com.sunxung.factoring.entity.attendancemanagement.attendancevo;
 
/**
 * @classname:reflectutil
 * @description:动态生成类的属性、并且赋值
 * @date:2018年4月3日 下午2:33:10
 */
public class reflectutil {
 
 static logger logger = logmanager.getlogger(reflectutil.class);
 
 @suppresswarnings("rawtypes")
 public static object gettarget(object dest, map<string, object> addproperties) {
  propertyutilsbean propertyutilsbean = new propertyutilsbean();
  propertydescriptor[] descriptors = propertyutilsbean.getpropertydescriptors(dest);
  map<string, class> propertymap = new hashmap<>();
  for (propertydescriptor d : descriptors) {
   if (!"class".equalsignorecase(d.getname())) {
    propertymap.put(d.getname(), d.getpropertytype());
   }
  }
  // add extra properties
  addproperties.foreach((k, v) -> propertymap.put(k, v.getclass()));
  // new dynamic bean
  dynamicbean dynamicbean = new dynamicbean(dest.getclass(), propertymap);
  // add old value
  propertymap.foreach((k, v) -> {
   try {
    // filter extra properties
    if (!addproperties.containskey(k)) {
     dynamicbean.setvalue(k, propertyutilsbean.getnestedproperty(dest, k));
    }
   } catch (exception e) {
    logger.error(e.getmessage(), e);
   }
  });
  // add extra value
  addproperties.foreach((k, v) -> {
   try {
    dynamicbean.setvalue(k, v);
   } catch (exception e) {
    logger.error(e.getmessage(), e);
   }
  });
  object target = dynamicbean.gettarget();
  return target;
 }
 
 public static void main(string[] args) {
  attendancevo entity = new attendancevo();
  map<string, object> addproperties = new hashmap<>();
  addproperties.put("day31", "你好");
  attendancevo newvo = (attendancevo) gettarget(entity, addproperties);
  system.out.println(newvo.getday0());
 }
}

4、在项目中动态生成属性并且赋值的使用

private attendancevo autodetailnew(searchattendancevo search, attendancevo att) {
  search.setdingdinguserid(att.getdingdinguserid());
  list<attendance> detaillist = attendancemapper.finddetaillist(search);
  map<string, object> addproperties = new hashmap<>();
  for (attendance attendance : detaillist) {
   addproperties.put("day" + dateutil.getdaystringformatymd(attendance.getattendancedate()),
     attendance.getremark());
  }
  attendancevo newvo = (attendancevo) reflectutil.gettarget(att, addproperties);
  return newvo;
 }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。