[Java]简单模拟ORM关系模型底层实现原理

26 篇文章 0 订阅
12 篇文章 0 订阅

前言

对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的–“虚拟对象数据库”。

面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。

模拟实现原理

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String  value();
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String value();
}

Entity

@Table("student")
public class Student {

    @Id
    @Column("sid")
    private int id;

    @Column("sname")
    private String name;

    @Column("ssex")
    private String sax;
}

ORM关系映射

public class BeanOrmUtil {

    public static List getResultSet(ResultSet set, Object object) {
        List list = new ArrayList();
        try {
            while (set.next()) {
                Class c = object.getClass();
                Field[] fields = c.getDeclaredFields();
                Object entity = c.newInstance();
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    Column column = field.getAnnotation(Column.class);
                    String columnName = column.value();
                    String fieldName = field.getName();
                    Object value = set.getObject(columnName);
                    String getMethodName = "set" + fieldName.
                            substring(0, 1).toUpperCase() + fieldName.substring(1);
                    entity.getClass().getMethod(getMethodName, field.getType()).
                            invoke(entity, value);
                }
                if (entity != null) {
                    list.add(entity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }


    public static String update(Object entity) {
        boolean flag = true;
        int id = -1;
        String idFileName = null;
        StringBuffer sb = new StringBuffer();
        Class c = entity.getClass();
        boolean exists = c.isAnnotationPresent(Table.class);
        if (!exists) {
            return null;
        }
        Table t = (Table) c.getAnnotation(Table.class);
        String tableName = t.value();
        sb.append(" update student set  ");
        Field[] fArray = c.getDeclaredFields();
        for (Field field : fArray) {
            boolean fExists = field.isAnnotationPresent(Column.class);
            if (!fExists) {
                continue;
            }
            Column column = field.getAnnotation(Column.class);
            String columnName = column.value();
            String fieldName = field.getName();
            String getMethodName = "get" + fieldName.
                    substring(0, 1).toUpperCase() + fieldName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);
                fieldValue = getMethod.invoke(entity);
                if (field.isAnnotationPresent(Id.class) && (Integer) fieldValue != 0) {
                    id = (Integer) fieldValue;
                    idFileName = columnName;
                    continue;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (fieldValue == null || 
                    (fieldValue instanceof Integer && (Integer) fieldValue == 0)
                    || (fieldValue instanceof String 
                         && ((String) fieldValue).trim().equals(""))) {
                continue;
            }
            if (fieldValue instanceof String) {
                if (flag) {
                    flag = false;
                    sb.append(columnName + "=" + "'" + fieldValue + "' ");
                } else {
                    sb.append("," + columnName + "=" + "'" + fieldValue + "' ");
                }
            } else {
                if (flag) {
                    flag = false;
                    sb.append(columnName + "=" + "" + fieldValue + " ");
                } else {
                    sb.append("," + columnName + "=" + "" + fieldValue + " ");
                }
            }
        }
        if (flag || idFileName == null) {
            return null;
        }
        sb.append(" where " + idFileName + " = " + id);
        return sb.toString();
    }


    public static String insert(Object entity) {
        boolean flag = true;
        StringBuffer sb = new StringBuffer();
        Class c = entity.getClass();
        boolean exists = c.isAnnotationPresent(Table.class);
        if (!exists) {
            return null;
        }
        Table t = (Table) c.getAnnotation(Table.class);
        String tableName = t.value();
        sb.append(" insert into ").append(tableName).append(" values( ");
        Field[] fArray = c.getDeclaredFields();
        for (Field field : fArray) {
            boolean fExists = field.isAnnotationPresent(Column.class);
            if (!fExists) {
                continue;
            }
            Column column = field.getAnnotation(Column.class);
            String columnName = column.value();
            String fieldName = field.getName();
            String getMethodName = "get" + fieldName.
                    substring(0, 1).toUpperCase() + fieldName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);
                fieldValue = getMethod.invoke(entity);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (fieldValue == null) {
                fieldValue = "";
            } else if (fieldValue instanceof String) {
                if (((String) fieldValue).trim().equals("")) {
                    fieldValue = "";
                }
            }

            if (field.isAnnotationPresent(Id.class)) {
                fieldValue = null;
            }

            if (fieldValue instanceof String) {
                if (flag) {
                    flag = false;
                    sb.append("'" + fieldValue + "'");
                } else {
                    sb.append(",'" + fieldValue + "'");
                }
            } else {
                if (flag) {
                    flag = false;
                    sb.append("" + fieldValue + "");
                } else {
                    sb.append("," + fieldValue + "");
                }
            }
        }
        sb.append(")");
        return sb.toString();
    }


    public static String delete(Object entity) {
        StringBuffer sb = new StringBuffer();
        Class c = entity.getClass();
        boolean exists = c.isAnnotationPresent(Table.class);
        if (!exists) {
            return null;
        }
        Table t = (Table) c.getAnnotation(Table.class);
        String tableName = t.value();
        sb.append(" delete from ").append(tableName).append(" where 1=1 ");
        Field[] fArray = c.getDeclaredFields();
        for (Field field : fArray) {
            boolean fExists = field.isAnnotationPresent(Column.class);
            if (!fExists) {
                continue;
            }
            Column column = field.getAnnotation(Column.class);
            String columnName = column.value();
            String fieldName = field.getName();
            String getMethodName = "get" + fieldName.
                    substring(0, 1).toUpperCase() + fieldName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);
                fieldValue = getMethod.invoke(entity);
                if (!field.isAnnotationPresent(Id.class)) {
                    continue;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            sb.append(" and ").append(columnName)
                    .append(" = ").append(fieldValue);
        }
        return sb.toString();
    }


    public static String query(Object entity) {
        StringBuffer sb = new StringBuffer();
        Class c = entity.getClass();
        boolean exists = c.isAnnotationPresent(Table.class);
        if (!exists) {
            return null;
        }
        Table t = (Table) c.getAnnotation(Table.class);
        String tableName = t.value();
        sb.append(" select * from ").append(tableName).append(" where 1=1 ");
        Field[] fArray = c.getDeclaredFields();
        for (Field field : fArray) {
            boolean fExists = field.isAnnotationPresent(Column.class);
            if (!fExists) {
                continue;
            }
            Column column = field.getAnnotation(Column.class);
            String columnName = column.value();
            String fieldName = field.getName();
            String getMethodName = "get" + fieldName.
                    substring(0, 1).toUpperCase() + fieldName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);
                fieldValue = getMethod.invoke(entity);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (fieldValue == null || 
                    (fieldValue instanceof Integer && (Integer) fieldValue == 0)
                    || (fieldValue instanceof String 
                         && ((String) fieldValue).trim().equals(""))) {
                continue;
            }
            if (fieldValue instanceof String) {
                sb.append(" and ").append(columnName).
                        append(" = ").append("'" + fieldValue + "'");
            } else {
                sb.append(" and ").append(columnName).
                        append(" = ").append(fieldValue);
            }
        }
        return sb.toString();
    }
}

至此,我们就简单实现ORM关系映射了,不过写到这里还是有很多瑕疵,ID必须是int自增,其他字段最好用varchar,所以还不是很完美吧,这里主要模拟的是ORM的实现原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值