Android中SQLite数据库介绍和使用

转载请注明出处:http://blog.csdn.net/yegongheng/article/details/38121557


SQLite简介

上一篇博文我们学习了Android几种简单的数据存储方式,SharedPreference存储和文件存储(其中又分为外部设备文件存储和内部设备文件存储),这些数据存储方式可以满足我们日常开发中存储少量数据的需求。那么,如果使用它们存储一些数据量较大并且逻辑关系较为复杂的数据集,它们便显得较为笨拙和效率低下。那有没有更好的存储方案来解决此类问题呢,还是只能选择忍受?放心,窝在Google的那一帮技术大牛早就考虑到这个问题,他们的解决方案是:为Android系统内置轻便又功能强大的嵌入式数据库--SQLite。今天我们将会深入地学习如何在Android中使用SQLite数据库存储数据,那在学习使用SQLite之前,我们现在简单了解一下SQLite数据库的特点。 SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎,它是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它的设计目标是嵌入式的,而且由于其占用资源低(占用内存只需几百K)、处理速度快等特点,目前许多嵌入式产品中都使用了它,其中就包括大名鼎鼎的iOS和Android移动操作系统。SQLite能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月, 至今已经有14个年头,现在SQLite也迎来了一个版本 SQLite 3已经发布。SQLite的特点大致总结如下: 1.轻量级
使用 SQLite 只需要带一个动态库,就可以享受它的全部功能,而且那个动态库的尺寸想当小。
2.独立性
SQLite 数据库的核心引擎不需要依赖第三方软件,也不需要所谓的“安装”。
3.隔离性
SQLite 数据库中所有的信息(比如表、视图、触发器等)都包含在一个文件夹内,方便管理和维护。
4.跨平台
SQLite 目前支持大部分操作系统,不至电脑操作系统更在众多的手机系统也是能够运行,比如:Android和IOS。
5.多语言接口
SQLite 数据库支持多语言编程接口。
6.安全性
SQLite 数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只能有一个可以写入数据。
要想了解更多有关SQLite数据库相关的历史、特点及命令操作,可以学习以下两个网站的资源: http://www.sqlite.org/lang.html http://www.w3cschool.cc/sqlite/sqlite-intro.html

在Android中使用SQLite实例

简单地了解了一下SQLite数据库后,我们再来学习一下如何在Android中编写应用程序来使用SQLite执行数据的CRUD操作。我们通过一个例子来完成我们的学习任务:大致要实现的功能就是将一些Person个人信息从SQLite数据库中的person表中查询出来并以列表的形式展现,然后可以对列表中的person信息进行修改和删除,并可以添加新的person信息数据库中。我们编写的程序列表及包图如下:
由于该例子中的类较多,且类和类之间的关系有点复杂,在这里我画一张简单的类图关系图,方便读者理解和学习。在这里特别声明一下,由于篇幅关系,不是每个类中的方法都在类图中声明了,具体的还要看Demo实例中的代码为准,我们主要是为了理清一下类与类之间的关系。类图图示如下:
整理好思路后,接下来我们来看下每个类中的具体代码是如何编写的。 那在实际的开发中,为了让我们更好的管理和维护SQLite数据库,Android提供了一个SQLiteOpenHelper类。我们需要定义一个继承自 SQLiteOpenHelper的子类(在实例中为DatabaseOpenHelper类),并在此类中重写onCreate()和onUpgrade()方法。下图列出了SQLiteOpenHelper所提供的一些方法和方法说明:
     /**   * 构造方法,一般是传递一个要创建的数据库名称那么参数 */public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,            DatabaseErrorHandler errorHandler)/** * 创建数据库时调用 */public void onCreate(SQLiteDatabase db)/** * 版本更新时调用 */public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)/** * 创建或打开一个读写数据库 */mDatabaseOpenHelper.getWritableDatabase();/** * 创建或打开一个只读数据库 */mDatabaseOpenHelper.getReadableDatabase();
从上面SQLiteOpenHelper类所提供的方法我们可知,该帮助类主要的作用是用于创建、打开数据库和定义数据库版本,并在数据库发生改变时更新一些数据库中的表信息。接下来我们编写具体的代码,代码列表如下:
/** * 该类是SQLiteDatabase的帮助类,主要管理数据库的创建和版本的更新 * @author AndroidLeaf * */@TargetApi(Build.VERSION_CODES.HONEYCOMB)public class DatabaseOpenHelper extends SQLiteOpenHelper {private static DatabaseOpenHelper mDatabaseOpenHelper;/** * 数据库版本号 */private static final int DATABASE_VERSION = 1;/** * 数据库名称 */private static final String DATABASE_NAME = "manager.db";/** * 定义一个事件监听回调,将创建表和更新数据库表的操作让子类实现 */public SQLiteDataTable mDataTable;public interface SQLiteDataTable{public void onCreate(SQLiteDatabase mSqLiteDatabase);public void onUpgrade(SQLiteDatabase mSqLiteDatabase);}public void setOnSQLiteDataTable(SQLiteDataTable mDataTable){this.mDataTable = mDataTable;}/** * 初始化数据库信息 * @param context 应用程序上下文 * @param name 数据库名称 * @param factory cursor工厂对象 * @param version 数据库版本号 * @param errorHandler 数据库错误处理对象 */public DatabaseOpenHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION, new DatabaseErrorHandler() {@Overridepublic void onCorruption(SQLiteDatabase dbObj) {// TODO Auto-generated method stub}});// TODO Auto-generated constructor stub}/** * 使用单例模式,获取数据库唯一实例 * @param mContext 应用程序上下文 * @return mDatabaseOpenHelper 该对象用于获取SQLiteDatabase实例 */public synchronized static DatabaseOpenHelper getDatabaseOpenHelper(Context mContext){if(mDatabaseOpenHelper == null){mDatabaseOpenHelper = new DatabaseOpenHelper(mContext);}return mDatabaseOpenHelper;} /** * 创建数据库时调用,一般执行创建表的操作 */@Overridepublic void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stub//创建一系列的数据库表mDataTable.onCreate(db);}/** * 当数据库需要修改的时系统会自动调用此方法。一般我们在这个方法里边删除数据库表, * 并建立新的数据库表,当然是否还需要其它操作,完全取决于应用的需求 */@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stubmDataTable.onUpgrade(db);onCreate(db);}}
接下来我们通过调用 SQLiteOpenHelper中的getWritableDatabase()方法获取SQLiteDatabase实例对象,并调用SQLiteDatabase提供的CRUD方法,执行对数据库中表的增、删、改、查操作。其中SQLiteDatabase类中提供的一些常用方法如下:
SQLiteDatabase mSqLiteDatabase = new DatabaseOpenHelper(mContext).getWritableDatabase();/** * 数据库事务操作 *///开启事务mSqLiteDatabase.beginTransaction();//数据库操作执行成功后设置事务执行成功mSqLiteDatabase.setTransactionSuccessful();//关闭事务操作mSqLiteDatabase.endTransaction();/** * 执行SQL语句的方法 */mSqLiteDatabase.execSQL(sql);mSqLiteDatabase.execSQL(sql, bindArgs);/** * 数据查询方法 */mSqLiteDatabase.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, cancellationSignal)mSqLiteDatabase.query(table, columns, selection, selectionArgs, groupBy, having, orderBy)mSqLiteDatabase.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)mSqLiteDatabase.query(distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)mSqLiteDatabase.queryWithFactory(cursorFactory, distinct, table, columns, selection, selectionArgs,groupBy, having, orderBy, limit)mSqLiteDatabase.queryWithFactory(cursorFactory, distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, cancellationSignal)/** * 数据查询方法,支持使用原始的SQL查询,比上面的查询方法速度更快(推荐使用) */mSqLiteDatabase.rawQuery(sql, selectionArgs)mSqLiteDatabase.rawQuery(sql, selectionArgs, cancellationSignal)mSqLiteDatabase.rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable)mSqLiteDatabase.rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, cancellationSignal)/** * 数据插入方法 */mSqLiteDatabase.insert(table, nullColumnHack, values)mSqLiteDatabase.insertOrThrow(table, nullColumnHack, values)mSqLiteDatabase.insertWithOnConflict(table, nullColumnHack, initialValues, conflictAlgorithm)/** * 数据更新方法 */mSqLiteDatabase.update(table, values, whereClause, whereArgs)mSqLiteDatabase.updateWithOnConflict(table, values, whereClause, whereArgs, conflictAlgorithm)/** * 数据删除方法 */mSqLiteDatabase.delete(table, whereClause, whereArgs)/** * 删除数据库 */mSqLiteDatabase.deleteDatabase(file)
接下来创建一个DataBaseManager类,并在该类中实例化DatabaseOpenHelper对象并调用getWritableDatabase()方法获取SQLiteDatabase对象,然后使用该对象执行CRUD操作,具体的代码列表如下:
public abstract class DataBaseManager<T> implements IDatabaseManager,SQLiteDataTable{private static final String TAG = "sqlite_log";private SQLiteDatabase mSqLiteDatabase;public DataBaseManager(Context mContext){DatabaseOpenHelper mDatabaseOpenHelper = DatabaseOpenHelper.getDatabaseOpenHelper(mContext);//设置事件监听mDatabaseOpenHelper.setOnSQLiteDataTable(this);//获取SQLiteDatabase对象,创建或打开数据库mSqLiteDatabase = mDatabaseOpenHelper.getWritableDatabase();}/** * 插入数据操作 * @param mContentValues 插入的数据集合 * @return boolean 布尔值,true为插入成功,false插入失败 */@Overridepublic boolean insert(ContentValues mContentValues) {// TODO Auto-generated method stubmSqLiteDatabase.beginTransaction();try {long rowId = mSqLiteDatabase.insertOrThrow(getTableName(), null, mContentValues);mSqLiteDatabase.setTransactionSuccessful();return rowId != -1;} catch (Exception e) {// TODO: handle exceptionLog.e(TAG, "The insert operation failed");}finally{mSqLiteDatabase.endTransaction();}return false;}/** * 更新数据操作 * @param mContentValues 需要更新的数据集合 * @return boolean 布尔值,true为更新成功,false更新失败 */@Overridepublic boolean update(ContentValues mContentValues) {// TODO Auto-generated method stubmSqLiteDatabase.beginTransaction();try {int rows = mSqLiteDatabase.update(getTableName(), mContentValues, getPrimayKeyID() +"= ?",new String[]{String.valueOf(mContentValues.get(getPrimayKeyID()))});mSqLiteDatabase.setTransactionSuccessful();return rows > 0;} catch (Exception e) {// TODO: handle exceptionLog.e(TAG, "The update operation failed");}finally{mSqLiteDatabase.endTransaction();}return false;}/** * 删除数据操作 * @param mContentValues 需要更删除的数据选项ID * @return boolean 布尔值,true为删除成功,false删除失败 */@Overridepublic boolean delete(int id) {// TODO Auto-generated method stubmSqLiteDatabase.beginTransaction();try {int rows = mSqLiteDatabase.delete(getTableName(), getPrimayKeyID() +"= ?", new String[]{String.valueOf(id)});mSqLiteDatabase.setTransactionSuccessful();return rows > 0;} catch (Exception e) {// TODO: handle exceptionLog.e(TAG, "The delete operation failed");}finally{mSqLiteDatabase.endTransaction();}return false;}/** * 使用标准SQL语句查询数据列表 * @param sql 标准SQL语句 * @return mList 查询后的数据列表 */@SuppressWarnings("unchecked")@Overridepublic ArrayList<T> query(String sql) {ArrayList<T> mList = new ArrayList<T>();Cursor mCursor = mSqLiteDatabase.rawQuery(sql, null);while(mCursor.moveToNext()){T mObject = getResultFromCursor(mCursor);mList.add(mObject);}return mList;}/** * 根据ID查询数据 * @param id 需要查询的数据ID * @return T 查询后获取到的对象 */@Overridepublic T query(int id) {// TODO Auto-generated method stubCursor mCursor = mSqLiteDatabase.query(getTableName(), null, getPrimayKeyID() + "=?", new String[]{String.valueOf(id)}, null, null, null);return getResultFromCursor(mCursor);}/** * 执行一些较为复杂的CRUD操作 */@Overridepublic void execSQL(String sql) {// TODO Auto-generated method stub}/** * 执行对数据库中数据的操作后关闭数据库 */@Overridepublic void closeDB() {// TODO Auto-generated method stubmSqLiteDatabase.close();}/** * 从子类获取表名 * @return String 表的名称 */public abstract String getTableName();/** * 获取表的主键名称 * @return String 主键名 */public abstract String getPrimayKeyID();/** * 使用Cursor转换对象 * @param mCursor 需要转换的Cursor对象 * @return T 创建的对象 */public abstract T getResultFromCursor(Cursor mCursor);}
在这里需要补充一个比较较重的知识点,那就是Cursor类。上面代码列表中的91行和107行执行语句查询后,都会返回一个Cursor对象,Cursor翻译成中文是"游标,光标"的意思,在Android中它代表了一行或多行的数据集合,比方说从数据库中查询的数据放在一个表中,我们可以通过使用Cursor游标去指定每一行的数据,并通过属性名称去查询指定所在的行的属性值。为了更好地理解,我们通过一个图来看一下:
依据上图,假如我们需要查询第5行的email属性的属性值,则我们应该将Cursor光标的位置(Position)移动到第5行,并通过Column Name为“email”来查询到第5行的email属性的属性值,具体的编码如下:
Cursor mCursor = SQLiteDatabase.rawQuery(sql, null);//将Cursor游标移动到第5行(下标从0开始)mCursor.moveToPosition(4);//通过属性名称"email"获取第5行的属性值String emailName = mCursor.getString(mCursor.getColumnIndex("email"));
当然Cursor还有很多其它比较有用的方法,比如说可以调用getColumnName(columnIndex)方法即从给定的索引返回列名,也可以使用getColumnCount()方法获取列的总数。下面我罗列了一些Cursor较为常用的方法,并附有说明,如下:
Cursor mCursor = SQLiteDatabase.rawQuery(sql, null);//返回所有列的总数mCursor.getColumnCount();//返回指定列的索引,如果不存在返回-1mCursor.getColumnIndex(columnName);//从给定的索引返回列名mCursor.getColumnName(columnIndex);//返回一个字符串数组的列名mCursor.getColumnNames();//返回Cursor中的行数mCursor.getCount();//移动光标到第一行mCursor.moveToFirst();//移动光标到最后一行mCursor.moveToLast();//移动光标到下一行mCursor.moveToNext();//移动光标到指定行mCursor.moveToPosition(position);//移动光标到上一行mCursor.moveToPrevious();//关闭游标,释放资源mCursor.close();
好了,我们已经大致学习了一下Cursor类,有想要深入学习Cursor的读者可以参考Android开发者官网。下面我接着开发我们的示例程序。我们定义DataBaseManager的接口IDatabaseManager,里面定义了一些常用抽象方法,代码列表如下:
public interface IDatabaseManager {public boolean insert(ContentValues mContentValues);public <T> ArrayList<T> query(String sql);public Object query(int id);public boolean update(ContentValues mContentValues);public boolean delete(int id);public void execSQL(String sql);public void closeDB();}
接着我们要定义Person类,代码如下:
public class Person {private int id;private String name;private String email;private float height;public Person(){}public Person(int id,String name,String email,float height){this.id = id;this.name = name;this.email = email;this.height = height;}public int getId(){return id;}public void setId(int id){this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public float getHeight() {return height;}public void setHeight(float height) {this.height = height;}}
然后我们创建PersonTableBusiness类,该类是Person操作的业务层,目的是为了提高我们应用程序的重用性和扩展性,PersonTableBusiness类的具体代码列表如下:
public class PersonTableBusiness extends DataBaseManager<Person> {//表的名称private static final String PERSON_TABLE_NAME = "person";private static final String PERSON_FIELD_ID = "id";private static final String PERSON_FIELD_PERSONNAME = "name";private static final String PERSON_FIELD_EMAIL = "email";private static final String PERSON_FIELD_HEIGHT = "height";//定义主键是否为空private static final int PRIMAY_KEY_IS_NULL = -1;public PersonTableBusiness(Context mContext) {super(mContext);// TODO Auto-generated constructor stub}public void insertPerson(String name, String email, float height) {ContentValues mContentValues = createParams(PRIMAY_KEY_IS_NULL, name,email, height);insert(mContentValues);}public void insertPersonObject(Person mPerson) {insert(createParams(mPerson));}public void insertListPerson(ArrayList<Person> mPersons) {for (Person mPerson : mPersons) {insert(createParams(mPerson));}}public void updatePerson(int id, String name, String email, float height) {update(createParams(id, name, email, height));}public void updatePersonObject(Person mPerson) {update(createParams(mPerson));}public void updatePersonList(ArrayList<Person> mPersons) {for (Person mPerson : mPersons) {update(createParams(mPerson));}}public void deletePersonById(int id) {delete(id);}public ArrayList<Person> queryAllPersons() {String sql = "select * from " + PERSON_TABLE_NAME;return query(sql);}public Person querySinglePersonById(int id) {return query(id);}/** * 实现回调方法,这里实现创建表的操作 */@Overridepublic void onCreate(SQLiteDatabase mSqLiteDatabase) {// TODO Auto-generated method stub// 创建表的SQL语句String DATABASE_CREATE_PERSON_TABLE = "CREATE TABLE "+ PERSON_TABLE_NAME + " (" + "" + PERSON_FIELD_ID+ " INTEGER PRIMARY KEY AUTOINCREMENT," + ""+ PERSON_FIELD_PERSONNAME + " VARCHAR(20) NOT NULL," + ""+ PERSON_FIELD_EMAIL + " VARCHAR(20) NOT NULL," + ""+ PERSON_FIELD_HEIGHT + " FLOAT(10) NOT NULL" + ")";// 执行创建表的操作mSqLiteDatabase.execSQL(DATABASE_CREATE_PERSON_TABLE);}/** * 实现回调方法,这里执行删除表的操作 */@Overridepublic void onUpgrade(SQLiteDatabase mSqLiteDatabase) {// TODO Auto-generated method stubmSqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + PERSON_TABLE_NAME);}/** * 创建参数集合 * @param mPerson * @return mValues */public ContentValues createParams(Person mPerson) {ContentValues mValues = new ContentValues();if (mPerson.getId() != PRIMAY_KEY_IS_NULL) {mValues.put(PERSON_FIELD_ID, mPerson.getId());}mValues.put(PERSON_FIELD_PERSONNAME, mPerson.getName());mValues.put(PERSON_FIELD_EMAIL, mPerson.getEmail());mValues.put(PERSON_FIELD_HEIGHT, mPerson.getHeight());return mValues;}/** * 创建参数集合 * @param id * @param name * @param email * @param height * @return mValues */public ContentValues createParams(int id, String name, String email,float height) {ContentValues mValues = new ContentValues();if (id != PRIMAY_KEY_IS_NULL) {mValues.put(PERSON_FIELD_ID, id);}mValues.put(PERSON_FIELD_PERSONNAME, name);mValues.put(PERSON_FIELD_EMAIL, email);mValues.put(PERSON_FIELD_HEIGHT, height);return mValues;}@Overridepublic String getTableName() {// TODO Auto-generated method stubreturn PERSON_TABLE_NAME;}@Overridepublic String getPrimayKeyID() {// TODO Auto-generated method stubreturn PERSON_FIELD_ID;}/** * 通过获取到的Cursor转换成Person对象 */@Overridepublic Person getResultFromCursor(Cursor mCursor) {// TODO Auto-generated method stubPerson mPerson = new Person();mPerson.setId(mCursor.getInt(mCursor.getColumnIndex(PERSON_FIELD_ID)));mPerson.setName(mCursor.getString(mCursor.getColumnIndex(PERSON_FIELD_PERSONNAME)));mPerson.setEmail(mCursor.getString(mCursor.getColumnIndex(PERSON_FIELD_EMAIL)));mPerson.setHeight(mCursor.getFloat(mCursor.getColumnIndex(PERSON_FIELD_HEIGHT)));return mPerson;}}
接着编写MainActivity的代码,MainActivity主要是初始化一些基本控件、 数据以及调用业务层PersonTableBusiness对象中的方法实现个人信息的增删改查,具体的代码如下:
public class MainActivity extends ListActivity {PersonTableBusiness mPersonTableBusiness;public static final int INSERT_ACTION = 0;public static final int UPDATE_ACTION = 1;public static final int DELETE_ACTION = 2;PersonListAdapter mAdapter = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}/** * 初始化数据,展现数据列表 */public void init(){mPersonTableBusiness = new PersonTableBusiness(this);//添加一些默认数据mPersonTableBusiness.insertListPerson(initData());mAdapter = new PersonListAdapter(this,mPersonTableBusiness.queryAllPersons());//适配器绑定数据setListAdapter(mAdapter);//将ListView列表添加到上下文Menu中this.registerForContextMenu(getListView());}/** * 插入数据 */public void insertPerson(){createDialog("添加", INSERT_ACTION, -1,null);}/** * 删除数据 * @param id 列表ID */public void deletePerson(final int id){AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this).setTitle("是否删除?").setPositiveButton("确定", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubmPersonTableBusiness.deletePersonById(id);//重新设置数据mAdapter.setData(mPersonTableBusiness.queryAllPersons());//更新数据列表mAdapter.notifyDataSetChanged();}}).setNegativeButton("取消", null);mBuilder.show();}/** * 更新数据 * @param id 列表ID */public void updatePerson(int id,Person mPerson){createDialog("更新", UPDATE_ACTION, id,mPerson);}/** * 初始化一些测试数据 * @return */public ArrayList<Person> initData(){ArrayList<Person> mList = new ArrayList<Person>();for(int i = 0; i < 20;i++){Person mPerson = new Person(-1,"Steve P.Jobs "+ i, "45936455"+ i +"@qq.com", (170 + i));mList.add(mPerson);}return mList;}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.menu.add(0, 1, Menu.NONE, "添加");return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// TODO Auto-generated method stubinsertPerson();return super.onOptionsItemSelected(item);}@Overridepublic void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {// TODO Auto-generated method stubmenu.setHeaderTitle("文件操作");menu.add(0, 1, Menu.NONE, "修改");menu.add(0, 2, Menu.NONE, "删除");}@Overridepublic boolean onContextItemSelected(MenuItem item) {// TODO Auto-generated method stub// 得到当前被选中的item信息AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();int id = -1;Person mPerson = null;if(mAdapter != null){mPerson = (Person)mAdapter.getItem(menuInfo.position);id = mPerson.getId();}switch (item.getItemId()) {case UPDATE_ACTION:updatePerson(id,mPerson);break;case DELETE_ACTION:deletePerson(id);break;default:break;}return true;}/** * 创建Dialog实例 * @param title 设置Dialog标题 * @param action 设置操作类型 ,UPDATE_ACTION为更新操作,INSERT_ACTION为插入操作 * @param id 被选中的选项ID */public void createDialog(String title,final int action,final int id,final Person mPerson){final View mView = LayoutInflater.from(MainActivity.this).inflate(R.layout.layout_operation, null);String titlName = getResources().getString(R.string.operation, new Object[]{title});final EditText mEditText_name = (EditText)mView.findViewById(R.id.name);final EditText mEditText_email = (EditText)mView.findViewById(R.id.email);final EditText mEditText_height = (EditText)mView.findViewById(R.id.height);//初始化数据if(action == UPDATE_ACTION){mEditText_name.setText(mPerson.getName());mEditText_email.setText(mPerson.getEmail());mEditText_height.setText(String.valueOf(mPerson.getHeight()));}//创建Dialog实例对象AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this).setTitle(titlName).setView(mView).setPositiveButton("确定", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubString name = mEditText_name.getText().toString().trim();String email = mEditText_email.getText().toString().trim();float height = Float.parseFloat(mEditText_height.getText().toString().trim());if(!TextUtils.isEmpty(name) && !TextUtils.isEmpty(email) && !TextUtils.isEmpty(mEditText_height.getText().toString().trim())){switch (action) {case INSERT_ACTION:mPersonTableBusiness.insertPerson(name, email, height);break;case UPDATE_ACTION:mPersonTableBusiness.updatePerson(id, name, email, height);break;default:break;}//重新设置数据mAdapter.setData(mPersonTableBusiness.queryAllPersons());//更新数据列表mAdapter.notifyDataSetChanged();}}}).setNegativeButton("取消", null);mBuilder.show();}/** * 当退出当前界面时,关闭数据库 */@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();mPersonTableBusiness.closeDB();}}
PersonListAdapter的作用就不必多说了,就是建立控件与数据的绑定,具体的代码如下:
public class PersonListAdapter extends BaseAdapter {private Context mContext;private ArrayList<Person> mList;public PersonListAdapter(Context mContext,ArrayList<Person> mList){this.mContext = mContext;this.mList = mList;}public void setData(ArrayList<Person> mList){this.mList = mList;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn mList.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn mList.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder mViewHolder = null;if(convertView == null){convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item, null);mViewHolder = new ViewHolder();mViewHolder.mTextView_id = (TextView)convertView.findViewById(R.id.person_id);mViewHolder.mTextView_name = (TextView)convertView.findViewById(R.id.person_name);mViewHolder.mTextView_height = (TextView)convertView.findViewById(R.id.person_height);mViewHolder.mTextView_email = (TextView)convertView.findViewById(R.id.person_email);convertView.setTag(mViewHolder);}else{mViewHolder = (ViewHolder)convertView.getTag();}mViewHolder.mTextView_id.setText(mList.get(position).getId()+"");mViewHolder.mTextView_name.setText(mList.get(position).getName());mViewHolder.mTextView_height.setText(mList.get(position).getHeight()+"");mViewHolder.mTextView_email.setText(mList.get(position).getEmail());return convertView;}class ViewHolder{TextView mTextView_id;TextView mTextView_name;TextView mTextView_height;TextView mTextView_email;}}
到目前为止,我们的代码就编写完毕了,代码量有点多,也有点复杂。不过代码都注释得很清楚,因此在这就不一一分析代码,请读者研究代码时候结合类关系图多花点时间仔细阅读。最后,我们在虚拟机中运行程序,并执行相关操作,操作图示如下:
我们再看下data/data/com.androidleaf.sqlite/databases/路径下我们的manager.db数据库文件,如图下:

导出manager.db数据库文件,使用SQLite Developer软件工具查询数据库中person表中的数据如图下:

查看上图的数据,我们发现我们成功地完成了对SQLite数据库中的person表的CRUD操作。
总结:今天我们主要对SQLite的概念有了一个初步的了解,并实现了再Android中使用SQLite进行存取数据的功能,大致总结一下,如下:(1)SQLite数据的概念及特点;(2)Cursor的概念及使用;(3)在Android中使用SQLite数据库实现数据的CRUD操作;SQLite数据库作为Android系统中复杂数据的存储引擎,在我们日常的应用开发中使用非常频繁,读者需要深入学习。
源代码下载,请戳这里!