一、概述
本篇文章讲述构建对象成员名与数据库字段关系。可以通过XML或注解方式获取其映射关系。映射关系默认注解获取,如果想用XML,可以调用scannTableClassMapping,传入XML文件路径。Property为元数据类,用于存储表字段与对象成员名对应关系;TableClassDefination用于存储表与对象映射关系;TableClassFactory采取静态工厂模式,生成TableClassDefination。
二、代码示例
- 元数据-Property:
*
Property类为 字段与成员对应类
存储字段与成员对应关系
额外任务:提供成员名为后续获取反射方法。
*/
class Property {
private Field proeprty;
private String column;
Field getProeprty() {
return proeprty;
}
void setProeprty(Field proeprty) {
this.proeprty = proeprty;
}
String getColumn() {
return column;
}
void setColumn(String column) {
this.column = column;
}
//通过成员名反射获取方法
String getPropertyName() {
return proeprty.getName();
}
}
- 表对象映射关系-TableClassDefination:
class TableClassDefination {
//该成员不应为static 只指针对一张表。
private Map<String, Property> propertyPool;
//用于初始化Property
private Class<?> klass;
private String table;
private Field primaryKey;
TableClassDefination() {
propertyPool = new HashMap<String, Property>();
}
Class<?> getKlass() {
return klass;
}
Field getPrimaryKey() {
return primaryKey;
}
void setPrimaryKey(String primaryKey) {
try {
this.primaryKey = klass.getDeclaredField(primaryKey);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
void setKlass(String className) {
try {
setKlass(Class.forName(className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//假设colunm与成员名相同 初始化Proproty
void setKlass(Class<?> klass) {
this.klass = klass;
Field[] fields = klass.getDeclaredFields();
for (Field field: fields) {
Property property = new Property();
property.setColumn(field.getName());
property.setProeprty(field);
propertyPool.put(property.getPropertyName(),property);
}
}
String getTable() {
return table;
}
void setTable(String table) {
this.table = table;
}
//将所有字段集生成为sql字段列表
String getColumns() {
Set<String> keys = propertyPool.keySet();
StringBuffer columns = new StringBuffer();
for (String key : keys) {
if (columns.length() > 0) {
columns.append("," + propertyPool.get(key).getColumn());
continue;
}
columns.append(propertyPool.get(key).getColumn());
}
return columns.toString();
}
//提供表映射关系
List<Property> getProperties() {
List<Property> properties = new ArrayList<>();
Set<String> keys = propertyPool.keySet();
for (String key : keys) {
properties.add(propertyPool.get(key));
}
return properties;
}
Property getProerty(String proertyName) {
if (propertyPool.containsKey(proertyName)) {
return propertyPool.get(proertyName);
}
return null;
}
}
- 生成映射关系表-TableClassFactory:
/*
TableClassFactory 读取数据工具
TableClassDefination 存储元数据容器
*/
class TableClassFactory {
private static Map<String, TableClassDefination> tablePool;
static {
tablePool = new HashMap<>();
}
// 扫描XML配置文件
private static void scannTableClassMapping(String XMLPath) {
new XMLParse() {
@Override
public void dealElement(Element element, int index) {
String className = element.getAttribute("class");
String table = element.getAttribute("table");
String primaryKey = element.getAttribute("primaryKey");
TableClassDefination tcd = new TableClassDefination();
tcd.setKlass(className);
tcd.setPrimaryKey(primaryKey);
tcd.setTable(table);
new XMLParse() {
@Override
public void dealElement(Element element, int index) {
String proeprtyName = element.getAttribute("property");
String column = element.getAttribute("column");
Property property = tcd.getProerty(proeprtyName);
property.setColumn(column);
}
}.parseTagByElement(element, "Column");
tablePool.put(className, tcd);
}
}.parseTagByDocument(XMLParse.getDocument(XMLPath), "Mapping");
}
//扫描XML配置文件并获取表
static TableClassDefination getTableClassDefination(String XMLPath) {
scannTableClassMapping(XMLPath);
return tablePool.get(klass.getName());
}
//类注解扫描
private static void scannTableClassMapping(Class<?> klass) {
TableClassDefination tcd = new TableClassDefination();
Table table = klass.getAnnotation(Table.class);
tcd.setTable(table.table());
tcd.setKlass(klass);
tcd.setPrimaryKey(table.primaryKey());
Field[] fields = klass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Column.class)) {
Column colunm = field.getAnnotation(Column.class);
Property property = tcd.getProerty(field.getName());
property.setColumn(colunm.value());
}
}
tablePool.put(klass.getName(), tcd);
}
// 根据类名获取表
static TableClassDefination getTableClassDefination(String className) {
try {
return getTableClassDefination(Class.forName(className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
// 根据类型获取表
static TableClassDefination getTableClassDefination(Class<?> klass) {
if (!tablePool.containsKey(klass.getName())) {
//默认为注解扫描
scannTableClassMapping(klass);
}
return tablePool.get(klass.getName());
}
}
- 注解:
@Retention(RUNTIME)
@Target(TYPE)
public @interface Table {
String table();
String primaryKey();
}
@Retention(RUNTIME)
@Target(FIELD)
public @interface Column {
String value();
}
- XML
<?xml version="1.0" encoding="UTF-8"?>
<mappings>
<mapping table = "sys_student_info" class = "edu.xupt.study.model.StudentInfo">
<column property = "id" name = "id"/>
<column property = "mgr" name = "mgr"/>
<column property = "joindate" name = "joindate"/>
<column property = "salary" name = "salary"/>
</mapping>
</mappings>