android sqlite 自定义路径,SQLite数据库创建时自定义路径
前言
在新建数据库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:
*
* 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:
*
* 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:
*
* 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 checkAll() {
List 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总增加相应权限:
还要在代码中添加Android7.0以上权限,关于代码授权,这里就不做介绍了。
ok,关于sqlite自定义数据库路径,今天就讲到这里了,谢谢!
android sqlite 自定义路径,SQLite数据库创建时自定义路径相关推荐
- android自定义sqlite路径,SQLite数据库创建时自定义路径
前言 在新建数据库sqlite的时候,我们已经知道了数据库默认路径为/data/data/com.example.pei.textdemo/databases/test_demo.db 那么,如果我们 ...
- 在数据库创建时创建OMF(Oracle Managed Files,Oracle管理的文件)
CREATE DATABASE语句可以执行与OMF相关的行为. 1.在数据库创建时指定控制文件 在数据库创建时,控制文件使用初始化参数CONTROL_FILES指定的文件来创建. 如果参数CONTRO ...
- 服务器数据库怎么导入数据库文件路径,服务器数据库导入sql文件路径
服务器数据库导入sql文件路径 内容精选 换一换 下载MySQL源码包(includes Boost Headers).cd /home wget https://dev.mysql.com/get/ ...
- 修改mysql 视图字段类型_记一次mysql视图创建时自定义字段类型不同环境不同的原因...
由于老项目使用的是hibernate,当项目启动时会去检查数据库字段类型等,发现一张视图中某个自定义字段在开发环境中类型为text,但是到了生产环境类型却为mediumtext,导致代码在生产上会有问 ...
- nodejs 获取文件路径_Nodejs读取文件时相对路径的正确写法(使用fs模块)
在开发Nodejs中,我们往往最常用的模块就是fs核心模块(fs.readFile)来读取文件.代码如下: 但是运行之后,并没有按照想象中一样,读取test.html文件内容,这是一个bug,坑爹的玩 ...
- nodejs写html文件路径,Nodejs读取文件时相对路径的正确写法(使用fs模块)
搜索热词 在开发Nodejs中,我们往往最常用的模块就是fs核心模块(fs.readFile)来读取文件.代码如下: 但是运行之后,并没有按照想象中一样,读取test.html文件内容,这是一个bug ...
- mysql数据库保存图片路径_mysql数据库怎么存图片路径
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...
- 数据库种类 与 MySQL中数据库创建
目录 写在前面 数据库 什么是数据库 数据库的分类 关系型数据库(SQL) 关系型数据库的组成 非关系型数据库(NoSQL) 数据库的代表 SQL语言 SQL的特点 为何选择 MySQL数据库 MyS ...
- log4net配置自定义字段存入数据库
2019独角兽企业重金招聘Python工程师标准>>> 前言 以bs项目中引入log4net为例.log4net存入数据库提供了基本的(时间.线程.等级.message)字段. 但是 ...
最新文章
- 嵌入式linux学习笔记1—内存管理MMU之虚拟地址到物理地址的转化
- 干货:排名前 16 的 Java 工具类!
- 海量数据处理:两个大文件中的相同记录
- 服务器里的文件怎么实时更新,简单几步,利用Serverless,让COS中文件变更自动刷新CDN...
- python3 http.server 本地服务支持跨域
- win10配置mysql8.0_Win10下mysql 8.0.20 安装配置方法图文教程
- js基础知识温习:构造函数与原型
- Linux 命名空间
- python网络编程初级
- 最新!CVPR2020 最新论文下载!
- 大学生计算机考证时间表
- 产品生命周期管理PLM系统概述——睿思成研发管理咨询(www.wiserdm.com)
- LaTeX 文字带边框
- 论文参考文献尾注引用方法
- 06 第五章 一阶逻辑等值演算与推理
- PCB各层的含义(讲的非常易懂清晰)
- MT6575芯片原理图MT6575原理图及量产板
- 你们公司测试都用什么工具啊?
- ubuntu16.04 设置静态ip
- vs调试nuget包_高冷?孩子气?醋包?那不得是分对象啊
热门文章
- ajax动态选项卡,如何将动态生成的ajax内容附加到jquery ui选项卡中新添加的选项卡?...
- sql server agent无法启动_PF启动首次实体瘤患者W0180人体临床试验
- 之江汇空间如何加音乐背景_之江汇要怎么用?听听大咖怎么说!
- 理光Ricoh Fax SL350 一体机驱动
- AOC V24t最薄24英寸
- 云服务器信息泄露,云服务器数据泄露
- 2010年第二批中关村高端领军人才公示公告
- 西南石油大学计算机专业考研分数线,2020西南石油大学研究生分数线汇总(含2016-2020历年复试)...
- can总线用java怎么解析_CAN报文DBC解析的编程方法说明
- 感冒了吃抗生素有用吗?