注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁。
注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致。Java SE5内置了三种标准注解:
@Override,表示当前的方法定义将覆盖超类中的方法。
@Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。
@SuppressWarnings,关闭不当编译器警告信息。
上面这三个注解多少我们都会在写代码的时候遇到。Java还提供了4中注解,专门负责新注解的创建。
1.@Target(ElementType) 用于制定限定注解的使用范围
ElementType属性详解(jdk java.lang.annotation):
public enum ElementType{
TYPE,
//用于类,接口,枚举但不能是注解
FIELD,
//字段上,包括枚举值
METHOD,
//方法,不包括构造方法
PARAMETER,
//方法的参数
CONSTRUCTOR,
//构造方法
LOCAL_VARIABLE,
//本地变量或catch语句
ANNOTATION_TYPE,
//注解类型(无数据)PACKAGE//Java包
}
2.@Retention(RetentionPolicy) 用于制定编译器处理策略
RetentionPolicy属性详解(jdk java.lang.annotation):
publicenumRetentionPolicy{
SOURCE,
//此类型会被编译器丢弃
CLASS,
//此类型注解会保留在class文件中,但JVM会忽略它
RUNTIME
//此类型注解会保留在class文件中,JVM会读取它
}
3.@Documented 用于制定文档化功能
注意使用此注解时必须设置RetentionPolicy为RUNTIME
4.@Inherited 用于指定允许继承
下面介绍一个注解具体使用实例:动态生成sql语句。
首先定义注解,表名注解@Table和列注解@Column
@Target({ElementType.TYPE}) //类或接口可用
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value(); //可以有多个值,一个值就必须写value,否则会报错
}
@Target({ElementType.FIELD}) //类或接口可用
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value(); //一个值就必须写value
}
然后创建与数据库信息对应的Model类,在其中加入注解。
@Table("User")
public class User {
@Column("id")
private int id1;
@Column("userName")
private String userName1;
@Column("nickname")
private String nickname1;
@Column("age")
private int age1;
@Column("city")
private String city1;
public int getId1() {
return id1;
}
public void setId1(int id1) {
this.id1 = id1;
}
public String getUserName1() {
return userName1;
}
public void setUserName1(String userName1) {
this.userName1 = userName1;
}
public String getNickname1() {
return nickname1;
}
public void setNickname1(String nickname1) {
this.nickname1 = nickname1;
}
public int getAge1() {
return age1;
}
public void setAge1(int age1) {
this.age1 = age1;
}
public String getCity1() {
return city1;
}
public void setCity1(String city1) {
this.city1 = city1;
}
}
@Table("department")
public class Department {
@Column("id")
private int id1;
@Column("name")
private String name1;
@Column("leader")
private String leader1;
public int getId1() {
return id1;
}
public void setId1(int id1) {
this.id1 = id1;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getLeader1() {
return leader1;
}
public void setLeader1(String leader1) {
this.leader1 = leader1;
}
}
下面是用于动态生成Sql语句的方法,传入一个加入@Table和@Column注解的Model类对象。功能还不完善,读者有具体需求可自己增加更复杂的sql动态生成功能。
public static String query(Object f){
StringBuilder sb = new StringBuilder();
//1.获取到class
Class c = f.getClass();
//2获取到table的名字
boolean exists = c.isAnnotationPresent(Table.class);
if(!exists) return null;
Table t = (Table)c.getAnnotation(Table.class);
String tableName = t.value();
sb.append("select * from ").append(tableName).append(" where 1=1");
//3.遍历所有的字段
Field[] fArray = c.getDeclaredFields();
for(Field field:fArray){
//4.处理每个字段对应的sql
//4.1 拿到字段名
boolean fexists = field.isAnnotationPresent(Column.class);
if(!fexists) continue;
Column column = field.getAnnotation(Column.class);
String columnName = column.value();
//4.2 拿到字段的值 通过反射
String fieldName = field.getName();
String getMethidName = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
Object fieldValue = null;
try {
Method getMethod = c.getMethod(getMethidName);
fieldValue = getMethod.invoke(f);
} catch (Exception e) {
e.printStackTrace();
}
if(fieldValue == null || (fieldValue instanceof Integer && (Integer)fieldValue == 0)) continue;
//4.3 拼装sql
// System.out.println(fieldValue.toString());
if(fieldValue instanceof String) {
if(((String) fieldValue).contains(",")){
sb.append(" and ").append(columnName).append(" in (");
String[] args =fieldValue.toString().split(",");
for(String str:args){
sb.append("\'").append(str).append("\',");
}
sb.deleteCharAt(sb.length()-1); //删除最后一个逗号
sb.append(")");
}
else{
sb.append(" and ").append(columnName).append("=").append("\'").append(fieldValue.toString()).append("\'");
}
}
else if(fieldValue instanceof Integer){
sb.append(" and ").append(columnName).append("=").append(fieldValue.toString());
}
}
return sb.toString();
}
接着进行测试:
public static void main(String[] args) {
User f1 = new User();
f1.setId1(10);
User f2 = new User();
f2.setUserName1("lucy");
User f3 = new User();
f3.setCity1("shenzhen,guangzhou,zhuhai");
f3.setNickname1("wahaha");
f3.setUserName1("username");
System.out.println(query(f1));
System.out.println(query(f2));
System.out.println(query(f3));
Department d1 = new Department();
d1.setLeader1("大领导");
d1.setId1(0);
Department d2 = new Department();
d2.setId1(2);
System.out.println(query(d1));
System.out.println(query(d2));
}
打印结果:
select * from User where 1=1 and id=10
select * from User where 1=1 and userName='lucy'
select * from User where 1=1 and userName='username' and nickname='wahaha' and city in ('shenzhen','guangzhou','zhuhai')
select * from department where 1=1 and leader='大领导'
select * from department where 1=1 and id=2