美文网首页
移动架构--12.数据库框架

移动架构--12.数据库框架

作者: 小小秤 | 来源:发表于2018-08-09 17:19 被阅读0次

    实现数据库、表的创建,便于扩展。调用层直接一个对象丢过去,即可实现增删改查。
    1.数据库增删改查接口

    //泛型实现一个对象丢过来实现增删改查
    public interface IBaseDao<T>{
      Long insert(T entity);
      int update(T entity,T where);
      int delete(T where);
      List<T> query(T where);
      List<T> query(T where,String orderBy, Integer startIndex,Integer limit);
      List<T> query(String sql);
    }
    

    2.注解
    因为在对象丢给数据库操作具体类的时候,要找到模型对象对应属性在数据库对应的表、列名。用注解来实现

    //1.数据库表名注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface DbTableName{
      String value();
    }
    
    //2.数据库列名注解
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface DbColumnName{
      String value();
    }
    

    3.工厂模式+单例模式给客户端调用

    public class BaseDaoFactory{
      //数据库存放路径
      private String dataBasePath;
      //操作数据库
      private SQLiteDatabase sqliteDatabase;
    
      private static BaseDaoFactory instance = new BaseDaoFactory();
    
      private BaseDaoFactory(){
        //设定数据库存储路径
        dataBasePath = 
        Environment.getExternalStorageDirectory().getAbsolutePath()
        +"/teacher.db";
        //创建数据库
        openDatabase();
      }
    
      public BaseDaoFactory getInstance(){
        return instance;
      }
      //创建了数据库
      private void openDatabase(){
        this.sqliteDatabase = 
        SQLiteDatabase.openOrCreateDatabase(dataBasePath,null);
      }
    
      //暴露给客户端的方法用于获取Database
      public synchronized <T extends BaseDao<M>,M>
         T 
      getDataHelper(Class<T> clazz,Class<M> entity){
        BaseDao baseDao = null;
        try{
          //反射new实例,每次调用都产生一个实例
          //就算以前调用过得也初始化
          //这里的代码不够优雅
          baseDao = clazz.newInstance();
          //初始化basedao
          baseDao.init(entity,sqlitDatabase);
        }catch(Exception e){e.printStackTrace();}
        return (T)baseDao;
      }
    }
    

    4.抽象的BaseDao类+模板方法具体的创建表交给子类去实现

    public abstract class BaseDao<T> implements IBaseDao<T>{
      //创建表交给子类去实现
      public abstract String createTable();
    
    
      //操作数据库的具体工具类
      protected SQLiteDatabase database;
      //操作的具体对象
      private Class<T> entity;
      //初始化标志符
      private boolean isInit = false;
      //表名
      private String tableName;
      //表列名与对象属性名映射表
      prvate Map<String,String> cacheMap;
    
      protected synchronized boolean init (Class<T> entity,
      SQLiteDatabase sqliteDatabase){
        if(!isInit){
          this.database = sqliteDatabase;
          this.entity = entity;
          if(entity.getAnnotation(DbTableName.class)==null){
            tableName = entity.getClass.getSimpleName;
          }else{
            tableName = entity.getAnnotation(DbTableName.class).value();
          }
          if(!sqliteDatabase.isOpen()){
            return false;
          }
          if(!TextUtils.isEmpty(createTable())){
            database.execSQL(createTable());
          }
          cacheMap = new HashMap<>();
          initCacheMap();
          isInit = true;
        }
        return isInit;
      }
    
      //初始化映射关系
      private void initCacheMap(){
        //1.查询表的各个列名
        String sql = "select * from "+this.tableName+" limit 1 , 0";
        Cursor cursor = null;
        try{
          cursor = database.rawQuery(sql,null);
          //数据表的各个列数据
          String[] columnNames = cursor.getColumnNames();
          //2.获取操作对象的Filed数组
          Field[] columnFields = entity.getFields();
          for(Field field : columnFields){
            //防止私有变量,所以这么操作
            field.setAccessible(true);
          }
          //3.循环遍历获取到的表列名,查看与类对应属性的标注名是否一致
          for(String columnName : columnNames){
            Field mField = null;
    
            for(Filed field : columnFields){
              String fieldName = null;
              if(field.getAnnotation(DbColumnName.class)!=null){
                fieldName = field.getAnnotation(DbColumnName.class).value();
              }else{
                fieldName = field.getName();
              }
              if(columnName.equals(fieldName)){
                mField = field;
                break;//结束内循环,执行内循环外代码
              }
            }
            if(mField!=null){
            cacheMap.put(colmunName,mField);
            }
          }
    
        }catch(Exception e){e.printStackTrace();}
        finally{cursor.close();}
       }
    
      //增操作
      @Override
      public Long insert(T entity){
        //1.根据entity获取 数据库列名和对应的值
        Map<String,String> map = getValues(entity);
        //2.得到的map转换成ContentValues
        ContentValues values=getContentValues(map);
        //3.进行新增操作
        Long result =database.insert(tableName,null,values);
        return result;
      }
      
      //根据传入的entity得到表列名与对应值的关系
      private Map<String,String> getValues(T entity){
        HashMap<String,String> result = new HashMap<>();
        Iterator<Field> iterator = cacheMap.values().iterator();
        while(iterator.hasNext()){
          Field field = iterator.next();
          String key = null;
          String value = null;
          if(field.getAnnotation(DbColumnName.class)!=null){
            key = field.getAnnotation(DbColumnName.class).value();
          }else{
            key = field.getName();
          }
          try{
            if(null==field.get(entity)){continue;}
            value = field.get(entity).toString();
          }catch(Exception e){e.printStackTrace();}
          result.put(key,value);
        }
        return result;
      }
    
      //根据表列名与值的map得到可以插入的ContentValue
      private ContentValues getContentValues(Map<String,String> map){
        ContentValues contentValues = new ContentValues();
        Set keys = map.keySet();
        Iterator<String> iterator = key.iterator();
        while (iterator.hasNext()){
          String key = iterator.next();
          String value = map.get(key);
          if(value!=null){
            contentValues.put(key,value);
          }
        }
        return contentValues;
      }
    
       //删除操作
      @Override
      public int delete(T where){
        Map map = getValues(where);
        Condition condition = new Condition(map);
        int result = database.delete(tableName,condition.getWhereClause(),
        condition.getWhereArgs());
        return result;
      }
    
      //Condition内部类,用户根据entity
      class Condition{
        private String whereClause;
        private String[] whereArgs;
    
        public Condition(Map<String ,String> where) {
          ArrayList list=new ArrayList();
          StringBuilder stringBuilder=new StringBuilder();
    
          stringBuilder.append(" 1=1 ");
          Set keys=where.keySet();
          Iterator iterator=keys.iterator();
          while (iterator.hasNext()){
            String key= (String) iterator.next();
            String value=where.get(key);
            if (value!=null){
              stringBuilder.append(" and "+key+" =?");
              list.add(value);
            }
          }
          this.whereClause=stringBuilder.toString();
          this.whereArgs= (String[]) list.toArray(new String[list.size()]);
        }
        public String[] getWhereArgs() {
          return whereArgs;
        }
        public String getWhereClause() {
          return whereClause;
        }
      }
    
      //更新操作
      @Override
      public int update(T entity, T where) {
        int reslut=-1;
        //更新列与值映射表
        Map values=getValues(entity);
        //原始的列与值映射表
        Map whereClause=getValues(where);
    
        Condition condition=new Condition(whereClause);
        //更新后的值
        ContentValues contentValues=getContentValues(values);
    
        reslut=database.update(tableName,
        contentValues,condition.getWhereClause(),
        condition.getWhereArgs());
        return reslut;
      }
    
      //查询操作
      @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){
          Map map = getValues(where);
          String limitString=null;
          if(startIndex!=null&&limit!=null){
            limitString=startIndex+" , "+limit;
          }
          Condition condition=new Condition(map);
          Cursor cursor=database.query(tableName,null,
          condition.getWhereClause(),
          condition.getWhereArgs(),null,null,orderBy,limitString);
          List<T> result=getResult(cursor,where);
          cursor.close();
          return result;
      }
    
      //Cursor转换成T
      private List<T> getResult(Cursor cursor, T where) {
        ArrayList list=new ArrayList();
        Object item;
        while (cursor.moveToNext()) {
        try {
          item=where.getClass().newInstance();
          Iterator iterator=cacheMap.entrySet().iterator();
          while (iterator.hasNext()) {
            Map.Entry entry= (Map.Entry) iterator.next();
            String colomunName= (String) entry.getKey();
            Integer colmunIndex=cursor.getColumnIndex(colomunName);
            Field field= (Field) entry.getValue();
            Class type=field.getType();
            if(colmunIndex!=-1){
              if(type==String.class){
                //反射方式赋值
                field.set(item,cursor.getString(colmunIndex));
               }else if(type==Double.class){
                field.set(item,cursor.getDouble(colmunIndex));
              }else  if(type==Integer.class){
                field.set(item,cursor.getInt(colmunIndex));
              }else if(type==Long.class){
                field.set(item,cursor.getLong(colmunIndex));
              }else  if(type==byte[].class){
                field.set(item,cursor.getBlob(colmunIndex));
              }else {
                continue;
              }
            }
          }
          list.add(item);
          } catch (InstantiationException e) {
            e.printStackTrace();
          } catch (IllegalAccessException e) {
            e.printStackTrace();
          }
        }
        return list;
      }
    
     }
    

    5.调用层的使用

    //1.实例类
    @DbTableName("tb_user")
    public class User{
      public int user_id;
      @DbColumnName("name")
      public String name;
      @DbColumnName("password")
      public String password
    }
    
    //2.具体的DaseDao
    public class UserDao extents BaseDao{
      @Override
      protected String createTable() {
        return "create table if not exists tb_user(user_Id int,name"+
        " varchar(20),password varchar(10))";
      }
      @Override
      public List query(String sql) {
        return null;
      }
    }
    
    //3.具体操作 通过baseDao操作
    baseDao= BaseDaoFactory.getInstance().getDataHelper(UserDao.class,
    User.class);
    

    相关文章

      网友评论

          本文标题:移动架构--12.数据库框架

          本文链接:https://www.haomeiwen.com/subject/gjpxbftx.html