註解與反射關聯的應用(三)

諸惡莫作,衆善奉行,自淨其意,是諸佛教
勸諸君,多行善事積福報,莫作惡

上一章簡單介紹了自定義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();
        }

    }

運行控制檯,打印輸出

有圖片

獲取到用戶傳入的內容之後,就可以進行更加複雜的操作了。 老蝴蝶這兒就不更深一步演示了。


謝謝您的觀看,如果喜歡,請關注我,再次感謝 !!!

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