日期:2014-05-16  浏览次数:20404 次

Afinal数据库模块实现(一)_注释Annotation和反射生成SQL语句

          可以看到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() &#