您的位置:首页 > 数据库 > SQL

关于 SQLiteOpenHelper 的自创建数据库目录文件

2016-07-27 22:40 489 查看
在 android 中有个类可方便的直接创建数据库,自己写一个类继承 SQLiteOpenHelper
package com.wangban.yzbbanban.test_mysqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

/**
* Created by YZBbanban on 16/7/27.
*/

public class MySQLiteHelper extends SQLiteOpenHelper {
private Context context;

public MySQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
this.context = context;
}

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table Book(id integer primary key autoincrement,name text,price real)");
Toast.makeText(context, "创建完成", Toast.LENGTH_SHORT).show();
}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

}
}

代码很简单,传入一个 Context(此 Context 很重要),创建一个对象,传入参数:上下文对象,数据库文件名,游标工厂(一般不用,为 null),数据库版本号(可自定义),

重写 onCreate 的方法,方法的参数即为数据库引用,可用此引用创建数据库中的表单:exeSQL()方法创建表单数据,创建成功,Toast 提示一下,onUpgrade 表示,若版本号与之前的老版本号不一致,则执行此方法(在此不需要用)。至此一个 MySQLiteHelper类完成,用于创建数据库文件,以及表单。

现在进入正题,之前提到过构造方法的一个传入值Context,我们可以在源码中找到一个这样的类:ContextWrapper (继承自 Context)通过此类我们可以获得应用程序的资源和类,包括对Activity,Broadcast,Intent等的操做,比如 startActivity(),sendBroadcast()等,还有些设置方法,像是setWallpaper(),当然最主要是有关于数据存储的一切方法:文件存储(File),个性化存储(sharedPreferances),数据库 (SQLite)等,对于数据库的操作直接看源码: public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
throw new RuntimeException("Stub!");
}

public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler) {
throw new RuntimeException("Stub!");
}

public boolean moveDatabaseFrom(Context sourceContext, String name) {
throw new RuntimeException("Stub!");
}

public boolean deleteDatabase(String name) {
throw new RuntimeException("Stub!");
}

public File getDatabasePath(String name) {
throw new RuntimeException("Stub!");
}

public String[] databaseList() {
throw new RuntimeException("Stub!");
}
构造方法:

public class ContextWrapper extends Context {
public ContextWrapper(Context base) {
throw new RuntimeException("Stub!");
}

可以知道构造方法只有一个参数 Context,而且,在 SQLiteOpenHelper 中传入的 Context,也是在此调用的,其中的具体方法被SDK 隐藏了,所以看不到,只有抛出异常,但是可以了解到:所以在创建数据库时需要传入一个参数:Context, 其中getDatabasePath() 为创建数据库路径,OpenOrCreateDatebase ()为创建数据库,所以也可以确认的是,在 SQLiteOpenHelper 中的子类,调用getReadableDatabase()生成数据库文件表单时也调用了OpenOrCreateDatebase
(),同样传入参数也是 Context,(只是默认路径在该程序的数据库文件夹里(data/data/~~)),所以我们只要重写了 ContextWrapper 方法,并重写其中的 OpenCreateDatebase(),与 getDatabasePath()方法即可创建所需要的数据库目录与数据库表单,下面是代码:
package com.wangban.yzbbanban.test_mysqlite;

import android.content.Context;
import android.content.ContextWrapper;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import java.io.File;
import java.io.IOException;

/**
* Created by YZBbanban on 16/7/27.
*/

public class MyContextWrapper extends ContextWrapper {
private Context mContext;
private String dirName;

/**
* 构造函数
*
* @param base
*			上下文环境
*/
public MyContextWrapper(Context base) {
super(base);
this.mContext = base;
}
/**
* 构造函数
* @param base
* @param dirName
*/
public MyContextWrapper(Context base, String dirName) {
super(base);
this.mContext = base;
this.dirName = dirName;
}

/**
* 获得数据库路径,如果不存在,则创建对象对象
*
* @param name
*/
@Override
public File getDatabasePath(String name) {
// 判断是否存在sd卡
boolean sdExist = android.os.Environment.MEDIA_MOUNTED
.equals(android.os.Environment.getExternalStorageState());
if (!sdExist) {// 如果不存在,
Log.e("SD卡管理:", "SD卡不存在,请加载SD卡");
return null;
} else {// 如果存在
// 获取sd卡路径
String dbDir = android.os.Environment.getExternalStorageDirectory()
.getAbsolutePath();
dbDir += "/" + ((dirName == null || "".equals(dirName)) ?
mContext.getPackageName() : dirName);// 数据库所在目录
String dbPath = dbDir + "/" + name;// 数据库路径
// 判断目录是否存在,不存在则创建该目录
File dirFile = new File(dbDir);
if (!dirFile.exists())
dirFile.mkdirs();

// 数据库文件是否创建成功
boolean isFileCreateSuccess = false;
// 判断文件是否存在,不存在则创建该文件
File dbFile = new File(dbPath);
if (!dbFile.exists()) {
try {
isFileCreateSuccess = dbFile.createNewFile();// 创建文件
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
isFileCreateSuccess = true;

// 返回数据库文件对象
if (isFileCreateSuccess)
return dbFile;
else
return null;
}
}

/**
* 重载这个方法,是用来打开SD卡上的数据库的,android 2.3及以下会调用这个方法。
*
* @param name
* @param mode
* @param factory
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
SQLiteDatabase.CursorFactory factory) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(
getDatabasePath(name), null);
return result;
}

/**
* Android 4.0会调用此方法获取数据库。
*
* @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String,
*	  int, android.database.sqlite.SQLiteDatabase.CursorFactory,
*	  android.database.DatabaseErrorHandler)
* @param name
* @param mode
* @param factory
* @param errorHandler
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(
getDatabasePath(name), null);
return result;
}
}
在 Activity 中创建 MySQLiteHelper()对象,并使用新的 Context 对象传入MySQLiteHelper的 onCreate() 方法中即可,下面是
Activity 代码:
package com.wangban.yzbbanban.test_mysqlite;

import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
private Button btnCreate;
private MySQLiteHelper helper;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCreate = (Button) findViewById(R.id.btn_create);
MyContextWrapper mContext = new MyContextWrapper(this, "Run");
helper = new MySQLiteHelper(mContext, "Book.db", null, 2);
setListeners();

}

private void setListeners() {
btnCreate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase db = helper.getWritableDatabase();
}
});
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.wangban.yzbbanban.test_mysqlite.MainActivity">

<TextView
android
ab57
:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
app:layout_constraintTop_toTopOf="@+id/activity_main"
app:layout_constraintRight_toRightOf="@+id/activity_main"
app:layout_constraintBottom_toBottomOf="@+id/activity_main" />

<Button
android:text="创建"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_create"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
app:layout_constraintTop_toTopOf="@+id/activity_main"
android:layout_marginTop="16dp"
app:layout_constraintRight_toRightOf="@+id/activity_main"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp" />

</android.support.constraint.ConstraintLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息