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

来源:互联网 发布:避孕套 知乎 编辑:程序博客网 时间:2024/05/17 23:44

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

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

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


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

具体代码如下:

先定义两个注解:

类上的注解:

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配置文件来实现的。



1 0
原创粉丝点击