Android数据存储
第一部分Android数据库编程
sqlite数据库,专门用于处理数据量较大的数据。sqlite他是一款轻型数据库。其特点:
1.轻量级
sqlite他是进程内的数据库引擎,因此不存在数据库的客户端和服务器。使用时只需带上它的一个动态库,就可用使用其全部功能,且动态库尺寸也很小。
2.独立性
sqlite数据库不依赖第三方软件,使用他不需要安装。
3.隔离性
sqlite数据库中所有的信息(如 表,视图,触发器)都包含在一个文件内,方便管理和维护。
4.跨平台
sqlite在很多系统上都可运行。
5.多语言接口
sqlite数据库支持多语言编程接口,如:C/C++,JAVA等。
6.安全性
sqlite数据库通过数据库级上的独占性和共享锁来实现独立事务处理。就是说多个进程在同一时间可以从同一数据库读取数据,但只有一个可以写入。在某个进程或线程
向数据库执行写入之前,必须获得独占锁定。在发出独占锁定后,其他的读或写操作将不会再发生。
sqlite数据库的基本操作包括:创建数据库,打开数据库,创建表,向表中添加数据,从表中删除数据,修改表中的数据,关闭数据库,删除指定表,删除数据库,和查询表中的
某条数据。下面有一例子。
public class Activity01 extends Activity{
private static intmiCount= 0;
private sqliteDatabasemsqliteDatabase= null;//数据库对象
private final static StringDATABASE_NAME= "Examples_06_05.db";//数据库名
private final static StringTABLE_NAME= "table1";//表名
/* 表中的字段 */
private final static StringTABLE_ID= "_id";
private final static StringTABLE_NUM= "num";
private final static StringTABLE_DATA= "data";
/* 创建表的sql语句 */
private final static StringCREATE_TABLE= "CREATE TABLE " + TABLE_NAME + " (" + TABLE_ID + " INTEGER PRIMARY KEY," + TABLE_NUM + " INTERGER,"+ TABLE_DATA + " TEXT)";
LinearLayoutm_LinearLayout= null;//线性布局
ListViewm_ListView= null;//用列表ListView视图-显示数据库中的数据
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
m_LinearLayout = new LinearLayout(this);
/* 设置布局LinearLayout的属性 */
m_LinearLayout.setOrientation(LinearLayout.VERTICAL);
m_LinearLayout.setBackgroundColor(android.graphics.Color.BLACK);
/* 创建ListView对象 */
m_ListView = new ListView(this);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
m_ListView.setBackgroundColor(Color.BLACK);
/* 添加m_ListView到m_LinearLayout布局 */
m_LinearLayout.addView(m_ListView,param);
/* 设置显示m_LinearLayout布局 */
setContentView(m_LinearLayout);
// 创建或打开已经存在的数据库。在Android中创建和打开一个数据库都可以用openOrCreateDatebase方法来完成因它会去自动检测是否存在这个数据库,如果存
在则打开,如果不存在则创建一个数据库;创建成功则返回一个sqliteDatabase对象
msqliteDatabase = this.openOrCreateDatabase(DATABASE_NAME,MODE_PRIVATE,null);
try{
msqliteDatabase.execsql(CREATE_TABLE);//在数据库msqliteDatabase中创建一个表.利用sql语句创建数据中的一个表。一个数据库中可以包含多个表,我们的
每一条数据保存在一个指定的表中,可以通过execsql方法来完成。
}catch (Exception e){
UpdataAdapter();
}
}
public boolean onKeyUp(int keyCode,KeyEvent event){
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_LEFT:
AddData();
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
DeleteData();
break;
case KeyEvent.KEYCODE_1:
UpData();
break;
case KeyEvent.KEYCODE_2:
DeleteTable();
break;
case KeyEvent.KEYCODE_3:
DeleteDataBase();
break;
}
return true;
}
public void DeleteDataBase(){//删除数据库可直接调用deleteDataBase方法
this.deleteDatabase(DATABASE_NAME);
this.finish();
}
public void DeleteTable(){//删除指定表此处使用了execsqlite方法
msqliteDatabase.execsql("DROP TABLE " + TABLE_NAME);
this.finish();
}
public void UpData(){//修改表中数据
ContentValues cv = new ContentValues();
cv.put(TABLE_NUM,miCount);
cv.put(TABLE_DATA,"修改后的数据" + miCount);
msqliteDatabase.update(TABLE_NAME,cv,TABLE_NUM + "=" + Integer.toString(miCount - 1),null);//使用update方法来更新一天数据。此处修改了TABLE_NUM值为
miCount-1的数据。
UpdataAdapter();
}
public void AddData(){//向表中添加一条数据.使用insert方法添加数据,但使用此方法时要把数据打包到ContentValues中。ContentValues其实就是一个Map,Key值是字段
名称,Value值是字段的值。通过ContentValues的put方法可以把数据放到ContentValues对象中去。
ContentValues cv = new ContentValues();
cv.put(TABLE_NUM,"测试数据库数据" + miCount);
msqliteDatabase.insert(TABLE_NAME,null,cv);//使用insert方法插入数据。也可使用execsql方法插入代码如:
String INSERT_DATA = "INSERT INTO table1(_id,num,data) values(1,1,‘通过sql语句插入’)";
msqliteDatabase.insert(INSETR_DATA);
miCount++;
UpdataAdapter();
}
public void DeleteData(){//从表中删除指定的一条数据
msqliteDatabase.execsql("DELETE FROM " + TABLE_NAME + " WHERE _id=" + Integer.toString(miCount));//此处通过execsqlite方法来删除字段为miCount+1的数据。也可使用delete方法删除如:
msqliteDatabase.delete("Examples_06_05.db","WHERE _id"+0,null);此处删除了字段等于1的数据
miCount--;
if (miCount < 0){
miCount = 0;
}
UpdataAdapter();
}
public void UpdataAdapter(){//更新视图显示
// 获取数据库Phones的Cursor,Cursor对象指向的是每一条数据
Cursor cur = msqliteDatabase.query(TABLE_NAME,new String[] { TABLE_ID,TABLE_NUM,TABLE_DATA },null);
miCount = cur.getCount();
if (cur != null && cur.getCount() >= 0){
ListAdapter adapter = new SimpleCursorAdapter(this,// ListAdapter是ListView和后台数据的桥梁
// 定义List中每一行的显示模板
android.R.layout.simple_list_item_2,// 表示每一行包含两个数据项
cur,// 数据库的Cursor对象
new String[] { TABLE_NUM,// 从数据库的TABLE_NUM和TABLE_DATA两列中取数据
new int[] { android.R.id.text1,android.R.id.text2 });// 与NAME和NUMBER对应的Views
m_ListView.setAdapter(adapter);//将adapter添加到m_ListView中
}
}
public boolean onKeyDown(int keyCode,KeyEvent event){
if (keyCode == KeyEvent.KEYCODE_BACK){
msqliteDatabase.close();//使用sqlite数据库后要及时关闭,否则可能会抛出sqliteException异常
this.finish();
return true;
}
return super.onKeyDown(keyCode,event);
}
}
上例中没有涉及到查询表中数据
在Android中查询数据是通过Cursor类来实现的,当我们使用sqliteDatabase.query()方法时。得到的是一个Cursor对象,Cursor指向的是每一条数据。
下面为使用Cursor来查询数据库中的数据。
Cursor cur = msqliteDatabase.rawQuery("SELECT*FORM table",null);
if (cur !=null){
if(cur.moveToFirst()){
do{
int numColumn = cur.getColumnIndex("num");
int num = cur.getInt(numColumn);
}while(cur.moveToNext());
}
}
sqliteOpenHelper应用
为了能更好的管理和维护数据库,我们可以封装一个继承自sqliteOpenHelper类的数据库操作类。
public class MyDataBaseAdapter{
private static final StringTAG= "MyDataBaseAdapter";// 用于打印log
public static final StringKEY_ID= "_id";// 表中一条数据的名称
public static final StringKEY_NUM= "num";// 表中一条数据的内容
public static final StringKEY_DATA= "data";// 表中一条数据的id
private static final StringDB_NAME= "Examples_06_06.db";// 数据库名称为data
private static final StringDB_TABLE= "table1";// 数据库表名
private static final intDB_VERSION= 1;// 数据库版本
private ContextmContext= null;// 本地Context对象
//创建一个表的sql语句
private static final StringDB_CREATE= "CREATE TABLE " + DB_TABLE + " (" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NUM + " INTERGER,"+ KEY_DATA + " TEXT)";
private sqliteDatabasemsqliteDatabase= null;// 执行open()打开数据库时,保存返回的数据库对象
private DatabaseHelpermDatabaseHelper= null;// 由sqliteOpenHelper继承过来
public MyDataBaseAdapter(Context context){//构造函数-取得Context
mContext = context;
}
public void open() throws sqlException{// 打开数据库,返回数据库对象
mDatabaseHelper = new DatabaseHelper(mContext);
msqliteDatabase = mDatabaseHelper.getWritableDatabase();
}
public void close(){// 关闭数据库
mDatabaseHelper.close();
}
public long insertData(int num,String data){//插入一条数据
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NUM,num);
initialValues.put(KEY_DATA,data);
return msqliteDatabase.insert(DB_TABLE,KEY_ID,initialValues);
}
public boolean deleteData(long rowId){//插入一条数据
return msqliteDatabase.delete(DB_TABLE,KEY_ID + "=" + rowId,null) > 0;
}
public Cursor fetchAllData(){//通过Cursor查询所有数据
return msqliteDatabase.query(DB_TABLE,new String[] { KEY_ID,KEY_NUM,KEY_DATA },null);
}
public Cursor fetchData(long rowId) throws sqlException{//查询指定数据
Cursor mCursor = msqliteDatabase.query(true,DB_TABLE,null);
if (mCursor != null){
mCursor.moveToFirst();
}
return mCursor;
}
public boolean updateData(long rowId,int num,String data){//更新一条数据
ContentValues args = new ContentValues();
args.put(KEY_NUM,num);
args.put(KEY_DATA,data);
return msqliteDatabase.update(DB_TABLE,args,null) > 0;
}
/*
*此处封装了一个继承自sqliteOpenHelper类的数据库操作类。sqliteOpenHelper的构造方法中分别需要传入Context,数据库名称,CursorFactory(一般为null,否则为默认数据库
*,数据库的版本号(不能为负数),在sqliteOpenHelper中当数据库第一次被创建时首先执行的是onCreate方法。
/
private static class DatabaseHelper extends sqliteOpenHelper{
DatabaseHelper(Context context){//构造函数在此处并没有真正创建一个数据库,而是当调
用getWritableDatabase()或 getReadableDatabase()方法时,则创建一个数据库,并且返回一个sqliteDatabase对象
super(context,DB_NAME,DB_VERSION);
}
public void onCreate(sqliteDatabase db){//创建一个表
db.execsql(DB_CREATE);// 数据库没有表时创建一个,此处利用sql语句在数据库对象 db中创建了一个表
}
public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion){//升级数据库
db.execsql("DROP TABLE IF EXISTS notes");
onCreate(db);
}
}
}
如果使用上面封装的MyDataBaseAdapter类如下:
public class Activity01 extends Activity{
private static intmiCount= 0;
LinearLayoutm_LinearLayout= null;
ListViewm_ListView= null;//ListView显示数据库中的数据
MyDataBaseAdapter m_MyDataBaseAdapter;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
m_LinearLayout = new LinearLayout(this);//创建LinearLayout布局对象
m_LinearLayout.setOrientation(LinearLayout.VERTICAL);//设置布局LinearLayout的属性
m_LinearLayout.setBackgroundColor(android.graphics.Color.BLACK);
m_ListView = new ListView(this);//创建ListView对象
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
m_ListView.setBackgroundColor(Color.BLACK);
m_LinearLayout.addView(m_ListView,param);//添加m_ListView到m_LinearLayout布局 setContentView(m_LinearLayout);//设置显示m_LinearLayout布局 m_MyDataBaseAdapter = new MyDataBaseAdapter(this);//构造MyDataBaseAdapter对象 m_MyDataBaseAdapter.open();//取得数据库对象 UpdataAdapter(); } public boolean onKeyUp(int keyCode,KeyEvent event){ switch (keyCode){ case KeyEvent.KEYCODE_DPAD_LEFT: AddData(); break; case KeyEvent.KEYCODE_DPAD_RIGHT: DeleteData(); break; case KeyEvent.KEYCODE_1: UpData(); break; } return true; } public void UpData(){//更新一条数据 m_MyDataBaseAdapter.updateData(miCount - 1,miCount,"修改后的数据" + miCount); UpdataAdapter(); } public void AddData(){//向表中添加一条数据 m_MyDataBaseAdapter.insertData(miCount,"测试数据库数据" + miCount); miCount++; UpdataAdapter(); } public void DeleteData(){//从表中删除指定的一条数据 m_MyDataBaseAdapter.deleteData(miCount);//删除数据 miCount--; if (miCount < 0){ miCount = 0; } UpdataAdapter(); } public boolean onKeyDown(int keyCode,KeyEvent event){//按键事件处理 if (keyCode == KeyEvent.KEYCODE_BACK){ m_MyDataBaseAdapter.close();//退出时,不要忘记关闭 this.finish(); return true; } return super.onKeyDown(keyCode,event); } public void UpdataAdapter(){//更新视图显示 // 获取数据库Phones的Cursor Cursor cur = m_MyDataBaseAdapter.fetchAllData(); miCount = cur.getCount(); if (cur != null && cur.getCount() >= 0){ ListAdapter adapter = new SimpleCursorAdapter(this,// ListAdapter是ListView和后台数据的桥梁 // 定义List中每一行的显示模板 android.R.layout.simple_list_item_2,// 表示每一行包含两个数据项 cur,// 数据库的Cursor对象 new String[] {MyDataBaseAdapter.KEY_NUM,MyDataBaseAdapter.KEY_DATA },// 从数据库的TABLE_NUM和TABLE_DATA两列中取数据 new int[] { android.R.id.text1,android.R.id.text2 });// 与NAME和NUMBER对应的Views m_ListView.setAdapter(adapter);//将adapter添加到m_ListView中 } } }