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() + "\",");
			} 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

          谢谢!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值