评论

收藏

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

编程语言 编程语言 发布于:2021-09-12 10:27 | 阅读数:577 | 评论:0

这篇文章主要介绍了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_")[1], 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[paramTypeList.size()];
  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 [name=" + name + ", age=" + age + ", address=" + address + "]";
  }
  
  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

关注下面的标签,发现更多相似文章