注解与反射关联的应用(三)

诸恶莫作,众善奉行,自净其意,是诸佛教
劝诸君,多行善事积福报,莫作恶

上一章简单介绍了自定义Annotation(二),如果没有看过,请观看上一章

像上一章节我们写的 Table,Id,Column 注解,如果填入了相应的属性,能不能获取到相应的属性,然后进行用户传入的属性,

进行后续的操作?

即 用户使用了 Table 注解,填入了表名, 用户使用了 Id 注解,填入了主键, 用户使用了 Column 注入,填入了列名,

我们就可以获取到表名,主键名,普通列名, 就可以进行后续的操作了,如创建表结构,映射表与Bean的关系等。

其实,这些对应关系,以前是通过 xml 配置文件进行处理的,现在通过 注解就可以进行处理, 非常方便。

这也是 Spring 框架在高版本中使用注解,而不是 xml 配置的原因。

如何获取注解里面的内容呢? 通过反射。 关于反射的章节,读者可以看老蝴蝶写的 反射专栏的内容。这儿就不重复讲解了。

一. 注解与反射关联 应用 获取表,主键,列名信息

一.一 准备上一章节添加的 Table,Id,Column 注解

一.一.一 表 Table 注解

@Target(ElementType.TYPE) //只能放置在类上
@Retention(RetentionPolicy.RUNTIME) //jvm虚拟机可以载入
@Documented
public @interface Table {

    //添加一个属性值, 表名
    String tableName();

}

一.一.二 主键 Id 注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) //jvm虚拟机可以载入
@Documented
public @interface Id {

    //默认列名是 id
    String name() default "id";

    //默认长度是 11 int 类型
    int length() default 11;
}

一.一.三 普通列名 Column 注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) //jvm虚拟机可以载入
@Documented
public @interface Column {

    //列名
    String name();
    //长度
    int length() default 30;

}

一.二 Person 实体添加 注解


@Table(tableName="person")
public class Person implements Serializable {
    @Id(name="tid")
    private int id;
    @Column(name = "tname",length = 50)
    private  String name;
    @Column(name="tsex")
    private  char sex;
    @Column(name="tage")
    private int age;
    @Column(name="tdesc")
    private String desc;

	...
//其余代码
}

一.三 演示关联

 /**
     * 传入类完整名称
     * @param className
     * @throws Exception
     */
    public static void getInfo(String className) throws Exception{

        //1. 获取当前类

        Class clazz=Class.forName(className);

        //获取表的注解, 不进行 NPE 异常的判断了。 标志在类上面的注解
         Table tableAnn=(Table) clazz.getDeclaredAnnotation(Table.class);

        System.out.println("表名:"+tableAnn.tableName());


        //获取类中的属性
        Field[] fields=clazz.getDeclaredFields();

        for(Field field:fields){

            //如果属性名称 是id, 那么就获取主键
            if("id".equals(field.getName())){
                //获取标志在 id 属性上的注解
                Id id=(Id) field.getDeclaredAnnotation(Id.class);
                System.out.println("获取主键id:"+id.name()+",长度是:"+id.length());
            }else{

                //其余属性
                Column column=(Column)field.getDeclaredAnnotation(Column.class);

               System.out.println("属性名:"+field.getName()+"列名:"+column.name()+",长度:"+column.length());


            }


        }

        //得到了表名, 主键名,普通列名,列名的长度, 当然,还需要有类型,这儿没有, 如果有类型的话,就可以拼接成简单的 create sql语句 了。
        //然后调用  JDBC 执行该 sql 语句,就可以创建表了。
    }
    public static void main(String[] args) {

        try {
            //传入实体名
            getInfo("com.yjl.annotation.Person");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

运行程序,查看控制台输出

有图片

如果用户没有传入属性值,则获取到默认的属性值。

用户的主键可能不叫id, 一个属性上面可能有多个注解, 所以可能需要改进一下。

一.四 改进 演示关联

  public static void getInfo2(String className) throws Exception{

        //1. 获取当前类

        Class clazz=Class.forName(className);

        //获取表的注解, 不进行 NPE 异常的判断了。 标志在类上面的注解
        Table tableAnn=(Table) clazz.getDeclaredAnnotation(Table.class);

        System.out.println("表名:"+tableAnn.tableName());


        //获取其余属性

        Field[] fields=clazz.getDeclaredFields();

        for(Field field:fields){

                System.out.println("属性名:"+field.getName());
                //获取标志在该属性上的所有注解
                Annotation[] annotations=field.getDeclaredAnnotations();

                for(Annotation annotation:annotations){

                    //如果是 Column 注解
                    if(annotation instanceof Column){

                        Column column=(Column) annotation;

                        System.out.println("表列名:"+column.name()+",长度:"+column.length());
                    }else if(annotation instanceof  Id){

                        Id id=(Id)annotation;
                        System.out.println("获取主键id:"+id.name()+",长度是:"+id.length());


                }else{
                        //其余属性
                    }

            }
        }

        //得到了表名, 主键名,普通列名,列名的长度, 当然,还需要有类型,这儿没有, 如果有类型的话,就可以拼接成简单的 create sql语句 了。
        //然后调用  JDBC 执行该 sql 语句,就可以创建表了。



    }
    public static void main(String[] args) {

        try {
            //传入实体名
            getInfo2("com.yjl.annotation.Person");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

运行控制台,打印输出

有图片

获取到用户传入的内容之后,就可以进行更加复杂的操作了。 老蝴蝶这儿就不更深一步演示了。


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章