前言
对象关系映射(英语:(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的实现原理。