声明:学习的书籍《Android应用开发揭秘》,这里记录学习该书籍的日志,引用的相关代码与总结描述,没有商业的用途,完全是自我学习的一个记录,刚刚学习不可避免会出现很多问题,若是有错误还请大家多多批评。
之前已经学习了三种数据操作的方式,还有一种最为常用数据库操作,因为之前的三种数据方式一般只存储一些简单的,数据量较小的数据。如果数据量比较大,需要管理,维护与升级的话,就不能满足需要了。而sqlite数据库则提供这种问题的解决方案。关于为什么使用sqlite数据,网上也有很多关于sqlite数据的优点,简单说一下:
1、 轻量级,它是进程内的数据库引擎,不存在数据库客户端与服务器端。
2、 独立性,sqlite的核心引擎不依赖第三方软件,也不需要安装。
3、 隔离性,sqlite数据库中所有信息都存放在一个文件中,方便管理与维护。
5、 多语言接口,支持很多语言编程接口。
6、 安全性,sqlite数据库通过数据库级上的独占性和共享锁来实现独立事物处理。也就是能够满足同事多个线程同个时间从数据库中读取数据,但是只有一个是可写的。
数据库操作,无非就是针对数据的增删改查,以及表的创建于删除,下面例子中包含了以上操作。该实例默认会创建一data1数据库并且创建表table1,然后设定按键的监听,点击方向键左时会添加一条数据,方向键右会删除一条数据,数字键1为修改最后一条数据,数字键2为删除表,数字键3为删除数据库。
关键源码:
public class DatabaseDataActivity extends Activity { private static int count = 0; private sqliteDatabase sqliteDatabase = null; //数据库对象 private final static String DATABASE_NAME = "data1";//数据库名 private final static String TABLE_NAME = "table1"; //表名 private final static String TABLE_ID = "_id"; private final static String TABLE_NUM = "num"; private final static String TABLE_DATA = "data"; private final static String CREATE_TABLE = "Create table " + TABLE_NAME + " (" + TABLE_ID + " integer primary key," + TABLE_NUM + " integer," + TABLE_DATA + " Text)"; LinearLayout linearLayout = null; ListView listView = null; //用来显示数据库中得数据 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); linearLayout = new LinearLayout(this); linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setBackgroundColor(android.graphics.Color.BLACK); listView = new ListView(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT); listView.setBackgroundColor(Color.BLACK); linearLayout.addView(listView,params); setContentView(linearLayout); //设置显示linearLayout布局 sqliteDatabase = this.openOrCreateDatabase(DATABASE_NAME,MODE_PRIVATE,null); //打开或者创建数据库 try { sqliteDatabase.execsql(CREATE_TABLE); } catch (Exception e) { UpdataAdapter(); } } //更新并显示视图 private void UpdataAdapter() { // 获取数据库Phones的Cursor Cursor cur = sqliteDatabase.query(TABLE_NAME,new String[] { TABLE_ID,TABLE_NUM,TABLE_DATA },null,null); count = cur.getCount(); if (cur != null && cur.getCount() >= 0){ // ListAdapter是ListView和后台数据的桥梁 ListAdapter adapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_2,// 定义List中每一行的显示模板,表示每一行包含两个数据项 cur,// 数据库的Cursor对象 new String[] { TABLE_NUM,// 从数据库的TABLE_NUM和TABLE_DATA两列中取数据 new int[] { android.R.id.text1,android.R.id.text2 });// 与NAME和NUMBER对应的Views listView.setAdapter(adapter);/* 将adapter添加到m_ListView中 */ } } public boolean onKeyDown(int keyCode,KeyEvent event) { // TODO Auto-generated method stub if (keyCode == KeyEvent.KEYCODE_BACK){ sqliteDatabase.close(); this.finish(); return true; } return super.onKeyDown(keyCode,event); } 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; } //删除数据库 private void DeleteDataBase() { this.deleteDatabase(DATABASE_NAME); this.finish(); } //删除表 private void DeleteTable() { sqliteDatabase.execsql("DROP TABLE " + TABLE_NAME); this.finish(); } //更新数据 private void UpData() { ContentValues values = new ContentValues(); values.put(TABLE_NUM,count); values.put(TABLE_DATA,"修改后的数据"+count); //更新数据 sqliteDatabase.update(TABLE_NAME,values,TABLE_NUM + "=" +Integer.toString(count-1),null); UpdataAdapter(); } //删除数据 private void DeleteData() { // TODO Auto-generated method stub sqliteDatabase.execsql("delete from " + TABLE_NAME + " where _id = " + Integer.toString(count)); count--; if(count < 0){ count = 0; } UpdataAdapter(); } //添加数据 private void AddData() { // TODO Auto-generated method stub ContentValues cv = new ContentValues(); cv.put(TABLE_NUM,count); cv.put(TABLE_DATA,"测试数据库数据" + count); /* 插入数据 */ sqliteDatabase.insert(TABLE_NAME,cv); count++; UpdataAdapter(); } }
一般查看数据库可以先把该对应目录下得数据库文件导出后,使用sqliteSpy.exe工具来查看,数据库文件的存放地址与之前的数据操作的存储目录一致,数据库文件放在databases文件下。该工具可以到我的资源里去下载。
【遇到问题】
开始在创建表的时候,我设置的主键为ID,但是实际在运行示例的时候,总是报_ID找不到,比较纳闷,我没有建立这一列啊。后来发现,针对sqlite的表创建时必须_ID,因为底层类在找得时候,就是以_ID来找,改过来之后就可以运行了。
【扩展学习】游标Cursor的使用
关于 Cursor,在你理解和使用 Android Cursor 的时候你必须先知道关于 Cursor 的几件事情:
Cursor 是每行的集合。
使用 moveToFirst() 定位第一行。
你必须知道每一列的名称。
你必须知道每一列的数据类型。
Cursor 是一个随机的数据源。
所有的数据都是通过下标取得。
关于 Cursor 的重要方法:
close() —— 关闭游标,释放资源
copyStringToBuffer(int columnIndex,CharArrayBuffer buffer) —— 在缓冲区中检索请求的列的文本,将将其存储
getColumnCount() —— 返回所有列的总数
getColumnIndex(String columnName) —— 返回指定列的名称,如果不存在返回-1
getColumnIndexOrThrow(String columnName) —— 从零开始返回指定列名称,如果不存在将抛出IllegalArgumentException 异常。
getColumnName(int columnIndex) —— 从给定的索引返回列名
getColumnNames() —— 返回一个字符串数组的列名
getCount() —— 返回Cursor 中的行数
moveToFirst() —— 移动光标到第一行
moveToLast() —— 移动光标到最后一行
moveToNext() —— 移动光标到下一行
moveToPosition(int position) —— 移动光标到一个绝对的位置
moveToPrevIoUs() —— 移动光标到上一行
下面来看看一小段代码:
if (cur.moveToFirst() == false){
//为空的Cursor
return;
}
访问 Cursor 的下标获得其中的数据
int nameColumnIndex = cur.getColumnIndex(People.NAME);
String name = cur.getString(nameColumnIndex);
现在让我们看看如何循环 Cursor 取出我们需要的数据
while(cur.moveToNext()){
//光标移动成功
//把数据取出
}
当cur.moveToNext() 为假时将跳出循环,即 Cursor 数据循环完毕。
原文链接:https://www.f2er.com/sqlite/202414.html