美文网首页AndroidAndroid开发经验谈Android开发
SQLite数据库创建时自定义路径

SQLite数据库创建时自定义路径

作者: 奔跑的佩恩 | 来源:发表于2017-11-21 16:01 被阅读78次

    前言

    在新建数据库sqlite的时候,我们已经知道了数据库默认路径为

    /data/data/com.example.pei.textdemo/databases/test_demo.db
    

    那么,如果我们想在创建数据库时,自定义一个自己的路径该如何处理呢,需要涉及到三步

    • 自定义Context,重写sqlite存储路径
    • 修改继承于SQLiteOpenHelper的DBOpenHelper类
    • 数据库的调用
      下面就来讲讲具体操作。
    一.自定义Context,重写sqlite存储路径

    我们在创建数据库的时候,会涉及到一个类SQLiteOpenHelper,一般建数据库的时候,都要继承SQLiteOpenHelper实现一个自己的helper类,这里,我写一个自己的helper来继承SQLiteOpenHelper,部分代码如下:

    public class DBOpenHelper extends SQLiteOpenHelper{
    ......
    }
    

    然后在DBOpenHelper这个类中,我们会有两个构造方法

       public DBOpenHelper(Context context) {
            this(context, DB_NAME, null, 1);
            this.mContext= context;
        }
    
        public DBOpenHelper(Context context, String dbName, SQLiteDatabase.CursorFactory factory, int version) {
            super(context, dbName, factory, version);
        }
    

    其中 mContext为Context,Context类会涉及到sqlite的储存路径,为了自定义数据库路径,我们需要实现一个自己的context,来自定义数据库路径,然而Context有一个子类ContextWrapper,可以方便用户对Context进行自定义,看源码中ContextWrapper继承关系如下:

    
    /**
     * Proxying implementation of Context that simply delegates all of its calls to
     * another Context.  Can be subclassed to modify behavior without changing
     * the original Context.
     */
    public class ContextWrapper extends Context {
        Context mBase;
    
        public ContextWrapper(Context base) {
            mBase = base;
        }
    

    那么,我们就写一个类ContextWrapper来继承ContextWrapper实现自己的context,代码如下:

    package com.example.pei.textdemo.sqlite;
    
    import android.content.Context;
    import android.content.ContextWrapper;
    import android.database.DatabaseErrorHandler;
    import android.database.sqlite.SQLiteDatabase;
    
    import com.example.pei.textdemo.util.SDCardUtil;
    
    import java.io.File;
    
    /**
     * Title:
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/20
     */
    public class DataBaseContext extends ContextWrapper {
    
        private Context mContext;
    
        public DataBaseContext(Context context){
            super(context);
            this.mContext=context;
        }
    
        /**重写数据库路径方法**/
        @Override
        public File getDatabasePath(String name) {
    //        String path1= SDCardUtil.getDiskFilePath(name);
    //        String dirPath=path1.replace(name,"");
    
            String dirPath=SDCardUtil.getInnerSDCardPath();
    
            String path=null;
            File parentFile=new File(dirPath);
            if(!parentFile.exists()){
                parentFile.mkdirs();
            }
            String parentPath=parentFile.getAbsolutePath();
            if(parentPath.lastIndexOf("\\/")!=-1){
                path=dirPath + File.separator + name;
            }else{
                path=dirPath+name;
            }
            File file = new File(path);
    
            return file;
        }
    
        @Override
        public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
            return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), factory);
        }
    
        @Override
        public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
            return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name).getAbsolutePath(),factory,errorHandler);
        }
    
    }
    
    

    其中我们需要重写getDatabasePath(String name)方法来自定义自己的数据库存储路径,然后重写ContextWrapper 的两个openOrCreateDatabase方法,代码中SDCardUtil.getInnerSDCardPath()方法代码如下

      /**获取内置sdcard路径(数据会保存,应用删除的时候,数据不会被清理掉)**/
        public static String getInnerSDCardPath(){
            if(isSdcardExist()){
                //------/storage/emulated/0/
                return Environment.getExternalStorageDirectory() + File.separator;
            }
            return null;
        }
    
    二.编写继承于SQLiteOpenHelper的DBOpenHelper类

    我们需要用自己定义的DataBaseContext 来代替之前的 Context,代码如下:

    package com.example.pei.textdemo.sqlite;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    /**
     * Title:创建数据库
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/16
     */
    public class DBOpenHelper extends SQLiteOpenHelper{
    
        private static final String DB_NAME = "tf_demo.db";//数据库文件名
        private static SQLiteDatabase INSTANCE;
        private DataBaseContext mContext;
    
        public SQLiteDatabase getInstance(){
            if (INSTANCE == null) {
                INSTANCE = new DBOpenHelper(mContext).getWritableDatabase();
            }
            return INSTANCE;
        }
    
        public DBOpenHelper(Context context) {
            this(context, DB_NAME, null, 1);
            this.mContext= (DataBaseContext) context;
        }
    
        public DBOpenHelper(Context context, String dbName, SQLiteDatabase.CursorFactory factory, int version) {
            super(context, dbName, factory, version);
        }
    
    
        /**获取数据库路径**/
        public String getDBPath(){
            return mContext.getDatabasePath(DB_NAME).getAbsolutePath();
        }
    
        //首次创建数据库时调用,一般进行建库建表操作
        @Override
        public void onCreate(SQLiteDatabase db) {
            String createTable = "CREATE TABLE IF NOT EXISTS user(_id integer NOT NULL PRIMARY KEY AUTOINCREMENT,\n" +
                    "                                name text,\n" +
                    "                                sex text,\n" +
                    "                                age integer);";
            //创建表
            db.execSQL(createTable);
        }
    
        //当数据库的版本发生变化的时候会自动执行,禁止人为调用
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    
    }
    
    
    三.在DBHelper中调整DBOpenHelper的调用

    代码如下:

    package com.example.pei.textdemo.sqlite;
    
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    
    import com.example.pei.textdemo.app.AppContext;
    
    import java.util.List;
    
    /**
     * Title:数据库增删改查帮助类
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/16
     */
    public abstract class DBHelper {
    
        protected DBOpenHelper mDBOpenHelper;
    
        private DBOpenHelper getDBOpenHelper(){
            if(mDBOpenHelper==null){
    //            mDBOpenHelper=new DBOpenHelper(AppContext.getInstance());
                mDBOpenHelper=new DBOpenHelper(new DataBaseContext(AppContext.getInstance()));
            }
            return mDBOpenHelper;
        }
    
    
        /**获取数据库对象**/
        protected SQLiteDatabase getDateBase(){
            return getDBOpenHelper().getInstance();
        }
    
        /**关闭数据库**/
        protected void closeDB(){
            SQLiteDatabase db = getDateBase();
            if(db!=null){
                db.close();
            }
        }
    
        /**
         * 判断表是否存在
         * @param tableName:表名
         * @return
         */
        protected boolean isTableExist(String tableName){
            Cursor cursor = getDateBase().rawQuery("select name from sqlite_master where type='table';", null);
            while(cursor.moveToNext()){
                //遍历出表名
                String name = cursor.getString(0);
                if(name.equals(tableName)){
                    return true;
                }
            }
            return false;
        }
    
        /**查询**/
        protected abstract List<?> checkAll();
        /**添加**/
        protected abstract void insert(Object obj);
        /**删除**/
        protected abstract void delete(Object obj);
        /**更新**/
        protected abstract void update(Object obj);
    }
    
    

    然后,写一个自己的UserDBHelper类去继承DBHelper,来实现具体的增删改查,就可以愉快的调用了,以下是我写的一个UserDBHelper范例:

    public class UserDBHelper extends DBHelper{
    
        private UserDBHelper() {
        }
    
        private static class Holder {
            private static UserDBHelper instance = new UserDBHelper();
        }
    
        public static UserDBHelper getInstance() {
            return Holder.instance;
        }
    
        @Override
        protected List<Person> checkAll() {
                List<Person> list = new ArrayList<>();
                //COLLATE NOCASE 忽略大小写查询
    //            Cursor cursor = getDateBase().rawQuery("select * from T_cpz where isqy='True' COLLATE NOCASE;", null);
                Cursor cursor = getDateBase().rawQuery("select * from user", null);
                while (cursor.moveToNext()) {
                    String name = cursor.getString(cursor.getColumnIndex("name"));
                    String sex = cursor.getString(cursor.getColumnIndex("sex"));
                    int age=cursor.getInt(cursor.getColumnIndex("age"));
    
                    Person person=new Person();
                    person.setName(name);
                    person.setSex(sex);
                    person.setAge(age);
                    list.add(person);
                }
                cursor.close();
            return list;
        }
    
        @Override
        protected void insert(Object obj){
            Person person= (Person) obj;
            String sql="INSERT INTO user(name,sex,age) VALUES('"+ person.getName()+"','"+ person.getSex()+"','"+ person.getAge()+"');";
            getDateBase().execSQL(sql);
        }
    
        @Override
        protected void delete(Object obj) {
            Person person = (Person) obj;
            String sql = "DELETE FROM user WHERE name='" + person.getName() + "';";
            getDateBase().execSQL(sql);
        }
    
        @Override
        protected void update(Object obj) {
            Person person = (Person) obj;
            String sql="UPDATE user SET age="+person.getAge()+" WHERE name='"+person.getName()+"';";
            getDateBase().execSQL(sql);
        }
    
    }
    

    然后在activity中,你可以这样获取数据库存储路径

      String dbPath=UserDBHelper.getInstance().getDataBasePath();
      LogUtil.e("=====dbPath===000=="+dbPath);
    

    当然,由于你自定义路径会涉及到存储的读写问题,所以要在mainfast总增加相应权限:

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    还要在代码中添加Android7.0以上权限,关于代码授权,这里就不做介绍了。

    ok,关于sqlite自定义数据库路径,今天就讲到这里了,谢谢!

    相关文章

      网友评论

        本文标题:SQLite数据库创建时自定义路径

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