【转载】java通过反射获取类名、属性名称以及@注解信息

前言: 场景为Spring data jpa,想通过反射获取表名以及id做点事情。那么如何通过反射进行呢。

这里转载了一篇比较好的文章。

 

getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。 
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段。

Spring data jpa依赖 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

反射工具类:JPA之@Entity、@Table、@Column、@Id

模仿mybatisplus的TableField接口,写的ColumnConf。可以用户前端页面表头或Excel导出表头等

package net.test.common.annotation;
 
import java.lang.annotation.*;
 
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface ColumnConf {
	String value() default "";
}
import net.test.common.annotation.ColumnConf 
public class UserListVO {
	/**
	 * 客户名称
	 */
	@ColumnConf("客户名称")
	private String clientName;
}
import net.test.common.annotation.ColumnConf;
 
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
public class ReflectUtils {
    public static final String TABLE_NAME = "tableName";
    public static final String CLASS_NAME = "className";
    public static final String FIELD_NAME = "fieldNames";
    public static final String COLUMN_NAME = "column";
 
 
    /**
     * * 获取属性名数组
     *
     * @param clazz
     * @return
     */
    public static String[] getPropertiesName(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        String[] fieldNameStrings = new String[fields.length];
        for (int i = 0; i < fieldNameStrings.length; i++) {
            fieldNameStrings[i] = fields[i].getName();
        }
 
        return fieldNameStrings;
    }
 
    /**
     * 通过反射设置属性的值
     *
     * @param fieldName      属性名
     * @param fieldValue     属性值
     * @param object         实体类对象
     * @param parameterTypes 设置属性值的类型  String.class
     * @throws
     */
    public static void setPropertyValue(String fieldName, Object fieldValue, Object object, Class<?>... parameterTypes) {
        try {
            Field[] fields = object.getClass().getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                //字段名称
                String name = field.getName();
                if (name.equals(fieldName)) {
                    field.setAccessible(true);
                    //field.set(object,fieldValue); //可代替下面的拼接set方法;
                    //将属性的首字符大写,方便构造get,set方法
                    String methname = name.substring(0, 1).toUpperCase() + name.substring(1);
                    Method m = object.getClass().getMethod("set" + methname, parameterTypes);
                    m.invoke(object, fieldValue);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 根据主键名称获取实体类主键属性值
     *
     * @param clazz     实体类对象
     * @param fieldName 属性名
     * @return
     */
    public static Object getPropertyValue(Object clazz, String fieldName) {
        try {
            /** 方法一
             Field field = clazz.getClass().getDeclaredField(fieldName);
             //设置对象的访问权限,保证对private的属性的访问
             field.setAccessible(true);
             Object value = field.get(clazz);
             */
 
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = clazz.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(clazz, new Object[]{});
 
            return value;
        } catch (Exception e) {
            return null;
        }
    }
 
    /**
     * 通过反射将 source不为空的值赋值给target
     *
     * @param source 实体类对象
     * @param target 实体类对象
     * @throws Exception
     */
    public static void copyProperties(Object source, Object target) throws Exception {
        Field[] field = source.getClass().getDeclaredFields();
        for (int i = 0; i < field.length; i++) {
            String name = field[i].getName();
            if ("serialVersionUID".equals(name)) {
                continue;
            }
            name = name.substring(0, 1).toUpperCase() + name.substring(1);
            Method m1 = source.getClass().getMethod("get" + name);
            Object value = m1.invoke(source);
            if (value != null) {
                Field f = field[i];
                //设置对象的访问权限,保证对private的属性的访问
                f.setAccessible(true);
                f.set(target, value);
            }
        }
    }
 
    /**
     * 获取实体类主键
     *
     * @param clazz
     * @return
     */
    public static Field getJpaIdField(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        Field item = null;
        for (Field field : fields) {
            Id id = field.getAnnotation(Id.class);
            if (id != null) {
                field.setAccessible(true);
                item = field;
                break;
            }
        }
        if (item == null) {
            Class<?> superclass = clazz.getSuperclass();
            if (superclass != null) {
                item = getJpaIdField(superclass);
            }
        }
 
        return item;
    }
 
    /**
     * 获取实体类 @Column 的其中一个属性名称
     *
     * @param clazz
     * @return
     */
    public static Map<String, String> getJpaColumns(Class<?> clazz) {
        Map<String, String> map = new ConcurrentHashMap<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Column.class)) {
                Column declaredAnnotation = field.getDeclaredAnnotation(Column.class);
                String column = declaredAnnotation.name();
                map.put(FIELD_NAME, field.getName());
                map.put(COLUMN_NAME, column);
            }
        }
 
        return map;
    }
 
    /**
     * 通过获取类上的@Table注解获取表名称
     *
     * @param clazz
     * @return
     */
    public static Map<String, String> getJpaTableName(Class<?> clazz) {
        Map<String, String> map = new ConcurrentHashMap<>();
        Table annotation = clazz.getAnnotation(Table.class);
        String name = annotation.name();
        String className = clazz.getSimpleName();
        map.put(TABLE_NAME, name);
        map.put(CLASS_NAME, className);
 
        return map;
    }
 
    /**
     * 获取VO @ColumnConf注解 属性与中文名称
     *
     * @param clazz
     * @return
     */
    public static Map<String, String> getVoColumns(Class<?> clazz) {
        Map<String, String> map = new ConcurrentHashMap<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            ColumnConf cc = field.getAnnotation(ColumnConf.class);
            if (cc == null) {
                continue;
            }
            map.put("code", field.getName());
            map.put("title", cc.value());
        }
 
        return map;
    }
 
    public static void main(String[] args) {
        Student s = new Student("张三", 23);
 
        System.out.println(s); //student [name=张三, age=23]
        setPropertyValue("name", "李四", s, String.class);
        System.out.println(s); //student [name=李四, age=23]
 
        Object val = getPropertyValue("name", s);
        System.out.println(val); //李四
 
        String[] strArray = getPropertiesName(Student.class);
        for (int i = 0; i < strArray.length; i++) {
            System.out.println(strArray[i]);
        }
    }
}


版权声明:本文为CSDN博主「航空母舰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hudeyong926/article/details/116236958

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值