美文网首页1-Android开发知识
android自己动手封装Sqllite数据库

android自己动手封装Sqllite数据库

作者: 代码界的泥石流 | 来源:发表于2018-03-08 18:04 被阅读254次

    废话:

    android数据库框架现在特别多,比如greenDAO,litepal都是各个大神封装好的,有时候自己只知道用,却不知道实现原理,于是自己准备动手撸一个。此框架是面向对象式数据库框架设计

    • 对于用户而言,调用一句话就可以实现增删改查的代码才是好代码,基于这种考虑,我们的框架必不可少使用泛型、反射、注解、等操作,建议大家先了解一下这些java的基本操作。
    • 首先创建一个Bean类(模拟用户插入数据库的类)
    //比如说User表  字段:id name password
    public class User {
        private Integer id;
        private String name;
        private String password;
    }
    
    既然是创建表,用户想自定义自己的字段名称和表名,那么我们就用注解去标志,在创建表或字段的时候,如果有注解,那么就取注解中的名称,反之直接取bean中默认的字段名称。

    新建表名的注解

    /**
     *
     * 用来控制表名叫做什么的注解类
     */
    @Target(ElementType.TYPE)//注解方法的
    @Retention(RetentionPolicy.RUNTIME)//保留位置 必须运行时 执行过程 获取相关信息
    public @interface DbTable {
        String value();
    }
    
    /**
     *
     * 用来控制字段名称叫做什么的注解类
     */
    @Target(ElementType.FIELD)//注解方法的
    @Retention(RetentionPolicy.RUNTIME)//保留位置 必须运行时 执行过程 获取相关信息
    public @interface DbField {
        String value();
    }
    

    那么我们的Bean类 如果想自定义表名,和自定义一些字段名称,可以改成

    @DbTable("tb_user")
    public class User {
        @DbField("_id")
        private Integer id;
        private String name;
        private String password;
    }
    

    好了,接下来,我们提供一个顶层接口类,此类的意义在于,给用户提供整体功能的一个接口类 我们封装增、删、改、查的具体实现,用户只需调用想用的功能,传入一些定制化参数

    /**
     * 封装操作功能的接口类
     */
    
    public interface IBaseDao<T> {
        long insert(T entity);
    
    //    int delete(String where);
    //
    //    long update(T entity, String where);
    //
    //    List<T> query(String where);
    //
    //    List<T> query(String where, String orderBy, Integer startIndex, Integer limit);
    //
    //    List<T> query(String sql);
    
    }
    

    然后,我们则实现insert操作。插入操作,我们必须先自动创建一个表,并且类中持有数据库的引用,对数据库操作,然后我们获取表名,字段,因为字段是外部传入,我们可以使用T泛型拿到,但是不灵活,此处我使用了Class拿到字节码进行操作 更方便。

    /**
     * 1.完成自动建表功能
     */
    
    public class BaseDao<T> implements IBaseDao<T> {
        //持有数据库的引用 对于数据库操作
        private SQLiteDatabase sqLiteDatabase;
        //表名
        private String tableNmae;
        //持有操作数据库所对应的java类型
        private Class<T> entityClass;
        //标识:用来标识是否做过初始化操作
        private boolean isInit = false;
    
        //框架内部逻辑,最好不要提供构造方法给调用层调用
    //    public BaseDao(SQLiteDatabase sqLiteDatabase, Class<T> entityClass) {
    //        this.sqLiteDatabase = sqLiteDatabase;
    //        this.entityClass = entityClass;
    //    }
        public boolean init(SQLiteDatabase sqLiteDatabase, Class<T> entityClass) {
            this.sqLiteDatabase = sqLiteDatabase;
            this.entityClass = entityClass;
            //根据传入的entityClass来建立表,只需建立一次
            if (!isInit) {
                isInit = true;
                //自动建表
                //取到表名 判断表上有没有自定义注解类名
                if (entityClass.getAnnotation(DbTable.class) == null) {
                    //反射到类名
                    tableNmae = entityClass.getSimpleName();
                } else {
                    //取注解上的名字
                    tableNmae = entityClass.getAnnotation(DbTable.class).value();
                }
                if (!sqLiteDatabase.isOpen()) {
                    return false;//数据库没打开 初始化失败
                }
                //执行建表操作
                //create table if not exists tb_user(_id integer,name varchar2(20),password varchar(20))
                //单独用个方法生成create命令
                String createTableSql = getCreateTableSql();
                sqLiteDatabase.execSQL(createTableSql);
    
            }
    
            return isInit;
        }
    }
    
    
    

    获取到了表名,建表之前,获取传入实体类所有成员变量类型。

        private String getCreateTableSql() {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("create table if not exists ");
            stringBuffer.append(tableNmae + "(");
            //反射得到所有的成员变量
            Field[] fields = entityClass.getDeclaredFields();
            for (Field field : fields) {
                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();
            }
         
    

    到此,此处我们的建表操作已经写好,但是如何提供给用户使用呢,那么我们将再写一个工厂类,用户调用工厂类,工厂类调用实现方法,则实现创表操作。

    public class BaseDaoFactory {
        private static final BaseDaoFactory ourInstance = new BaseDaoFactory();
    
        public static BaseDaoFactory getOurInstance() {
            return ourInstance;
        }
    
        private SQLiteDatabase sqLiteDatabase;
        //定义建数据数据的路径
        //建议写在SD卡中 好处APP删了 下次安装 数据还在
        private String sqliteDatabasePath;
    
        private BaseDaoFactory() {
            //内置sd卡路径
            String sqlitePath = createSDCardOrOpenDir() + "/dao.db";
            if (sqlitePath == null) {
                //SD卡不存在
                return;
            }
            sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(sqlitePath, null);
        }
    
        public String createSDCardOrOpenDir() {
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                // 创建一个文件夹对象,赋值为外部存储器的目录
                File sdcardDir = Environment.getExternalStorageDirectory();
                //得到一个路径,内容是sdcard的文件夹路径和名字
                String path = sdcardDir.getPath() + "/dbImage";
                File newpath = new File(path);
                if (!newpath.exists()) {
                    //若不存在,创建目录,可以在应用启动的时候创建
                    newpath.mkdirs();
                }
                return path;
    
            } else {
                return null;
            }
    
        }
    
        public <T> BaseDao<T> getBaseDao(Class<T> entityClass) {
            BaseDao baseDao = null;
            try {
                baseDao = BaseDao.class.newInstance();
                baseDao.init(sqLiteDatabase, entityClass);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return baseDao;
        }
    

    //此处测试一下 测试

       BaseDao baseDao = BaseDaoFactory.getOurInstance().getBaseDao(User.class);
            Toast.makeText(this, "执行成功", Toast.LENGTH_SHORT);
    
    • CRUD操作 必不可少需要成员变量获取字段和值等,此处反射太耗时,我们整体写一个缓存参数,将成员变量和数据库的字段缓存起来,方便下次对对象操作可以直接从缓存里取数据
      //CacheMap  键值对  对应着 字段 》成员变量
      private HashMap<String, Field> cacheMap; 
    
      private void initCacheMap() {
            //获取所有列名 空表
            String sql = "select * from " + tableNmae + " limit 1,0";
            Cursor cursor = sqLiteDatabase.rawQuery(sql, null);
            String[] columnNames = cursor.getColumnNames();//获取所有字段名字
            //获取成员变量
            Field[] fields = entityClass.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);//把字段设置可写;
            }
            for (String columnName : columnNames) {//循环字段
                Field columField = null;
                for (Field field : fields) {//循环成员变量
                    String fieldName = null;
                    if (field.getAnnotation(DbField.class) != null) {
                        fieldName = field.getAnnotation(DbField.class).value();
                    } else {
                        fieldName = field.getName();
                    }
                    if (fieldName.equals(columnName)) {//
                        columField = field;
                        break;
                    }
                }
                cacheMap.put(columnName, columField);
            }
    
            //把字段和成员变量映射起来
    
        }
    

    并且将初始化操作 放入init方法中。

    • Insert方法定义
      在顶层接口中,定义一个insert(T entity)方法 在BaseDao去实现
      普通插入方法: sqLiteDatabase.insert(tableNmae,null,contentValues)
      contentValues对应的则是插入对象的数据。
      封装思路:第一步先从cacheMap获取数据 并且将值传入一个MAP,然后将MAP再封装到ContentValues,此处之所以不直接用cacheMAp封装到ContentValues,因为后面会时常用到Map。
     private Map<String, String> getValues(T entity) {
            Map<String, String> resultMap = new HashMap<>();
            //获取传入类的key  values
            Iterator<Field> iterator = cacheMap.values().iterator();
            while (iterator.hasNext()) {
                Field field = iterator.next();
                try {
                    Object object = field.get(entity);//获取成员变量的值
                    String value = object.toString();
                    if (object == null) {
                        continue;
                    }
                    String key = null;
                    //获取key
                    if (field.getAnnotation(DbField.class)!= null) {
                        key = field.getAnnotation(DbField.class).value();
                    } else {
                        key = field.getName();
                    }
                    if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
                        resultMap.put(key, value);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            return resultMap;
        }
    
       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;
    
        }
    

    BaseDao实现类就可以

        public long insert(T entity) {
            Map<String, String> map = getValues(entity);
            ContentValues contentValues = getContentValues(map);
            long result = sqLiteDatabase.insert(tableNmae, null, contentValues);
            return result;
        }
    

    测试:

       public void insertObject(View view) {
            BaseDao baseDao = BaseDaoFactory.getOurInstance().getBaseDao(Person.class);
            baseDao.insert(new Person("lcx",24));
            Toast.makeText(this, "执行成功", Toast.LENGTH_SHORT).show();
        }
    

    这是插入操作,接下来 我们可以进行 修改+删除操作

    • 修改
      正常修改操作:
    sqLiteDatabase.update(tableNmae,contentvalues,"name=?",new String[] {"lcx"})
    

    那么我们定义一个方法

     public long update(T entity, T where) {}
    

    entity 传入修改的对象
    where 代表修改的条件

    tatableNmae获取得到,contentvalues也可以获取到,通过cacheMap获取缓存的成员变量,再通过成员获取传入entity的值,最后封装到ContentValues,
    和insert一个道理,然后具体条件,我们将定义一个内部类,写个构造,传入修改的MAp值,这样我们就可以得到 “name=?" 和条件的值

     public class Condition {
            private String whereCause;
            private String[] whereArgs;
    
            public Condition(Map<String, String> whereCause) {
                ArrayList arrayList = new ArrayList();
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append("1=1");
                //取所有字段值
                Set keys = whereCause.keySet();
                Iterator iterator = keys.iterator();
                while (iterator.hasNext()) {
                    String key = (String) iterator.next();
                    String value = whereCause.get(key);
                    if (value != null) {
                        stringBuilder.append(" and " + key + "=?");
                        arrayList.add(value);
                    }
                }
                this.whereCause = stringBuilder.toString();
                this.whereArgs = (String[]) arrayList.toArray(new String[arrayList.size()]);
            }
    
            ;
    

    最后我们的修改操作代码 是这样的

    public long update(T entity, T where) {
    //        UPDATE Person SET FirstName = 'Fred' WHERE LastName = 'Wilson'
    //        sqLiteDatabase.update(tableNmae,contentvalues,"name=?",new String[] {"lcx"})
          long result = -1;
          Map map = getValues(entity);
          ContentValues contentValues = getContentValues(map);
          //定义内部类  用来拼接修改参数及条件
          Map whereCause = getValues(where);
          Condition condition = new Condition(whereCause);
          sqLiteDatabase.update(tableNmae, contentValues, condition.whereCause, condition.whereArgs);
          return result;
      }
    
    • 删除
      既然修改出来了 删除就更简单啦
        @Override
        public long delete(T where) {
    //        sqLiteDatabase.delete(tableNmae,whrerClause,whereArgs);
            Map map = getValues(where);
            Condition condition = new Condition(map);
            long result = sqLiteDatabase.delete(tableNmae, condition.whereCause, condition.whereArgs);
            return result;
    
    
    • 查询
      查询的话 相比较删除和修改稍微复杂一些,因为涉及查询到的数据动态转化集合对象。
      正常查询
     sqLiteDatabase.query(tableName,null,"id=?",new String[],null,null,orderBy,"1,5");
    

    封装:

     @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");
            Map map = getValues(where);
            String limitString = null;
            if (startIndex != null && limit != null) {
                limitString = startIndex + " , " + limit;
            }
            Condition condition = new Condition(map);
    
            Cursor cursor = sqLiteDatabase.query(tableNmae, null, condition.whereCause, condition.whereArgs, null, null, orderBy, limitString);
            //定义一个用来解析游标的方法
            List<T> result = getResult(cursor, where);
            return result;
        }
    

    主要涉及到对象转换。
    循环查询出的游标,实例化传入对象,然后获取缓存的所有Map 字段-成员变量,然后循环,得到数据库字段,获取字段在游标位置,获取成员变量,通过成员变量获取属性,判断并进入对应各个属性,动态设置Field的值。最后将对象添加集合 并返回集合数据

     //obj是用来表示User类的结构
        private List<T> getResult(Cursor cursor, T obj) {
            ArrayList list = new ArrayList();
            Object item = null;
            while (cursor.moveToNext()) {
                try {
                    item = obj.getClass().newInstance();//new User();
                    Iterator iterator = cacheMap.entrySet().iterator();//字段-成员变量
                    while (iterator.hasNext()) {
                        Map.Entry entry = (Map.Entry) iterator.next();
                        //取列名
                        String columnName = (String) entry.getKey();
                        //然后以列名拿到列名在游标中的位置
                        Integer columnIndex = cursor.getColumnIndex(columnName);
    
                        Field field = (Field) entry.getValue();
                        Class type = field.getType();
    
                        if (columnIndex != -1) {
                            if (type == String.class) {
                                field.set(item, cursor.getString(columnIndex));//set(Object obj, Object value) : 向obj对象的这个Field设置新值value
                            } else if (type == Double.class) {
                                field.set(item, cursor.getDouble(columnIndex));
                            } else if (type == Integer.class) {
                                field.set(item, cursor.getInt(columnIndex));
                            } else if (type == Long.class) {
                                field.set(item, cursor.getLong(columnIndex));
                            } else if (type == byte[].class) {
                                field.set(item, cursor.getBlob(columnIndex));
                            } else {
                                continue;
                            }
                        }
                    }
                    list.add(item);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            cursor.close();
            return list;
        }
    

    此处,CURD 雏形已成,扩展一下,将工厂类生产BaseDao的扩展下,传入俩泛型,M代表传入的User对象 T代表BaseDao,为了更灵活调用。

      public  <T extends BaseDao<M>,M> T  getBaseDao(Class<T> daoClass,Class<M> entityClass){
            BaseDao baseDao=null;
            try {
                baseDao=daoClass.newInstance();
                baseDao.init(sqLiteDatabase,entityClass);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return (T)baseDao;
        }
    

    记得测试下

    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            verifyStoragePermissions(this);
        }
    
        public void insertObject(View view) {
            IBaseDao baseDao = BaseDaoFactory.getOurInstance().getBaseDao(BaseDaoNewImpl.class, User.class);
            baseDao.insert(new User(6, "abcd", "123"));
            Toast.makeText(this, "执行成功!", Toast.LENGTH_SHORT).show();
        }
    
    
        private static final int REQUEST_EXTERNAL_STORAGE = 1;
        private static String[] PERMISSIONS_STORAGE = {
                "android.permission.READ_EXTERNAL_STORAGE",
                "android.permission.WRITE_EXTERNAL_STORAGE"};
    
    
        public static void verifyStoragePermissions(Activity activity) {
    
            try {
                //检测是否有写的权限
                int permission = ActivityCompat.checkSelfPermission(activity,
                        "android.permission.WRITE_EXTERNAL_STORAGE");
                if (permission != PackageManager.PERMISSION_GRANTED) {
                    // 没有写的权限,去申请写的权限,会弹出对话框
                    ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public void updateObject(View view) {
            BaseDaoNewImpl baseDao = BaseDaoFactory.getOurInstance().getBaseDao(BaseDaoNewImpl.class, User.class);
            //update tb_user where name='jett' set password='1111'
            User user = new User();
            user.setName("abcd");
            User where = new User();
            where.setId(6);
            baseDao.update(user, where);
            Toast.makeText(this, "执行成功!", Toast.LENGTH_SHORT).show();
        }
    
        public void deleteObject(View view) {
            BaseDao baseDao = BaseDaoFactory.getOurInstance().getBaseDao(BaseDaoNewImpl.class, User.class);
            User where = new User();
            where.setName("abcd");
            where.setId(6);
            baseDao.delete(where);
        }
    
        public void queryObject(View view) {
            BaseDaoNewImpl baseDao = BaseDaoFactory.getOurInstance().getBaseDao(BaseDaoNewImpl.class, User.class);
            User where = new User();
            where.setName("abcd");
            List<User> list = baseDao.query(where);
            Log.i("jett", "listsize=" + list.size());
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i) + " i=" + i);
            }
        }
    }
    

    数据库Demo:链接:https://pan.baidu.com/s/1SHTcCgzXpFkNd-ZHRrmZgg 密码:hohw

    • 多用户分库

    接下来,我们设计一个多用户分库功能。就是说每一个用户数据库都是独立的,这些大厂设计都是这样的,每一个用户对应不同数据库。

    首先 为了方便BaseDao不生成多个实例,我们把原本生成数据库实例的方法改下

    ////设计一个数据库连接池                                                                                       
    private Map<String, BaseDao> hashMap = Collections.synchronizedMap(new HashMap<String, BaseDao>());  
    
     public <T extends BaseDao<M>, M> T getBaseDao(Class<T> daoClass, Class<M> entityClass) {      
         BaseDao baseDao = null;                                                                   
         try {                                                                                     
             if (hashMap.get(daoClass.getSimpleName()) != null) {                                  
                 return (T) hashMap.get(daoClass.getSimpleName());                                 
             }                                                                                     
             baseDao = BaseDao.class.newInstance();                                                
             baseDao.init(sqLiteDatabase, entityClass);                                            
             hashMap.put(daoClass.getSimpleName(), baseDao);                                       
         } catch (InstantiationException e) {                                                      
             e.printStackTrace();                                                                  
         } catch (IllegalAccessException e) {                                                      
             e.printStackTrace();                                                                  
         }                                                                                         
         return (T) baseDao;                                                                       
     }                                                                                             
    

    分库的实现步骤

    • 获取当前登录用户 以及重写一个插入方法(此方法可在新用户登录时候调用 把其余用户状态设置离线状态 新用户为在线状态)
    public class UserDao extends BaseDao<User> {
        @Override
        public long insert(User entity) {
            //查询表中所有的用户记录
            List<User> list = query(new User());
            User where = null;
            for (User user : list) {
                where = new User();
                where.setId(user.getId());
                user.setStatus(0);
                Log.i("lcx", "用户" + user.getName() + "更改为未登录状态");
                update(user, where);
            }
            Log.i("lcx", "用户" + entity.getName() + "登录");
            entity.setStatus(1);
            return super.insert(entity);
        }
    
        /**
         * 得到当前的登录用户
         */
        public User getCurrLoginUser() {
            User user = new User();
            user.setStatus(1);
            List<User> list = query(user);
            if (list.size() > 0) {
                return list.get(0);
            }
            return null;
        }
    }
    
    • 定义一个枚举类 用来产生当前用户的数据库地址
    用于产生私有数据库在存放位置
     /**
     * 用于产生私有数据库在存放位置
     */
    public enum PrivateDataBaseEnums {
        database("");
        private String value;
    
        PrivateDataBaseEnums(String value) {
    
        }
    
        //用于产生路径
        public String getValue() {
            UserDao userDao = BaseDaoFactory.getOurInstance().getBaseDao(UserDao.class, User.class);
            if (userDao != null) {
                User currUser = userDao.getCurrLoginUser();
                if (currUser != null) {
                    File sdcardDir = Environment.getExternalStorageDirectory();
                    //得到一个路径,内容是sdcard的文件夹路径和名字
                    String path = sdcardDir.getPath() + "/dbImage";
                    File file = new File(path);
    //                File file = new File("/data/data/com.example.a48608.ls4_databaseframework_20180307");
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    ///data/data/com.example.a48608.ls4_databaseframework_20180307/n0003_login.db
                    return file.getAbsolutePath() + "/" + currUser.getId() + "_login.db";
                }
            }
            return null;
        }
    }
    
    • 定义一个工厂类 生产具体用户的数据库信息
        //这个用来生成不同对象的数据库地址
        public <T extends BaseDao<M>, M> T getSubDao(Class<T> daoClass, Class<M> entityClass) {
            BaseDao baseDao=null;
            if(hashMap.get(PrivateDataBaseEnums.database.getValue())!=null){
                return (T) hashMap.get(PrivateDataBaseEnums.database.getValue());
            }
            Log.i("jett","生成数据库文件的位置:"+PrivateDataBaseEnums.database.getValue());
            subSqliteDatabase=SQLiteDatabase.openOrCreateDatabase(PrivateDataBaseEnums.database.getValue(),null);
            try {
                baseDao=daoClass.newInstance();
                baseDao.init(subSqliteDatabase,entityClass);
                hashMap.put(PrivateDataBaseEnums.database.getValue(),baseDao);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            return (T) baseDao;
        }
    

    测试

     BaseDao userDao;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            userDao = BaseDaoFactory.getOurInstance().getBaseDao(UserDao.class, User.class);
        }
    
    /*模拟用户登录的  此处的insert是UserDao的insert  就是说把当前用户User为在线状态 其余为离线状态**/
       public void clickLogin(View view) {
            //服务器传回的信息
            User user = new User();
            user.setName("张三" + (++i));
            user.setPassword("123456");
            user.setId("N00" + i);
            //数据插入
            userDao.insert(user);
            Toast.makeText(this, "执行成功!", Toast.LENGTH_SHORT).show();
    
        }
    /*执行这一步之前 我们已经知道了 当前用户,也已经实例化了UserDAO,那么根据这两点 执行枚举方法 得到当前用户数据库地址,然后打开或者创建当前用户数据库, 并且初始化。  接下来进行一个新增动作  就可以查看当前用户的数据库插入的表数据*/
     public void clickSubInsert(View view) {
            Photo photo = new Photo();
            photo.setPath("data/data/my.jpg");
            photo.setTime(new Date().toString());
            PhotoDao photoDao =  BaseDaoSubFactory.getOurInstance().getSubDao(PhotoDao.class, Photo.class);
            photoDao.insert(photo);
            Toast.makeText(this, "执行成功!", Toast.LENGTH_SHORT).show();
        }
    

    相关文章

      网友评论

        本文标题:android自己动手封装Sqllite数据库

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