小蚂蚁 发表于 2021-9-12 10:27:21

java通过cglib动态生成实体bean的操作

这篇文章主要介绍了java通过cglib动态生成实体bean的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
maven依赖:


<dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.9.3</version>
    </dependency>
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib-nodep</artifactId>
      <version>3.2.4</version>
    </dependency>
DynamicBeanEntity.class动态bean类:


package com.dym.entity;
import net.sf.cglib.beans.BeanGenerator;
import org.apache.commons.collections.map.MultiValueMap;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @author: zhaoxu
* @description:
*/
public class DynamicBeanEntity {
Object dynamicBean;
Class clazz;
public DynamicBeanEntity(Map dynAttrMap) {
    this.dynamicBean = generateBean(dynAttrMap);
    clazz = dynamicBean.getClass();
}
/**
   * 获取所有属性值
   *
   * @return
   * @throws IllegalAccessException
   */
public Map<String, Object> getValues() throws IllegalAccessException {
    Map<String, Object> fieldValuesMap = new HashMap(16);
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      field.setAccessible(true);
      Object fieldValue = field.get(dynamicBean);
      fieldValuesMap.put(field.getName().split("\\$cglib_prop_"), fieldValue);
    }
    return fieldValuesMap;
}
/**
   * 获取动态bean所有方法信息
   *
   * @return
   */
public MultiValueMap getMethods() {
    MultiValueMap map = new MultiValueMap();
    Method[] methods = clazz.getMethods();
    for (Method method : methods) {
      Type[] genericParameterTypes = method.getGenericParameterTypes();
      if (genericParameterTypes.length > 0) {
      for (Type type : genericParameterTypes) {
          map.put(method.getName(), type);
      }
      } else {
      map.put(method.getName(), null);
      }
    }
    return map;
}
/**
   * 执行某个方法
   *
   * @param methodName
   * @param parameters
   * @return
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   * @throws NoSuchMethodException
   */
public Object executeMethod(String methodName, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
    ArrayList<Class> paramTypeList = new ArrayList();
    for (Object paramType : parameters) {
      paramTypeList.add(paramType.getClass());
    }
    Class[] classArray = new Class;
    Method method = clazz.getMethod(methodName, paramTypeList.toArray(classArray));
    Object invoke = method.invoke(dynamicBean, parameters);
    return invoke;
}
/**
   * 设置属性值
   *
   * @param property
   * @param value
   * @throws NoSuchFieldException
   * @throws IllegalAccessException
   */
public void setValue(String property, Object value) throws NoSuchFieldException, IllegalAccessException {
    Field declaredField = clazz.getDeclaredField("$cglib_prop_" + property);
    declaredField.setAccessible(true);
    declaredField.set(dynamicBean, value);
}
/**
   * 获取属性值
   *
   * @param property
   * @return
   * @throws NoSuchFieldException
   * @throws IllegalAccessException
   */
public Object getValue(String property) throws NoSuchFieldException, IllegalAccessException {
    Field declaredField = clazz.getDeclaredField("$cglib_prop_" + property);
    declaredField.setAccessible(true);
    Object value = declaredField.get(dynamicBean);
    return value;
}
public Object getEntity() {
    return this.dynamicBean;
}
/**
   * 利用cglib的BeanGenerator创建对象
   *
   * @param dynAttrMap
   * @return
   */
private Object generateBean(Map dynAttrMap) {
    BeanGenerator generator = new BeanGenerator();
    Iterator iterator = dynAttrMap.keySet().iterator();
    while (iterator.hasNext()) {
      String key = iterator.next().toString();
      generator.addProperty(key, (Class) dynAttrMap.get(key));
    }
    return generator.create();
}
}
test.class测试类测试动态生成bean


package com.dym.attr;
import com.dym.entity.DynamicBeanEntity;
import org.apache.commons.collections.map.MultiValueMap;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* @author: zhaoxu
* @description:
*/
public class test {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    // 设置属性们,默认16
    HashMap propertyMap = new HashMap(16);
    propertyMap.put("name", String.class);
    propertyMap.put("age", Integer.class);
    propertyMap.put("height", Double.class);
    // 生成动态 Entity
    DynamicBeanEntity bean = new DynamicBeanEntity(propertyMap);
    //设置属性值
    bean.setValue("name", "zx");
    bean.setValue("age", 22);
    bean.setValue("height", 175.0);
    //获取属性值
    Map<String, Object> values = bean.getValues();
    //获取可执行的方法
    MultiValueMap methods = bean.getMethods();
    //执行某个方法
    bean.executeMethod("setAge", 23);
    System.out.println("动态bean的age属性:"+bean.getValue("age"));
}
}
test.class测试类测试链接数据库动态生成bean


package com.dym.test;
import com.dym.util.DBUtil;
import com.dym.util.DynmicEntity;
import org.springframework.stereotype.Component;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* @author: zhaoxu
* @description:
*/
@Component
public class test {
public static void main(String[] args) {
    ArrayList<DynmicEntity> beans = new ArrayList<>();
    Connection conn = null;
    PreparedStatement prst = null;
    String sql = "";
    sql = "select table_name from information_schema.tables where table_schema=\'public\'";
    conn = DBUtil.getConn();
    try {
      prst = conn.prepareStatement(sql);
      ResultSet rs = prst.executeQuery();
      while (rs.next()) {
      String tableName = rs.getString(1);
      Map attrMap = new HashMap<>();
      String findFieldSql = "SELECT format_type(a.atttypid,a.atttypmod) as type,a.attname as name, a.attnotnull as notnull\n" +
            "FROM pg_class as c,pg_attribute as a where c.relname = \'" + tableName + "\' and a.attrelid = c.oid and a.attnum>0";
      PreparedStatement fieldsPrst = conn.prepareStatement(findFieldSql);
      ResultSet fieldsRs = fieldsPrst.executeQuery();
      while (fieldsRs.next()) {
          String fieldType = fieldsRs.getString(1);
          String fieldName = fieldsRs.getString(2);
          attrMap.put(fieldName, Object.class);
      }
      DynmicEntity bean = new DynmicEntity(attrMap);
      beans.add(bean);
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
    DBUtil.close(prst, conn);
}
}
DBUtil.class:


package com.dym.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author: zhaoxu
* @description:
*/
public class DBUtil {
private final static String URL="jdbc:postgresql://localhost:5432/dynmic";
private final static String NAME="postgres";
private final static String PASS="123456";
private static Connection conn=null;
/**
   *
   *@Title:DBUtil
   *@Description:
   */
public DBUtil(){
}
/**
   *
   * @Tiltle getConn
   * @return Connection
   * @Description:返回连接
   */
public static Connection getConn(){
    //告诉jvm使用mysql
    try {
      //加载驱动,string为驱动名字
      Class.forName("org.postgresql.Driver");
      //连接数据库,得到Connection连接
      conn=DriverManager.getConnection(URL,NAME,PASS);
      //System.out.println("连接数据库: "+conn);
    }catch(ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }catch(SQLException e){
      e.printStackTrace();
    }
    return conn;
}
//关闭结果对象集
public static void close(ResultSet rs){
    if(rs!=null){
      try{
      rs.close();
      }catch(SQLException e){
      e.printStackTrace();
      }
    }
}
//关闭编译语句对象
public static void close(PreparedStatement prst){
    if(prst!=null){
      try{
      prst.close();
      }catch(SQLException e){
      e.printStackTrace();
      }
    }
}
//关闭结果对象集
public static void close(Connection conn){
    if(conn!=null){
      try{
      conn.close();
      }catch(SQLException e){
      e.printStackTrace();
      }
    }
}
//对于更新操作关闭资源
public static void close(PreparedStatement prst,Connection conn){
    close(prst);
    close(conn);
}
//关闭所有
public static void close(ResultSet rs,PreparedStatement prst,Connection conn){
    close(rs);
    close(prst);
    close(conn);
}
}
补充:java 反射 json动态转实体类
我就废话不多说了,大家还是直接看代码吧~


package test.refect;
public class Student {
    // 姓名
    private String name;
    // 年龄
    private String age;
    // 住址
    private String address;

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public String getAge() {
      return age;
    }

    public void setAge(String age) {
      this.age = age;
    }

    public String getAddress() {
      return address;
    }

    public void setAddress(String address) {
      this.address = address;
    }

    @Override
    public String toString() {
      return "Student ";
    }
   
    public void sayHello(Book book){
      System.out.println(book.getName());   
    }
}


package test.refect;
public class Book {
    private String name;
    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }   
}


package test.refect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.Iterator;
import net.sf.json.JSONObject;
public class Main {
    public static void main(String[] args) throws Exception {
      
      //Student str --> Student 主类
      String str = "test.refect.Student";
      Class<?> clazz = Class.forName(str);
      
      //Book实体 str --> Book 参数类
      String bookStr = "test.refect.Book";
      Class<?> bookClazz = Class.forName(bookStr);      
      
      //json --> Book    将参数类转为JSONOBJECT
      String bookJson ="{\"name\":\"Java\"}";
      JSONObject jsonObject=JSONObject.fromObject(bookJson);
      
      //实例化参数类
      Object bookInStance = bookClazz.newInstance();
      
      // 通过JSONOBJECT 为参数类赋值
      Iterator<?> keys = jsonObject.keys();
    while (keys.hasNext()) {
      Object key = keys.next();
      Object value = jsonObject.get(key);
      // 替换非法字符
      String _key = String.valueOf(key).replaceFirst("\\W", "");
      Field field = bookClazz.getDeclaredField(_key);
      field.setAccessible(true);
      field.set(bookInStance, URLDecoder.decode(String.valueOf(value), "UTF-8"));
      field.setAccessible(false);
    }
   
    //将参数类注入到主类
    Method method = clazz.getDeclaredMethod("sayHello", bookClazz);
   
    //执行主类
    method.invoke(clazz.newInstance(), bookInStance);      
    }
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持CodeAE代码之家。如有错误或未考虑完全的地方,望不吝赐教。
原文链接:https://blog.csdn.net/qq_39898191/article/details/112366508

http://www.zzvips.com/article/182392.html
页: [1]
查看完整版本: java通过cglib动态生成实体bean的操作