模拟数据库ORM之构建映射关系

本文探讨如何构建对象成员名与数据库字段的映射关系,使用XML或注解方式获取映射。介绍了Property元数据类、TableClassDefination表对象映射关系及静态工厂模式的TableClassFactory。提供了代码示例,展示如何根据对象成员名生成SQL字段。
摘要由CSDN通过智能技术生成

一、概述

本篇文章讲述构建对象成员名与数据库字段关系。可以通过XML或注解方式获取其映射关系。映射关系默认注解获取,如果想用XML,可以调用scannTableClassMapping,传入XML文件路径。Property为元数据类,用于存储表字段与对象成员名对应关系;TableClassDefination用于存储表与对象映射关系;TableClassFactory采取静态工厂模式,生成TableClassDefination。

二、代码示例

  1. 元数据-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();
    }
}
  1. 表对象映射关系-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;
    }
}
  1. 生成映射关系表-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());
    }
    
}

  1. 注解:
@Retention(RUNTIME)
@Target(TYPE)
public @interface Table {
    String table();
    String primaryKey();
}
@Retention(RUNTIME)
@Target(FIELD)
public @interface Column {
    String value();
}
  1. 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>

通过上述操作,可以获取Map映射集合。在构造sql语句时,可以根据对象成员名,转换为字段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值