1. 概念
Java提供了一種源程序中的元素關聯任何信息和任何元素數據的途徑和方法。
2. 常見註解
(1). JDK自帶註解
@Override複寫、@Deprecated過時、@SuppressWarnings忽略
(2). Spring
@Autowired、@Service、@Repository
(3). Mybatis
@InsertProvider、@UpdateProvider、@Options
3. 註解的分類
(1). 按照運行機制分爲源碼註解、編譯時註解、運行時註解。
(2). 按照來源分爲JDK註解、第三方註解、自定義註解。
(3). 元註解。
4. 自定義註解
(1). 語法要求
<pre name="code" class="java"><pre name="code" class="java">@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
String desc();
String author();
int age() default 18;
}
ElementType的類型還有CONSTRUCTOR(構造方法聲明)、FIELD(字段聲明)、LOCAL_VARIABLE(局部變量聲明)、METHOD(方法聲明)、PACKAGE(包聲明)、PARAMETER(參數聲明)、TYPE(類接口)。
RetentionPolicy類型有SOURCE(只在源碼顯示,編譯時會丟棄)、CLASS(編譯時會記錄到class中,運行時忽略)、RUNTIME(運行時存在,可以通過反射讀取)
Inherited是指允許子類繼承
Documented是指生成javadoc時會包含註解。
(2). 使用自定義註解
@<註解名>(<成員1>=<成員1值>, <成員名1>=<成員值1>,...)
例如:
@Description(desc = "Something desc", author = "Writer", age = 22)
public String say() {
return "hello";
}
(3). 幾個要求1). 使用@interface關鍵字定義註解
2). 成員以無參無異常方式聲明
3). 可以用default爲成員制定一個默認值
4). 成員類型是受限的,包括基本類型及String,Class,Annotation,Enumeration。
5). 如果註解只有一個成員,則成員名必須取名爲value(),在使用時可以忽略成員名和賦值號=。
6). 註解類可以沒有成員,沒有成員的註解稱爲標識註解。
(4). 解析註解
通過反射獲取類、函數或者成員上的運行時註解信息,從而實現動態控制程序運行的邏輯。
5. 實戰
首先創建兩個註解:
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
一個是用來註解表名的,一個是用來註解字段名的。然後寫這樣子的一個bean,使用我們上面寫的註解。
@Table("users")
public class Filter {
@Column("id")
private int id;
@Column("username")
private String username;
@Column("nickName")
private String nickName;
@Column("age")
private int age;
@Column("city")
private String city;
@Column("email")
private String email;
@Column("mobile")
private String mobile;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
最後來使用它:
public static void main(String[] args) {
Filter f1 = new Filter();
f1.setId(10);
Filter f2 = new Filter();
f2.setUsername("Jerry");
f2.setAge(24);
Filter f3 = new Filter();
f3.setEmail("[email protected], [email protected]");
Filter2 f4 = new Filter2();
f4.setAmount(40);
String sql1 = query(f1);
String sql2 = query(f2);
String sql3 = query(f3);
String sql4 = query(f4);
System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);
System.out.println(sql4);
}
private static String query(Object f) {
StringBuilder sb = new StringBuilder();
Class c = f.getClass();
if (c.isAnnotationPresent(Table.class)) {
Table t = (Table) c.getAnnotation(Table.class);
// 得到表名
String talbeName = t.value();
sb.append("select * from ").append(talbeName).append(" where 1=1");
// 取得所有字段
Field[] fs = c.getDeclaredFields();
for (Field field : fs) {
// 如果註解存在
if (field.isAnnotationPresent(Column.class)) {
Column column = field.getAnnotation(Column.class);
// 取得字段的名字
String columnName = column.value();
// 取得字段的值
String fieldName = field.getName();
String getMethodName = "get"
+ fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
Object fieldValue = null;
try {
Method getMethod = c.getMethod(getMethodName);
fieldValue = getMethod.invoke(f);
} catch (Exception e) {
e.printStackTrace();
}
// 拼裝sql
if (fieldValue == null
|| ((fieldValue instanceof Integer && (Integer) fieldValue == 0))) {
continue;
}
sb.append(" and ").append(fieldName);
// 當是String類型的時候
if (fieldValue instanceof String) {
if (((String) fieldValue).contains(",")) {
String[] values = ((String) fieldValue).split(",");
sb.append(" in(");
for (String v : values) {
sb.append("'").append(v).append("'")
.append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
} else {
sb.append("=").append("'").append(fieldValue)
.append("'");
}
}
// 當是Integer類型的時候
else if (fieldValue instanceof Integer) {
sb.append("=").append(fieldValue);
}
}
}
}
return sb.toString();
}
這樣,就完成了一個生成SQL語句的一個功能。