可以看到Afinal框架中数据库模块支持注解(Annotation)来方便的自定义主语表名(使用@Table)、主键(使用@id)。但是这到底是怎么实现的呢?前面本人有翻译过一篇介绍Java中Annotation的文章,不了解Annotation的朋友可以先看一下:http://blog.csdn.net/u011638883/article/details/13168799。
好了,首先需要知道的是Annotation常常是和反射相关联的,查看Java的API文档,在lang包的Class类中可以看到方法:
同样地,在反射包reflect中的Method和Field类中也都有定义了getAnnotation(Class<A> annotationClass)方法。
那么我们到底要怎么使用注释呢?现在以Afinal中实体类的数据表名自定义为例,加以说明。
一、定义一个注释类型,就叫MyTableAnnotation吧。
package com.wly.annotationtest;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解类型,用于注释实体类对应表名
* @author wly
*
*/
@Target(ElementType.TYPE) //定义本注释能被用来注释什么类型的java元素
@Retention(RetentionPolicy.RUNTIME) //定义本注释,在Runtime可见
public @interface MyTableAnnotation {
//注释中元素的定义和接口中的方法定义看上去很像
public String name();
}
二、定义一个实体Bean对象,就叫User
package com.wly.annotationtest;
/**
* 实体类
* @author wly
*
*/
@MyTableAnnotation(name="abc") //使用自定义注解
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
三、定义一个从实体Bean生成数据库语句的工具类SqlString
package com.wly.annotationtest;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 一个用于生成数据库语句的工具类
* @author wly
*
*/
public class SqlString {
public String getInsertSql(Object obj) throws Exception{
//String sql = "insert into table_name (field1,field2...) values(value1,value2...)";
Class clazz = obj.getClass();
StringBuilder _sb = new StringBuilder();
_sb.append("INSERT INTO TABLE ");
//得到表名,这里的表名是由Annotation注释的
MyTableAnnotation annotation = (MyTableAnnotation)clazz.getAnnotation(MyTableAnnotation.class);
if(annotation.name() == null || annotation.name().length() == 0) {
System.out.println("操作异常,表名未定义!");
return null;
} else {
_sb.append(annotation.name() + " ");
}
_sb.append("(");
//添加字段名,注意getFields()和getDeclaredFields()的区别,前者只能得到public成员变量,而后者则可以得到所有成员变量
Field[] fields = clazz.getDeclaredFields();
for(Field f:fields) {
_sb.append(f.getName() + ",");
}
//删除最后的","
_sb.deleteCharAt(_sb.length()-1);
_sb.append(") values(");
//根据成员变量类型生成不同的value值
for(Field f:fields) {
Method method = clazz.getMethod("get" + upperFirstCase(f.getName()), null);
Object value = method.invoke(obj, null);
if(f.getType() == String.class) {
_sb.append("\"" + value.toString() + "\",");
} else if(f.getType() == int.class) { //***注意这里是int.class,而不是Integer.class***
_sb.append(value.toString() + ",");
}
}
//删除最后的","
_sb.deleteCharAt(_sb.length()-1);
_sb.append(");");
return _sb.toString();
}
/**
* 将首字母转成大写字母,以构造get方法
* @param string
* @return
*/
private String upperFirstCase(String string) {
StringBuffer sb = new StringBuffer(string);
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
return sb.toString();
}
}
四、编写测试类Test,这里为了使代码简洁一些,仅编写了一个添加数据的测试
package com.wly.annotationtest;
/**
* 测试类
* @author wly
* @date 2013-10-27
*/
public class Test {
public static void main(String[] args) {
//这里简单的测试一下使用反射和注释,由对象生成数据库语句的过程
User user = new User("机器喵", 12);
SqlString sqlStr = new SqlString();
try {
System.out.println(sqlStr.getInsertSql(user));
} catch (Exception e) {
e.printStackTrace();
}
}
}
五、输出结果:
INSERT INTO TABLE abc (name,age) values("机器喵",12);
O啦~~~
转帖请保留出处:http://write.blog.csdn.net/postedit/13214485
工程地址:http://download.csdn.net/detail/u011638883/6462119
谢谢!!