ORM
ORM-对象关系映射(Object relation mapping), 主要是将对象模型表示的对象(例如java object)映射到基于SQL的关系数据库,这样我们在操作具体的实体对象时,就不需要跟SQL打交道,而只需要操作具体对象的属性,ORM 技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化。
具体到Android上,就是我们在处理业务的时候不应该直接跟SQL打交道,而应该将数据库中的数据到对象的转换封装在底层,上层只需要跟对象(Model)打交道。通常我们会将数据的增删改查封装在ContentProvider中,通过uri获取,修改数据, 但是从ContentProvider中查询出来的数据(Cursor),仍然描述的是数据库中的数据结构(数据列), 需要转换成Model,通常的做法是在Model(或者管理这个Model的Manager 类)中,负责将数据库存储的数据转换成Model, 以及将Model转换成数据库数据。但是这样的一个很大的问题是:每一个需要存储的Model都需要写一份存储解析逻辑.
public class Student {
private String name;
private int number;
private static Uri uri = Uri.parse("student_uri");
List<Student> allStudents = new ArrayList<Student> ();
public Student(String name, int number) {
this.name = name;
this.number = number;
}
public void saveToDB() {
ContentValues values = new ContentValues();
values.put("name", name);
values.put("number", number);
updateDB(uri, values);
}
public void initAllCachedStudentFromDB() {
Cursor cursor = AppGlobals.getContext().query(uri);
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
Student student = parse(cursor);
allStudents.add(student);
}
}
}
public class School {
private String name;
private String address;
private static Uri uri = Uri.parse("adress_uri");
List<School> allSchools = new ArrayList<School> ();
public School(String name, String address) {
this.name = name;
this.address = address;
}
public void saveToDB() {
ContentValues values = new ContentValues();
values.put("name", name);
values.put("address", address);
updateDB(uri, values);
}
public void initAllCachedSchoolFromDB() {
Cursor cursor = AppGlobals.getContext().query(uri);
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
School school = parse(cursor);
allSchool.add(school);
}
}
}
显示对于这样重复性的工作,需要自动化。对于这种自动化,基本上核心就两点:
- 反射
- Annotation
对于Orm,可定义定义两个Annotation
@Target(ElementType.Type)
@Retention(RetentionPolicy.RUNTIME) //这个必需,因为需要保证运行时这个Annotation还保留
public @interface Table {
/**
table name
*/
value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
/**
column name
*/
values();
}
@Table("student)
public class Student {
@Column("name")
private String name;
@Column("number")
private int number;
}
public class MyDatabaseHelper extends SQLiteDatabase {
public void save(Object obj) {
Class<?> clazz = obj.getClass();
String tableName = clazz.getAnnotation(Table.class).values();
List<Field> fields = FieldUtil.getAllDeclaredFields(claxx);
ContentValues
for (Field field : fields) {
Annotation annotation = field.getAnnotation(Column.class);
if (annotation != null) {
String columnName = annotation.values();
values.put(columnName, field.get(obj));
}
}
getWritableDatabase().insert(values);
}
}