利用反射和注解模拟ORM框架中的自动建表功能

在Mybatis当中,可能我们经常会用到在一个方法上加上注解,如:@Insert,@Update,@Delete,@Select,加上这些注解后,框架就能帮助我们执行sql语句,那框架是如何实现的呢?今天笔者就使用注解和反射的知识模拟了一个自动建数据表的功能,当然只是一些简单的代码,重要的是其中的原理。

加入我们现在有一个JavaBean,那么我们如何利用反射和注解实现,让数据库自动帮我们创建一张和该JavaBean对应的数据表呢?

首先我们得弄清楚JavaBean和数据表结构的对应关系:

利用反射和注解模拟ORM框架中的自动建表功能_第1张图片

类对应表,属性对应列,对象对应数据库中表的一条记录,那么创建一张表就需要表名,列名,则我们可以分别在类上加上注解,用来得到表名,在属性上加上注解,得到列名。

具体代码如下:

先定义两个注解:

类上的注解:

package com.tiantang.annotation;

import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 类的注解,对应于数据库中的表
 * @author LiuJinkun
 *
 */
@Target(TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTable {
	/**
	 * 对应数据库的表名
	 * @return
	 */
	String value();
}
属性上的注解:

package com.tiantang.annotation;

import static java.lang.annotation.ElementType.FIELD;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 属性的注解,对应于数据库中的列
 * @author LiuJinkun
 *
 */
@Target(FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
	/**
	 * 表的列名
	 * @return
	 */
	String columnName();
	
	/**
	 * 每一列的长度
	 * @return
	 */
	int length();
	
	/**
	 * 列的类型
	 * @return
	 */
	String type();
}


 
  

 
  注意,这里在自定义注解时,需要把注解的声明周期设置成RetentionPolicy.RUNTIME,因为反射是在程序运行时才能使用的,因此要想用反射获取到注解,则需要注解在程序运行时还存在着。 
  

定义的JavaBean类:

package com.tiantang.annotation;

@MyTable("students")
public class Student {

	@MyField(columnName = "student_id", length = 6, type = "int")
	private int id;

	@MyField(columnName="name",length=20,type="varchar")
	private String name;

	@MyField(columnName="address",length=30,type="varchar")
	private String address;
	
	@MyField(columnName="phone",length=20,type="varchar")
	private String phone;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

}

测试类:在测试类中,当程序运行时,利用反射获得类和属性的注解,然后拼接SQL语句:

package com.tiantang.annotation;

import java.lang.reflect.Field;

public class Client {
	
	public static void main(String[] args) throws Exception {
		//用于拼接sql语句
		StringBuffer sql=new StringBuffer();
		
		Class clazz=Class.forName("com.tiantang.annotation.Student");
		//获取类上的注解
		MyTable myTable=clazz.getAnnotation(MyTable.class);
		String tableName=myTable.value();
		sql.append("CREATE TABLE "+tableName+" ( ");
		//获取类的属性
		Field[] fields=clazz.getDeclaredFields();
		
		for(Field f:fields){
			//获取属性上的注解
			MyField myField=f.getAnnotation(MyField.class);
			//拼接sql语句
			sql.append(myField.columnName()+" "+myField.type()+"("+myField.length()+"),");
		}
		//因为该sql语句最后会多一个逗号,这里将其删除
		sql.deleteCharAt(sql.length()-1);
		sql.append(")");
		//打印sql语句
		System.out.println(sql.toString());
	}

}
这样SQL语句就拼接完成了,接下来执行sql语句就简单了,读者可以自行测试。这样我们就简单的实现利用反射和注解根据JavaBean的结构来自动建表的功能。当然,在框架里面自动建表大部分都是通过解析XML配置文件来实现的。



你可能感兴趣的:(Java,反射,注解)