在代码中注解可以给我们带来很多方便,而且在很多框架中都有注解的身影,那注解是怎么创建和使用的呢。这里大概分以下几个步骤:
1.创建自定义的注解
2.编写注解解析,(及定义这个注解的目的)
3.按照文明定义的注解来使用注解
我们做一个使用注解通过传入一个对象来生成简单查询sql语句的例子。(注解的分类和定义时的相关说明看这里)
这里我们将会定义Table、Column两个注解分别表示表名和字段。编写注解的解析器(需要使用反射),最后创建Students类,在这个类上使用Table、Column注解。
我们先定义Table、Column的注解:
Table:
import java.lang.annotation.ElementType;Column:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})//标注只能放在类或接口的注解
@Retention(RetentionPolicy.RUNTIME)//在运行时有效
public @interface Table {
String value();
}
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 Column {
String value();
}
为了后面看得不那么乱我先创建Students类,并使用注解:
Students:
<span style="font-size:18px;">@Table("students")我们可以增加一个School类:
public class Students {
@Column("id")
private int id;
@Column("name")
private String name;
@Column("age")
private int age;
@Column("addr")
private String addr;
@Column("city")
private String city;
set...get...
}</span>
@Table("SCHOOL")
public class School {
@Column("id")
private int id;
@Column("schoolName")
private String schoolName;
@Column("schoolAddr")
private String schoolAddr;
@Column("schoolNum")
private int schoolNum;
set...get...
}
我们在AnnotationTest类中定义一个query方法来解析注解:接收一个对象,返回这个对象生成的查询sql语句:
/**现在我们来测试我们想要的效果是否能实现,还是在AnnotationTest中,增加main方法:
* 简单查询sql语句 (只能是简单的条件语句)
* @param obj 要查询的类的条件
* @return 返回生成的sql语句
*/
private static String query(Object obj) {
StringBuffer sb = new StringBuffer();
Class stu = obj.getClass();
//查看这个类是否有Table的注解
boolean istableAnnot = stu.isAnnotationPresent(Table.class);
if(!istableAnnot){
//有Table的注解,那我们开始拿到这个类对于的表名
return null;
}
//得到这个注解中的value
Table table = (Table) stu.getAnnotation(Table.class);
sb.append("select * from ").append(table.value()).append(" where 1=1 ");
//直接遍历这个类的field
Field[] fields = stu.getDeclaredFields();
for (Field field : fields) {
<span style="white-space:pre"> </span>//得到有Column的注释的Field
boolean isExistsColumn = field.isAnnotationPresent(Column.class);
if(isExistsColumn){
Column column = field.getAnnotation(Column.class);
//有了Column注解之后我们应该使用反射方法取得getMethod来取得对于field中的值
String fieldName = field.getName();
String FieldGetMethod = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
try {
Method method = stu.getMethod(FieldGetMethod);
Object getFieldValue = method.invoke(obj);
//如果取得的对象为空,则说明这个field无值或值为0时,不拼接
if(getFieldValue==null||(getFieldValue instanceof Integer&&(Integer)getFieldValue==0)){
continue;
}
if(getFieldValue instanceof Integer){
sb.append(" and "+column.value()+"="+getFieldValue.toString());
}else{
sb.append(" and "+column.value()+"='"+getFieldValue.toString()+"'");
}
<span style="white-space:pre"> </span>} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return sb.toString();
public static void main(String[] args) {School school = new School();school.setId(9878932);school.setSchoolAddr("清华路实验高中");school.setSchoolName("实验高级中学");school.setSchoolNum(9527);//调用注解解析方法String sql3 = query(school);System.out.println(sql3);} 结果:
Students students = new Students();
students.setName("赵四");
students.setAddr("XXX-ccc");
students.setAge(23);
students.setId(0001);
<span style="font-family: Arial, Helvetica, sans-serif;">//调用注解解析方法</span>
<span style="white-space:pre"> </span>students.setCity("MyCity");
String sql = query(students);
System.out.println(sql);
Students students2 = new Students();
students2.setName("张三");
students2.setAge(23);
String sql2 = query(students2);
System.out.println(sql2);
<pre name="code" class="java"> //调用注解解析方法
这样我们就实现了通过注解来生成简单的sql语句了。