一起来写个SQLite ORM数据库框架(下)

接上一节 一起来写个SQLite ORM数据库框架(上) 这节讲下代码实现。
首先有4个注解类:表名注解-Table、主键注解-PrimaryKey、列注解-Column、非数据库字段注解-NotDBColumn。因为篇幅的原因 这里只单独看看新增的实现 其他都类似

列注解类

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    String value() default "";
    String defaultValue() default "";
}

列注解对应的对象实体类(ColumnEntity ):

public class ColumnEntity {
    /**
     * 实体类中的属性字段
     */
    private Field field;
    private String columnName;
    private String defaultValue;

    /**
     * 获取指定对象的当前字段的值
     * @param entity    获取字段值的对象
     * @return
     */
    public Object getValue(Object entity) {
        if(entity != null) {
            try {
                //设置属性是可以访问的
                field.setAccessible(true);
                return field.get(entity);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 设置指定对象的当前字段的值
     * @param entity    获取字段值的对象
     * @return
     */
    public void setValue(Object entity, Cursor cursor) throws Exception{
        Class<?> fieldType = field.getType();
        try {
            int columnIdx = cursor.getColumnIndex(columnName);
            if(columnIdx == -1) {//当前游标中没有该字段的值
                return;
            }
            field.setAccessible(true);
            if(fieldType==int.class||fieldType==Integer.class) {
                field.set(entity, cursor.getInt(columnIdx));
                return;
            }
            if(fieldType==char.class||fieldType==String.class){
                field.set(entity, cursor.getString(columnIdx));
                return;
            }
            if(fieldType==long.class||fieldType==Long.class){
                field.set(entity, cursor.getLong(columnIdx));
                return;
            }
            if(fieldType==float.class||fieldType==Float.class){
                field.set(entity, cursor.getFloat(columnIdx));
                return;
            }
            if(fieldType==double.class||fieldType==Double.class){
                field.set(entity, cursor.getDouble(columnIdx));
                return;
            }
        } catch (Exception e) {
            throw e;
        }
    }

//    public Field getField() {
//        return field;
//    }

    public void setField(Field field) {
        this.field = field;
    }

    public String getColumnName() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public String getDefaultValue() {
        return defaultValue;
    }

    public void setDefaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
    }
}

解析注解映射对象管理类(TableEntityManager ):

public class TableEntityManager {

    /**
     * 每张表的相关信息缓存集合
     */
    private static HashMap<Object, TableEntity> mTableMap = new HashMap<Object, TableEntity>();

    /**
     * 获取EntityTable对象
     */
    public static <T> TableEntity getTableEntity(T entity) {
        return getTableEntity(entity.getClass());
    }

    public static <T> TableEntity getTableEntity(Class<?> mClass) {
        if(mTableMap.containsKey(mClass)) {
            return mTableMap.get(mClass);
        } else {
            return createTableEntity(mClass);
        }
    }

    public static TableEntity createTableEntity(Class<?> mClass) {
        TableEntity tableEntity = new TableEntity();
        //设置表名
        setTableName(tableEntity,mClass);
        //设置主键和列
        setColumnList(tableEntity,mClass);
        mTableMap.put(mClass, tableEntity);
        return tableEntity;
    }

    /**
     * 解析注解设置表名
     */
    public static void setTableName(TableEntity tableEntity,Class<?> mClass) {
        Table table = mClass.getAnnotation(Table.class);
        if(null==table||TextUtils.isEmpty(table.value())) {
            tableEntity.setTableName(mClass.getSimpleName());
        }
        tableEntity.setTableName(table.value());
    }

    /**
     * 解析注解设置主键(PrimaryKeyEntity)
     */
    public static boolean setPrimaryKey(TableEntity tableEntity,Field field){
        PrimaryKey primaryKey = field.getAnnotation(PrimaryKey.class);
        if(null == primaryKey) {
            return false;
        }
        if(primaryKey.isAutoGenerate() && field.getType()!=long.class && field.getType()!=int.class){
            throw new RuntimeException("自增长主键字段类型不正确,请设置自增长字段类型为long或者int");
        }
        PrimaryKeyEntity primaryKeyEntity = new PrimaryKeyEntity();
        primaryKeyEntity.setField(field);
        if(TextUtils.isEmpty(primaryKey.value())) {//没有通过注解设置列名,默认取字段名称为列名
            primaryKeyEntity.setColumnName(field.getName());
        } else {
            primaryKeyEntity.setColumnName(primaryKey.value());
        }
        primaryKeyEntity.setAutoGenerate(primaryKey.isAutoGenerate());//获取是否自动增长
        tableEntity.setPrimaryKey(primaryKeyEntity);
        return true;
    }

    /**
     * 解析注解获得字段列名和默认值并封装到 ColumnEntity
     */
    public static void setColumnList(TableEntity tableEntity,Class<?> mClass) {
        Field[] fields = mClass.getDeclaredFields();
        List<ColumnEntity> columnList = new ArrayList<ColumnEntity>();
        ColumnEntity columnEntity = null;
        for(Field field:fields){
            if (Modifier.isStatic(field.getModifiers())) {//过滤掉static静态字段
                continue;
            }
            if(field.getType() == Object.class) {//过滤掉非基本类型字段
                continue;
            }
            NotDBColumn notDbColumn = field.getAnnotation(NotDBColumn.class);
            if(null != notDbColumn) {//非数据库字段不作处理
                continue;
            }
            if(null==tableEntity.getPrimaryKey()){ //判断是否有主键注释 并设置主键
                if(setPrimaryKey(tableEntity,field)){
                    continue;
                }
            }
            //获取每个字段的注解
            Column column = field.getAnnotation(Column.class);
            columnEntity = new ColumnEntity();
            columnEntity.setField(field);
            // 解析注解设置列名,默认取字段名称为列名
            String columnName = field.getName();
            if(column != null) {
                if (!TextUtils.isEmpty(column.value())) {
                    columnName = column.value();
                }
                if(!TextUtils.isEmpty(column.defaultValue())){
                    columnEntity.setDefaultValue(column.defaultValue());
                }
            }
            columnEntity.setColumnName(columnName);
            columnList.add(columnEntity);
        }
        tableEntity.setColumnList(columnList);
    }
}

拼接SQL语句类(SQLBuilder) 这里说下在拼创建表的sql的时候 我并没有把字段类型拼上 这是由于对于sqllite数据库 它有个特点就是可以是无类型的 意思就是你给它什么类型 它就会存什么类型 所以我省去转化类型的步骤

//拼接插入的sql语句
public static <T> BindSQL getInsertSQL(TableEntity tableEntity,T entity){
        StringBuilder sql = new StringBuilder();
        StringBuilder valueSql = new StringBuilder();
        int size = tableEntity.getColumnList().size();
        Object[] args = new Object[size+1];
        sql.append("INSERT INTO ").append(tableEntity.getTableName()).append("(");
        valueSql.append(" VALUES(");

        int i = 0;
        PrimaryKeyEntity primaryKey = tableEntity.getPrimaryKey();
        if(null!=primaryKey&&!primaryKey.isAutoGenerate()){
            sql.append(primaryKey.getColumnName()+",");
            valueSql.append("?,");
            args[i++] = primaryKey.getValue(entity);
        }

        for (ColumnEntity columnEntity:tableEntity.getColumnList()){
            Object valueObj = columnEntity.getValue(entity);
            if(null!=valueObj){
                sql.append(columnEntity.getColumnName());
                sql.append(",");
                valueSql.append("?");
                valueSql.append(",");
                args[i++] = columnEntity.getValue(entity);
            }
        }

        sql.deleteCharAt(sql.length() - 1);
        valueSql.deleteCharAt(valueSql.length()-1);
        sql.append(")");
        valueSql.append(")");
        sql.append(valueSql);
        Object[] args2 = new Object[i];
        System.arraycopy(args,0,args2,0,i);
        return new BindSQL(sql.toString(),args2);
    };

执行数据库操作管理类(SQLExecuteManager ):

/**
 * 新增一条数据
 */
public <T> long insert(T entity){
    TableEntity tableEntity = TableEntityManager.getTableEntity(entity);
    BindSQL bindSQL = SQLBuilder.getInsertSQL(tableEntity,entity);
    long rowId =  insert(bindSQL.getSql(),bindSQL.getBindArgs());
    return rowId;
}

框架入口类(SQLiteDB)

 /**
   * 新增一条数据
   */
  public <T> long insert(T entity){
      return mSQLExecuteManager.insert(entity);
  }

整个easyDB数据库框架的大体结构就介绍到这里了,大家可以下载源码查看更多实现 ,还有很多不足的地方 比如不支持多数据库,线程安全等 也可以自行扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值