喜欢文章的小伙伴来波关注吧,谢谢了,您的支持是我继续的动力!么么哒!---当我们用hibernate的自动建表功能时,感觉很方便,但是他是怎么完成的呢?让我们来探索一下。开始之前你需要了解反射和自定义注解的相关概念。
数据库字段与实体类字段相对应
你应该明白的是数据库字段与实体类之间的字段存在一一对应的关系,当我们应用反射解析实体类时,能够获取实体类名,各个字段名,以及重要的自定义注解。如以下一个实体类
package com.dingjianlei.entity;
import com.dingjianlei.annotation.MyField;
import com.dingjianlei.annotation.Mytable;
@Mytable(value="zl_indent")
public class Indent {
@MyField(name="ID",lenth=30,status="not null",primaryKey="YES",type="varchar")
private String id;
@MyField(name="NAME",lenth=30,status="not null",type="varchar")
private String name;
@MyField(name="ADDRESS",lenth=30,status="not null",type="varchar")
private String address;
@MyField(name="AGE",lenth=30,status="not null",type="int")
private int age;
@MyField(name="INDENT_NAME",lenth=30,status="not null",type="varchar")
private String indentName;
public String getId() {
return id;
}
public void setId(String 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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getIndentName() {
return indentName;
}
public void setIndentName(String indentName) {
this.indentName = indentName;
}
}

这个实体类有两个自定义注解@Mytable,@MyField。这两个注解的作用是帮我们建立实体类与数据库之间的对应关系,但是你可能会问,怎么起作用呢?当然是利用反射。
利用反射解析实体类有注解的字段
package com.dingjianlei.utils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import com.dingjianlei.annotation.MyField;
import com.dingjianlei.annotation.Mytable;
/**
模拟自动建表,根绝需求建表
* @author djl 2017 4 22
*
*/
public class OrmUtil {
public static boolean orm(Class<?> clazz) {
StringBuffer sql = new StringBuffer();
Mytable tableName = clazz.getAnnotation(Mytable.class);
if (tableName != null) {
String table = tableName.value();
sql.append("CREATE TABLE " + table + "(");
Field[] field = clazz.getDeclaredFields();
for (Field property : field) {
MyField entityProperty = property.getAnnotation(MyField.class);
String name = entityProperty.name();
String type = entityProperty.type();
String status = entityProperty.status();
int lenth = entityProperty.lenth();
String primaryKey = entityProperty.primaryKey();
if ("int".equals(type)) {
sql.append(name + " " + type + " " + status + " ");
if ("NO".equals(primaryKey)) {
sql.append(",");
} else {
sql.append("PRIMARY KEY, ");
}
} else {
sql.append(name + " " + type + "(" + lenth + ") " + status + " ");
if ("NO".equals(primaryKey)) {
sql.append(",");
} else {
sql.append("primary key, ");
}
}
}
} else {
}
try {
sql.deleteCharAt(sql.length() - 1);
sql.append(")");
System.out.println(sql.toString());
Properties properties = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");
String driver = properties.getProperty("jdbc.driver");
String url = properties.getProperty("jdbc.url");
String username = properties.getProperty("jdbc.username");
String password = properties.getProperty("jdbc.password");
Class.forName(driver);
Connection connection = DriverManager.getConnection(url, username, password);
Statement statement = connection.createStatement();
statement.execute(sql.toString());
} catch (IOException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}
}

主要思想就是:每一个类都有一个Class类,通过传入实体类对应的Class类,我们可以获取到实体类的各个字段值,字段值Filed有方法可以解析标注在字段的注解,获取注解的值,利用jdbcUtil执行Insert语句,建表。
github地址 https://github.com/gongtengxinyi