android架构师之路——面向对象数据库

简介

  • BaseDaoFactory  数据库创建,初始化
  • IBaseDao 增删改查接口
  • BaseDao 增删改查具体的实现
  • User 增删改查的对象
  • DbField 数据库字段名字标注
  • DbTable 数据库表名注解

我们这里只要是学习对象型数据库实现原理,如果要直接使用,可以查看GreenDao直接使用

BaseDaoFactory
public class BaseDaoFactory {

    private static final BaseDaoFactory instance = new BaseDaoFactory();
    //定义建数据库的路劲
    private String sqliteDatabasePath;
    private SQLiteDatabase sqLiteDatabase;

    public static BaseDaoFactory getInstance() {
        return instance;
    }

    public BaseDaoFactory() {
        //新建数据库
        //数据库路径,建议创建在sdcard上面,即使卸载了,数据库依然存在
//        sqliteDatabasePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "zkq.db";
        sqliteDatabasePath = "data/data/com.example.db_project/zkq.db";
        sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(sqliteDatabasePath, null);
    }
    public <T> BaseDao<T> getBaseDao(Class<T> entityClass) {
        BaseDao baseDao = null;
        try {
            baseDao = BaseDao.class.newInstance();
            baseDao.init(sqLiteDatabase, entityClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return baseDao;
    }
}
BaseDao中

 initCacheMap方法,将数据库中的字段和传入的user字段匹配,如果数据库中的字段名字和user的变量名字相匹配,就存入cacheMap中,方便读取

getValues方法,将user中的字段读取出来,放回一个Map<String,String>

下面是BaseDao全部代码

public class BaseDao<T> implements IBaseDao<T> {

    private static final String TAG = "BaseDao";
    //持有数据库操作的引用
    private SQLiteDatabase sqLiteDatabase;

    //持有操作数据库所对应的java类型
    private Class<T> entityClass;

    //表名
    private String tableName;

    //定义一个缓存空间(key-字段名   value-成员变量)
    private HashMap<String, Field> cacheMap;

    //标记:用来表示是否做过初始化操作
    private boolean isInit = false;

    public void init(SQLiteDatabase sqLiteDatabase, Class<T> entityClass) {
        this.sqLiteDatabase = sqLiteDatabase;
        this.entityClass = entityClass;

        //可以根据传入的entityClass类型来建表,只需要建一次
        if(!isInit){
            //自动建表
            //取得表明
            if(entityClass.getAnnotation(DbTable.class) == null){
                //反射到类名
                this.tableName =  entityClass.getSimpleName();
            } else {
                //取得注解上的名字
                this.tableName =  entityClass.getAnnotation(DbTable.class).value();
            }

            //执行建表操作
            // create table if not exists tb_user(_id TEXT,name TEXT,password TEXT)
            //使用getCreateTableSql() 生成sql语句
            String createTableSql = getCreateTableSql();
            Log.i(TAG, createTableSql);
            this.sqLiteDatabase.execSQL(createTableSql);
            cacheMap  = new HashMap<>();
            initCacheMap();
            isInit = true;
        }
    }

    /**
     * 初始化数据表字段
     * 将数据库中的字段和传入的user字段匹配,如果数据库中的字段名字和user的变量名字相匹配,就存入cacheMap中,方便读取
     */
    private void initCacheMap() {
        //1、取得所有字段名
        String sql = "select * from " + tableName + " limit 1, 0";  //空表
        Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
        String[] columnNames = cursor.getColumnNames();
        //2、取所有的成员变量
        Field[] declaredFields = entityClass.getDeclaredFields();
        //把所有字段的访问权限打开
        for (Field f: declaredFields) {
            f.setAccessible(true);
        }

        //字段 跟  成员变量一一对应
        for(String columNage : columnNames){
            Field columnField = null;
            for(Field field : declaredFields){
                String fieldName = "";  //对象中的成员变量名字
                if(field.getAnnotation(DbField.class) != null){
                    fieldName = field.getAnnotation(DbField.class).value();
                } else {
                    fieldName = field.getName();
                }

                if(columNage.equals(fieldName)){  //匹配
                    columnField = field;
                    break;
                }
            }

            if(columnField != null){
                cacheMap.put(columNage, columnField);
            }
        }
    }

    /**
     * 建表的sql语句
     *
     * @return
     */

    private String getCreateTableSql() {
       //create table if not exists tb_user(_id TEXT,name TEXT,password TEXT,status INTEGER)
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("create table if not exists ");
        stringBuffer.append(tableName + "(");
        //反射得到所有的成员变量
        Field[] declaredFields = entityClass.getDeclaredFields();
        for (Field field : declaredFields) {
            Class type = field.getType();// 拿到成员的类型

            if(field.getAnnotation(DbField.class) != null){
                //通过注解获取
                if(type == String.class){
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " TEXT,");
                } else  if(type == Integer.class){
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " INTEGER,");
                }else  if(type == Long.class){
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " BIGINT,");
                }else  if(type == Double.class){
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " DOUBLE,");
                }else  if(type == byte[].class){
                    stringBuffer.append(field.getAnnotation(DbField.class).value() + " BLOB,");
                }else {
                    //不支持的类型
                    continue;
                }
            } else {
                //通过反射获取
                if(type == String.class){
                    stringBuffer.append(field.getName() + " TEXT,");
                } else  if(type == Integer.class){
                    stringBuffer.append(field.getName() + " INTEGER,");
                }else  if(type == Long.class){
                    stringBuffer.append(field.getName() + " BIGINT,");
                }else  if(type == Double.class){
                    stringBuffer.append(field.getName() + " DOUBLE,");
                }else  if(type == byte[].class){
                    stringBuffer.append(field.getName() + " BLOB,");
                }else {
                    //不支持的类型
                    continue;
                }
            }
        }

        if(stringBuffer.charAt(stringBuffer.length()  - 1) == ','){
            stringBuffer.deleteCharAt(stringBuffer.length()  - 1);
        }
        stringBuffer.append(")");
        return stringBuffer.toString();
    }

    @Override
    public long insert(T entity) {
        //1、准本好ContentValues中需要的数据
        Map<String, String> map = getValues(entity);
        //2、把数据转移到ContentValues
        ContentValues values = getContentValues(map);
        //3、开始插入
        long result = sqLiteDatabase.insert(tableName, null, values);
        return result;
    }



    /**
     *
     * @param map 成员变量的名字  成员变量的值
     * @return
     */
    private ContentValues getContentValues(Map<String, String> map) {
        ContentValues contentValues = new ContentValues();
        Set keys = map.keySet();
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()){
            String key = iterator.next();
            String value = map.get(key);
            if(value != null){
                contentValues.put(key, value);
            }
        }
        return contentValues;
    }


    /**
     * 将entity的字段放入到map中
     * @param entity
     * @return
     */
    private Map<String, String> getValues(T entity) {
        HashMap<String, String> map = new HashMap<>();
        //返回的是所有的成员变量
        Iterator<Field> iterator = cacheMap.values().iterator();
        while (iterator.hasNext()){
            Field field = iterator.next();
            field.setAccessible(true);

            try {
                //获取对象的属性的值
                Object obj = field.get(entity);
                if(obj == null){
                    continue;
                }

                String value = obj.toString();

                String key  = "";
                if(field.getAnnotation(DbField.class) != null){
                    key = field.getAnnotation(DbField.class).value();
                } else {
                    key = field.getName();
                }

                if(!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)){
                    map.put(key, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return map;
    }

    @Override
    public int update(T entity, T where) {

        int result = -1;
        //1、准本好ContentValues中需要的数据
        Map<String, String> values = getValues(entity);
        ContentValues contentValues = getContentValues(values);

        //条件map
        Map<String, String> values1 = getValues(where);

        Condition condition = new Condition(values1);

        result = sqLiteDatabase.update(tableName, contentValues, condition.whereClause, condition.whereArgs);
        return result;
    }

    @Override
    public int delete(T where) {
        int result = -1;
        //1、准本好ContentValues中需要的数据
        Map<String, String> values = getValues(where);
        Condition condition = new Condition(values);
        result = sqLiteDatabase.delete(tableName, condition.whereClause, condition.whereArgs);
        return result;
    }

    @Override
    public List<T> query(T where) {
        return query(where, null, null, null);
    }

    @Override
    public List<T> query(T where, String orderBy, Integer startIndex, Integer limit) {
//        sqLiteDatabase.query(tableName, null, "id = ?",
//                new String[], null. null, orderBy, "1, 5");
        //1、准本好ContentValues中需要的数据
        Map<String, String> values = getValues(where);

        String limitString = "";   //"2,6"
        if(startIndex != null && limit != null){
            limitString = startIndex + " , " + limit;
        }

        Condition condition = new Condition(values);

        Cursor query = sqLiteDatabase.query(tableName, null, condition.whereClause,
                condition.whereArgs, null, orderBy, limitString);

        List<T> result = getResult(query, where);  //游标  --- 》 javabean  --- list<javabaen>
        return result;
    }

    private List<T> getResult(Cursor query, T where) {
        ArrayList list = new ArrayList();
        Object item = null;
        while (query.moveToNext()){
            try {
                item = where.getClass().newInstance();  //因为不知道 new  ? , 所以通过反射方式
                //cacheMap  (字段---成员变量的名字)
                Iterator<Map.Entry<String, Field>> iterator = cacheMap.entrySet().iterator();
                while (iterator.hasNext()){
                    Map.Entry<String, Field> entry = iterator.next();
                    //取列名
                    String columnName = entry.getKey();

                    //以列名拿到列名在游标中的位置
                    int columnIndex = query.getColumnIndex(columnName);

                    Field value = entry.getValue();   //id
                    Class<?> type = value.getType();  //Integer
                    if(columnIndex != -1){  //columnName = "age"
                        if(type==String.class){
                            value.set(item,query.getString(columnIndex));//setid(1)
                        }else if(type==Double.class){
                            value.set(item,query.getDouble(columnIndex));
                        }else if(type==Integer.class){
                            value.set(item,query.getInt(columnIndex));
                        }else if(type==Long.class){
                            value.set(item,query.getLong(columnIndex));
                        }else if(type==byte[].class){
                            value.set(item,query.getBlob(columnIndex));
                        }else{
                            continue;
                        }
                    }
                }
                list.add(item);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        query.close();
        return list;
    }

    private class Condition {
        private String whereClause;  //1=1 and password = ?  --- >password = ?
        private String[] whereArgs;

        /**
         * new Person(1, "alan", "123")
         * @param whereCasue
         */
        public Condition(Map<String, String> whereCasue ) {
            ArrayList list = new ArrayList();  //whereArgs里面的内容存入的list
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("1=1");
            //取得所有成员变量的名字
            Set<String> keys = whereCasue.keySet();
            Iterator<String> iterator = keys.iterator();
            while (iterator.hasNext()){
                String key = iterator.next();
                String value = whereCasue.get(key);
                if(value != null){
                    stringBuffer.append(" and " + key + "=?");
                    list.add(value);
                }
            }

            this.whereClause = stringBuffer.toString();
            this.whereArgs = (String[]) list.toArray(new String[list.size()]);
        }
    }
}

User代码

/**
 * 如果没有设置DbTable 数据库表名就是tb_user
 * 设置了DbTable,数据库表名就是User
 */
@DbTable("tb_user")
public class User {
    /**
     * 如果没有设置DbField 数据库保存的就是id
     * 设置了DbField,数据库字段就是_id
     */
    @DbField("_id")
    private String id;
    private String name;
    private String password;

    public User() {
    }

    public User(String id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
DbTable代码
/**
 * 表名
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DbTable {
    String value();
}
DbField代码
/**
 * 字段名
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DbField {
    String value();
}

在mainActivity中具体使用

    /**
     * 插入
     * @param view
     */
    public void insert(View view) {
        BaseDao baseDao = BaseDaoFactory.getInstance().getBaseDao(User.class);
        baseDao.insert(new User("1", "zhangsan", "111111"));
        baseDao.insert(new User("2", "lisi", "222222"));
        baseDao.insert(new User("3", "wangwu", "333333"));
        baseDao.insert(new User("4", "zhaoliu", "444444"));
        baseDao.insert(new User("5", "liqi", "555555"));
    }

    /**
     * 修改
     * @param view
     */
    public void clickUpdate(View view) {
        BaseDao baseDao = BaseDaoFactory.getInstance().getBaseDao(User.class);
        User user = new User("5","liqi","666666");
        User where = new User("5","","");
        baseDao.update(user,where);
    }

    /**
     * 删除
     * @param view
     */
    public void clickDelete(View view) {
        BaseDao baseDao = BaseDaoFactory.getInstance().getBaseDao(User.class);
        User where = new User("2","","");
        baseDao.delete(where);
    }

    /**
     * 查询
     * @param view
     */
    public void clickSelect(View view) {
        BaseDao baseDao = BaseDaoFactory.getInstance().getBaseDao(User.class);
        User user = new User();
        List<User> users = baseDao.query(user);
        for (User user1 : users) {
            Log.e(TAG,user1.toString());
        }
    }

demo下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值