今晚讀了think in java 的章節,感覺很不錯,我就敲了下來,貼上代碼給以后一個回顧:
建議提前讀一下think in java 注解 。
說明創建注解我在第一個注解說明下,以后的注解不在說明。‘
DBTable 注解:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
/** * Project Name:myannotation * File Name:DBTable.java * Package Name:com.iflytek.db * Date:2016-8-28下午08:20:54 * Copyright (c) 2016, [email protected] All Rights Reserved. * */ package com.iflytek.db; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** @Target: @Target說明了Annotation所修飾的對象范圍:Annotation可被用于 packages、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數)。在Annotation類型的聲明中使用了target可更加明晰其修飾的目標。 作用:用于描述注解的使用范圍(即:被描述的注解可以用在什么地方) 取值(ElementType)有: 1.CONSTRUCTOR:用于描述構造器 2.FIELD:用于描述域 3.LOCAL_VARIABLE:用于描述局部變量 4.METHOD:用于描述方法 5.PACKAGE:用于描述包 6.PARAMETER:用于描述參數 7.TYPE:用于描述類、接口(包括注解類型) 或enum聲明 @Retention: @Retention定義了該Annotation被保留的時間長短:某些Annotation僅出現在源代碼中,而被編譯器丟棄;而另一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,而另一些在class被裝載時將被讀取(請注意并不影響class的執行,因為Annotation與class在使用上是被分離的)。使用這個meta-Annotation可以對 Annotation的“生命周期”限制。 作用:表示需要在什么級別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內有效) 取值(RetentionPoicy)有: 1.SOURCE:在源文件中有效(即源文件保留) 2.CLASS:在class文件中有效(即class保留) 3.RUNTIME:在運行時有效(即運行時保留) Retention meta-annotation類型有唯一的value作為成員,它的取值來自java.lang.annotation.RetentionPolicy的枚舉類型值 */ @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) public @interface DBTable { public String name() default "" ; } |
Constraints 約束注解:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/** * Project Name:myannotation * File Name:Constraints.java * Package Name:com.iflytek.db * Date:2016-8-28下午08:27:08 * Copyright (c) 2016, [email protected] All Rights Reserved. * */ package com.iflytek.db; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target (ElementType.FIELD) @Retention (RetentionPolicy.RUNTIME) public @interface Constraints { boolean primaryKey() default false ; boolean allowNull() default true ; boolean unique() default false ; } |
SQLInteger int注解:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/** * Project Name:myannotation * File Name:SQLInteger.java * Package Name:com.iflytek.db * Date:2016-8-29下午10:24:11 * Copyright (c) 2016, [email protected] All Rights Reserved. * */ package com.iflytek.db; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target (ElementType.FIELD) @Retention (RetentionPolicy.RUNTIME) public @interface SQLInteger { String name() default "" ; Constraints constraints() default @Constraints ; } |
SQLString 字符注解:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/** * Project Name:myannotation * File Name:SQLString.java * Package Name:com.iflytek.db * Date:2016-8-29下午10:28:04 * Copyright (c) 2016, [email protected] All Rights Reserved. * */ package com.iflytek.db; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target (ElementType.FIELD) @Retention (RetentionPolicy.RUNTIME) public @interface SQLString { int value() default 0 ; String name() default "" ; Constraints constraints() default @Constraints ; } |
創建表的處理器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/** * Project Name:myannotation * File Name:TableCreator.java * Package Name:com.iflytek.table * Date:2016-8-29下午10:57:52 * Copyright (c) 2016, [email protected] All Rights Reserved. * */ package com.iflytek.table; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import com.iflytek.db.Constraints; import com.iflytek.db.DBTable; import com.iflytek.db.SQLInteger; import com.iflytek.db.SQLString; public class TableCreator { public static void main(String[] args) { createTable(Member. class ); } //創建表SQL語句 private static void createTable(Class<?> cl) { //獲取DBTable注解 DBTable dbTable = cl.getAnnotation(DBTable. class ); //判斷DBTable注解是否存在 if (dbTable == null ) { System.out.println( "沒有找到關于DBTable" ); return ; } //如果@DBTable注解存在獲取表明 String tableName = dbTable.name(); //判斷表名是否存在 if (tableName.length() < 1 ) { //不存在,說明默認就是類名,通過 cl.getSimpleName()獲取類名并且大寫 tableName = cl.getSimpleName().toUpperCase(); } //定義獲取column的容器 List<String> columnDefs = new ArrayList<String>(); //循環屬性字段 //說明:getDeclaredFields()獲得某個類的所有申明的字段,即包括public、private和proteced,但是不包括父類的申明字段。 //getFields()獲得某個類的所有的公共(public)的字段,包括父類。 for (Field field : cl.getDeclaredFields()) { //定義表字段名稱變量 String columnName = null ; //獲取字段上的注解(現在字段允許多個注解,因此返回的是數組) Annotation[] anns = field.getDeclaredAnnotations(); //判斷屬性是否存在注解 if (anns.length < 1 ) continue ; //判斷是否是我們定義的數據類型 if (anns[ 0 ] instanceof SQLInteger) { //獲取SQLInteger 注解 SQLInteger sInt = (SQLInteger)anns[ 0 ]; //判斷是否注解的name是否有值 if (sInt.name().length() < 1 ) { //如果沒有值,說明是類的屬性字段,獲取屬性并轉換大寫 columnName = field.getName().toUpperCase(); } else { //如果有值,獲取設置的name值 columnName = sInt.name(); } //放到屬性的容器內 columnDefs.add(columnName + " INT " + getConstraints(sInt.constraints())); } //同上SQLInteger,這里不寫注釋了 if (anns[ 0 ] instanceof SQLString) { SQLString sString = (SQLString)anns[ 0 ]; if (sString.name().length() < 1 ) { columnName = field.getName().toUpperCase(); } else { columnName = sString.name(); } columnDefs.add(columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints())); } //定義生成創建表的SQL語句 StringBuilder createCommand = new StringBuilder( "CREATE TABLE " + tableName + "(" ); //循環上面屬性容器, for (String columnDef : columnDefs) { //把屬性添加到sql語句中 createCommand.append( "\n " + columnDef + "," ); //去掉最后一個逗號 String tableCreate = createCommand.substring( 0 , createCommand.length() - 1 ) + ");" ; //打印 System.out.println( "Table creation SQL for " + cl.getName() + " is :\n" + tableCreate); } } } private static String getConstraints(Constraints con) { String constraints = "" ; //判斷是否為null if (!con.allowNull()) { constraints += " NOT NULL " ; } //判斷是否是主鍵 if (con.primaryKey()) { constraints += " PRIMARY KEY " ; } //是否唯一 if (con.unique()) { constraints += " UNIQUE " ; } return constraints; } } |
以上代碼拷貝出來,就可以運行了!
上面雖然是簡單的創建表語句,但我們可以蔓延到hibernate的domain類里的注解,各種CURD ,何嘗不是這樣處理的呢,只是hibernate有很多東西,但是萬變不離其宗,以后有機會研究一下hibernate 。
收獲:
讀了以后,對于注解知道為什么要這么用了,其實顧名思義就是一個注解,只是有一個處理器來處理這個注解,這對我以后用到注解方面應該有幫助的,
時間不早了,就寫到這里!
結果:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。