美文网首页
移动架构--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