版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/qq_18885315/article/details/72639413
喜歡文章的小夥伴來波關注吧,謝謝了,您的支持是我繼續的動力!麼麼噠!---當我們用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