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("thrforever@126.com, thrforever@qq.com");
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语句的一个功能。