【转载请注明出处】
作者:DrkCore (http://blog.csdn.net/DrkCore)
原文链接:(http://blog.csdn.net/drkcore/article/details/51866495)
xUtils3 的数据库模块是我们经常使用的一个模块。如果你对 SQLiteOpenHelper 的各种方法十分的熟悉的话你就会发现该模块其实就是对其的一种封装:通过注解、建造者模式等方式替代徒手撕鬼子式手写 SQL 语句来规范化对数据库的操作,毫无疑问的是——这确实帮了我们很大的忙。
Column注解与Converter
大多数注解本身只是起到一个标记的作用,Column 注解也不例外,其源码如下:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String name();
String property() default "";
boolean isId() default false;
boolean autoGen() default true;
}
用过 xUtils3 数据库模块的人都知道每个方法代表意义,不再赘述。
在运行过程中 Column 所标注的成员变量会被“翻译”成 ColumnEntity:
/* package */ ColumnEntity(Class<?> entityType, Field field, Column column) {
field.setAccessible(true);
this.columnField = field;
this.name = column.name();
this.property = column.property();
this.isId = column.isId();
Class<?> fieldType = field.getType();
this.isAutoId = this.isId && column.autoGen() && ColumnUtils.isAutoIdType(fieldType);
this.columnConverter = ColumnConverterFactory.getColumnConverter(fieldType);
this.getMethod = ColumnUtils.findGetMethod(entityType, field);
if (this.getMethod != null && !this.getMethod.isAccessible()) {
this.getMethod.setAccessible(true);
}
this.setMethod = ColumnUtils.findSetMethod(entityType, field);
if (this.setMethod != null && !this.setMethod.isAccessible()) {
this.setMethod.setAccessible(true);
}
就像我们知道的那样,注解要和反射混着用才能发挥神奇的疗效,这里也不例外。需要注意的是这里的一行代码:
this.columnConverter = ColumnConverterFactory.getColumnConverter(fieldType);
我们知道在 SQLite 中除了整形的主键列之外其他列存储的类型都是未定的,所以和 JAVA 的基础数据类型自然不可能一一对应。
在JAVA中整数的类型就有 int、short、long 三种类型而在 SQLite 中只有一个 INTEGER,另一个例子是 SQLite 没有 BOOLEAN类型。这些矛盾在 xUtils3 中是通过策略工厂模式来化解的,就拿 BooleanColumnConverter做例子:
public class BooleanColumnConverter implements ColumnConverter<Boolean> {
@Override
public Boolean getFieldValue(final Cursor cursor, int index) {