2014-10-27Android学习------SQLite数据库操作(二)-----数据库的创建--SQLiteHelper extends SQLiteOpenHelper

2022-03-07 08:39:20 浏览数 (1)

上篇有篇文章讲了数据库的操作 条件是:数据库已经建好的了,我们只需要从里面获取数据(查询)就可以了,

现在我们来看看第二种数据库的操作:

class SQLiteHelper extends SQLiteOpenHelper

封装一个继承SQLiteOpenHelper类的数据库操作类。SQLiteOpenHelper类是一个抽象的辅助类,主要用来生成一个数据库并对数据库的版本进行管理,在SQLiteOpenHelper类的构造方法中分别传入Context、数据库名称,CursorFactory(一般传入null,否则为默认数据库),数据库版本号(不能为负数)。

在SQLiteOpenHelper中首先执行的是onCreate方法(当数据库第一次创建时),一般在这个方法里生成数据表。

要注意的是,在构造函数时并没有真正创建数据库,而是在调用getWriteableDatabase()或者getReadableDatabase()方法的时候系统才会真正创建数据库,

如果当时系统中不存在这个数据库,系统会自动生成一个数据库,然后返回SQLiteDatabase对象。

在继承这个类的时候,要实现里面的3个方法,其中前两个方法是必须重写的。

/** * 创建表 */ @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL("CREATE TABLE IF NOT EXISTS " TB_NAME "(" CityBean.ID " integer primary key," CityBean.CITY " varchar," CityBean.CODE " integer" ")"); } /** * 当检测与前一次创建数据库版本不一样时,先删除表再创建新表 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub db.execSQL("DROP TABLE IF EXISTS " TB_NAME);// 先删除表 onCreate(db);//再创建表 } 还有个onOpen(SQLiteDatabase db) 这个函数是:打开数据库时的回调函数,一般不会用到

该类的源代码如下:

代码语言:javascript复制
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class SQLiteHelper extends SQLiteOpenHelper {
	
	public static final String TB_NAME = "citys";

	public SQLiteHelper(Context context, String name, CursorFactory factory,
			int version) {
		// version  就是 数据库的版本号
		super(context, name, factory, version);
		// TODO Auto-generated constructor stub
	}

	/**
	 * 创建表
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL("CREATE TABLE IF NOT EXISTS "  
				TB_NAME   "("  
				CityBean.ID   " integer primary key,"  
				CityBean.CITY   " varchar,"   
				CityBean.CODE   " integer" 
				")");

	}

	/**
	 * 当检测与前一次创建数据库版本不一样时,先删除表再创建新表
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		db.execSQL("DROP TABLE IF EXISTS "   TB_NAME);// 先删除表
		onCreate(db);//再创建表
	}
	
	
	/**
	 * 变更列名
	 * @param db
	 * @param oldColumn
	 * @param newColumn
	 * @param typeColumn
	 */
	public void updateColumn(SQLiteDatabase db, String oldColumn, String newColumn, String typeColumn){
		try{
			db.execSQL("ALTER TABLE "  
					TB_NAME   " CHANGE "  
					oldColumn   " "  newColumn  
					" "   typeColumn
			);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}

使用这个类:

当我们在一个activity类中使用这个数据库的时候 步奏如下:

1.必须先定义一个类的成员变量 申明数据库名字 声明数据库的版本号 声明一个查询结果游标 申明一个数据库对象

private static String DB_NAME = "mycity.db";//数据库名字 private static int DB_VERSION = 1;//数据库版本号 private Cursor cursor;//查询结果游标集 private SQLiteDatabase db;//打开数据库返回对象 private SQLiteHelper dbHelper;//数据库操作类

2.在一个activity的onCreate(Bundle)里面初始化和使用上面的变量

try{ /* 初始化并创建数据库 */ dbHelper = new SQLiteHelper(this, DB_NAME, null, DB_VERSION); /* 创建表 */ db = dbHelper.getWritableDatabase(); //调用SQLiteHelper.OnCreate() /* 查询表,得到cursor对象 */ cursor = db.query(SQLiteHelper.TB_NAME, null, null, null, null, null, CityBean.CODE " DESC"); cursor.moveToFirst(); while(!cursor.isAfterLast() && (cursor.getString(1) != null)){ CityBean city = new CityBean(); city.setId(cursor.getString(0)); city.setCity(cursor.getString(1)); city.setCode(cursor.getString(2)); cityList.add(city); cursor.moveToNext(); } }catch(IllegalArgumentException e){ //当用SimpleCursorAdapter装载数据时,表ID列必须是_id,否则报错column '_id' does not exist e.printStackTrace(); //当版本变更时会调用SQLiteHelper.onUpgrade()方法重建表 注:表以前数据将丢失 DB_VERSION; dbHelper.onUpgrade(db, --DB_VERSION, DB_VERSION); }

3.在函数中使用:

查询:

cursor = db.query(true, SQLiteHelper.TB_NAME, new String[]{CityBean.ID, CityBean.CITY, CityBean.CODE}, sql, null, null, null, null, null);

添加:

Long cityID = db.insert(SQLiteHelper.TB_NAME, CityBean.ID, values); 插入成功的话会返回一个值

修改:

db.update(SQLiteHelper.TB_NAME, values, CityBean.ID "=" cityList.get(POSTION).getId(), null);

删除:

db.delete(SQLiteHelper.TB_NAME, CityBean.ID "=" view.getId(), null);

4.在activity销毁之后需要关闭数据库的:

在activity的生命周期函数onDestroy()里面加上下面的代码

@Override protected void onDestroy() { db.delete(SQLiteHelper.TB_NAME, null, null); super.onDestroy(); }

至此 一个简单的数据库操作基本完成了,下面我们来看看需要掌握的知识:

Android中每一个数据库对创建它的应用程序包套件来说都是私有的,默认情况下其他应用程序无法直接访问此私有数据库。所有的数据库文件存放在手机中的/data/data/package_name/databases路径下,以下是常用的与数据库相关的函数:

那么我们首先需要学习一下数据库的 创建函数 打开函数 关闭函数

返回值

函数

备注

static SQLiteDatabase

create(SQLiteDatabase.CursorFactory factory)

创建一个数据库 factory:可选的数据库游标工厂类,当查询(query)被提交时,该对象会被调用来实例化一个游标。

static SQLiteDatabase

openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags)

根据提供的模式打开一个数据库 path:打开或创建的数据库文件 factory:可选的数据库游标工厂类,当查询(query)被提交时,该对象会被调用来实例化一个游标。默认为null。 flags:控制数据库的访问模式。主要有以下几种模式: l OPEN_READWRITE l OPEN_READONLY l CREATE_IF_NECESSARY l NO_LOCALIZED_COLLATORS

static SQLiteDatabase

openOrCreateDatabase(File file, SQLiteDatabase.CursorFactory factory)

等同于openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY)

static SQLiteDatabase

openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory)

等同于openDatabase(path,factory, CREATE_IF_NECESSARY)

void

close()

关闭数据库

boolean

deleteDatabase(String name)

删除指定的数据库 name:要关闭的数据库的名字

上面表格里面的有些参数请看我的上面一篇文章 地址: http://blog.csdn.net/u014737138/article/details/40618003

这些函数的使用方法:

代码语言:javascript复制
//创建数据库

SQLiteDatabase mydataBase=SQLiteDatabase.create(new CursorFactory(){

//工厂类,一个可选工厂类,当查询时调用来实例化一个游标

@Override

public Cursor newCursor(SQLiteDatabase db,

SQLiteCursorDriver masterQuery, String editTable,

SQLiteQuery query) {

// TODO Auto-generated method stub

return null;

}

});

//创建或打开数据库

SQLiteDatabase myDataBase=this.openOrCreateDatabase("myDataBase.db",

MODE_PRIVATE, new CursorFactory(){

//创建新的数据库,名称myDatabase,模式MODE_PRIVATE,可选的游标工厂类

@Override

public Cursor newCursor(SQLiteDatabase db,

SQLiteCursorDriver masterQuery, String editTable,

SQLiteQuery query) {

// TODO Auto-generated method stub

return null;

}

});

SQLiteDatabase myDataBase=this.openOrCreateDatabase("myDataBase.db",MODE_PRIVATE,null);

//关闭数据库

myDataBase.close();

//删除指定名称的数据库

this.deleteDatabase(“myDatabase.db”);

2.对数据库表的操作 主要是建表:这个是一个非查询操作 一般使用execSQL(sql)命令来执行

在对数据库中的表进行相关操作时,可以使用非查询的execSQL(String sql)来执行。示例代码如下:

String CREATE_TABLE = “create table table1 (_id integer primary key autoincrement,number integer,data text)”; //创建表

myDataBase.execSQL(CREATE_TABLE); 1)对表的插入操作:

long insert(String table, String nullColumnHack, ContentValues values) 向表中插入一条数据 参数: table:想要插入数据的表名 nullColumnHack:SQL不允许插入空行,初始化值为空时,这一列将会被显示地赋一个null值 values:要插入的值,类型为ContentValues

ContentValues主要是存放表中的数据段,以及其对应的值,与map一样采用名值对的形式存储,但是它存储的名值对中,名是一个String类型,值是基本数据类型。其使用示例如下:简单的理解他就是键值对,跟map一样,如果你看源代码,它其实就是继承他们并实现的。

ContentValues args = new ContentValues(); args.put(KEY_TITLE, title); args.put(KEY_BODY, body); myDataBase.update(DATABASE_TABLE, args, KEY_ROWID "=" rowId, null);

2)对表的更新 修改操作

int update(String table, ContentValues values, String whereClause, String[] whereArgs) 修改表中的数据 table:想要修改数据的表名 values:要更新的值,使用方法看上面的例子 whereClause:可选的where子句,如果其值为null,将会修改所有的行。 whereArgs:当在whereClause中包含”?”时,如果whereArgs的值不为null,则这个数组中的值将依次替换whereClause中出现的”?” ?就是写sql语句占位符

3)删除一行数据

int delete(String table, String whereClause, String[] whereArgs) 从表中删除一行数据 table:想要删除数据的表名 whereClause:可选的where子句,如果其值为null,将会删除所有的行。 whereArgs:当在whereClause中包含”?”时,如果whereArgs的值不为null,则这个数组中的值将依次替换whereClause中出现的”?”

4)查询表操作

Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) 查询数据表 table:要查询数据的表名 columns:要返回的列的列名数组 selection:可选的where子句 ,如果其值为null,将会返回所有的行 selectionArgs:当在selection中包含”?”时,如果selectionArgs的值不为null,则这个数组中的值将依次替换selection中出现的”?” groupBy:可选的group by子句,如果其值为null,将不会对行进行分组 having:可选的having子句,如果其值为null,将会包含所有的分组 orderBy:可选的order by子句,如果其值为null,将会使用默认的排序规则 limit:可选的limit子句,如果其值为null,将不会包含limit子句

3.关于游标Cursor学习:

Android采用游标对从数据库中查询出来的结果进行随机的读写访问,在查询数据库后,将结果返回给游标(即android.database.Cursor),这是查询结果的记录集,示意图如下:

_id

someNumber

1

8

2

10

3

2

Cursor类常见的方法如下:

返回值

函数

备注

boolean

move(int offset)

以当前位置为参考,将Cursor移动指定数目的位置(相对位置)

boolean

moveToPosition(int position)

将Cursor移动到指定位置(绝对位置)

boolean

moveToNext()

将Cursor向前移动一个位置

boolean

moveToLast()

将Cursor向后移动一个位置

boolean

moveToFirst()

将Cursor移动到第一行

boolean

isBeforeFirst()

返回Cursor是否指向第一项数据之前

boolean

isAfterLast()

返回Cursor是否指向最后一项数据之后

boolean

isClosed()

返回Cursor是否关闭

boolean

isFirst()

返回Cursor是否指向第一项数据

boolean

isLast()

返回Cursor是否指向最后一项数据

boolean

isNull(int columnIndex)

返回指定位置的值是否为null

int

getCount()

返回总的项目总数

int

getInt(int columnIndex)

返回指定列中的数据的int型表示

int

getColumnIndex(String columnName)

按给定的列的名字返回列的索引值,如果不存在则返回 -1

特别提示:

要创建一个Cursor(游标),必须执行一个查询,通过SQL使用rawQuery()方法或是更精心的query()方法,而不能使用execSQL(String sql)【戴帽子】方法。以下为Cursor的使用示例:

Cursor cur=myDataBase.rawQuery("select * from test", null);

if(cur!=null){//游标不为空

//返回给定名称的列的基于0开始的index,如果该属性列不存在则返回-1

//通过它们的index来检索属性值

int numColumn=cur.getColumnIndex("someNumber");

if(cur.moveToFirst()){ //cur.moveToFirst()让游标指向第一行,如果游标指向第一行,则返回true

do {

int num=cur.getInt(numColumn);//获得当前行该属性的值

/*Cursor提供了不同的方法来回索不同的数据类型,例如getInt(int index)/getString(int index)等等*/

/*做一些事情*/

} while (cur.moveToNext());

/*游标移动到下一行,如果游标已经到达结果集中的最后,即没有行可以移动时,则返回false*/

//其他可能移动的是 moveToPrevious() 和moveToFirst()方法

}

}

至此数据库的函数基本学习了一篇,现在就是以后如何去熟练的使用它们了

最后还是总结下 public class SQLiteHelper extends SQLiteOpenHelper{}做法经常用到的两个函数:

返回值

函数

备注

public void

onCreate(SQLiteDatabase db)

在数据库第一次生成时会调用这个方法,一般我们在这个方法里生成数据表

public void

onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)

当数据库需要升级时,系统会自动调用这个方法,一般我们在这个方法里删除数据表,并建立新的数据表,并根据实际需求做其他的操作

public void

onOpen(SQLiteDatabase db)

这是打开数据库时的回调函数,一般不会用到

0 人点赞