Android中SQLite数据库介绍和使用

本文介绍了SQLite数据库的基本概念,并通过实例展示了在Android应用中如何创建、操作SQLite数据库,包括数据的增删查改操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:http://blog.youkuaiyun.com/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数据库相关的历史、特点及命令操作,可以学习以下两个网站的资源:

在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() {
			
			@Override
			public 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;
	} 

	/**
	 * 创建数据库时调用,一般执行创建表的操作
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		//创建一系列的数据库表
		mDataTable.onCreate(db);
	}

	/**
	 * 当数据库需要修改的时系统会自动调用此方法。一般我们在这个方法里边删除数据库表,
	 * 并建立新的数据库表,当然是否还需要其它操作,完全取决于应用的需求
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		mDataTable.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插入失败
	 */
	@Override
	public boolean insert(ContentValues mContentValues) {
		// TODO Auto-generated method stub
		mSqLiteDatabase.beginTransaction();
		try {
			long rowId = mSqLiteDatabase.insertOrThrow(getTableName(), null, mContentValues);
			mSqLiteDatabase.setTransactionSuccessful();
			return rowId != -1;
		} catch (Exception e) {
			// TODO: handle exception
			Log.e(TAG, "The insert operation failed");
		}finally{
			mSqLiteDatabase.endTransaction();
		}
		return false;
	}

	/**
	 * 更新数据操作
	 * @param mContentValues 需要更新的数据集合
	 * @return boolean 布尔值,true为更新成功,false更新失败
	 */
	@Override
	public boolean update(ContentValues mContentValues) {
		// TODO Auto-generated method stub
		mSqLiteDatabase.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 exception
			Log.e(TAG, "The update operation failed");
		}finally{
			mSqLiteDatabase.endTransaction();
		}
		return false;
	}

	/**
	 * 删除数据操作
	 * @param mContentValues 需要更删除的数据选项ID
	 * @return boolean 布尔值,true为删除成功,false删除失败
	 */
	@Override
	public boolean delete(int id) {
		// TODO Auto-generated method stub
		mSqLiteDatabase.beginTransaction();
		try {
			int rows = mSqLiteDatabase.delete(getTableName(), getPrimayKeyID() +"= ?", new String[]{String.valueOf(id)});
			mSqLiteDatabase.setTransactionSuccessful();
			return rows > 0;
		} catch (Exception e) {
			// TODO: handle exception
			Log.e(TAG, "The delete operation failed");
		}finally{
			mSqLiteDatabase.endTransaction();
		}
		return false;
	}

	/**
	 * 使用标准SQL语句查询数据列表
	 * @param sql 标准SQL语句
	 * @return mList 查询后的数据列表
	 */
	@SuppressWarnings("unchecked")
	@Override
	public 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 查询后获取到的对象
	 */
	@Override
	public T query(int id) {
		// TODO Auto-generated method stub
		Cursor mCursor = mSqLiteDatabase.query(getTableName(), null, getPrimayKeyID() + "=?", new String[]{String.valueOf(id)}, null, null, null);
		return getResultFromCursor(mCursor);
	}
	
	/**
	 * 执行一些较为复杂的CRUD操作
	 */
	@Override
	public void execSQL(String sql) {
		// TODO Auto-generated method stub
		
	}

	/**
	 * 执行对数据库中数据的操作后关闭数据库
	 */
	@Override
	public void closeDB() {
		// TODO Auto-generated method stub
		mSqLiteDatabase.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();
	//返回指定列的索引,如果不存在返回-1
	mCursor.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);
	}

	/**
	 * 实现回调方法,这里实现创建表的操作
	 */
	@Override
	public 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);
	}

	/**
	 * 实现回调方法,这里执行删除表的操作
	 */
	@Override
	public void onUpgrade(SQLiteDatabase mSqLiteDatabase) {
		// TODO Auto-generated method stub
		mSqLiteDatabase.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;
	}

	@Override
	public String getTableName() {
		// TODO Auto-generated method stub
		return PERSON_TABLE_NAME;
	}

	@Override
	public String getPrimayKeyID() {
		// TODO Auto-generated method stub
		return PERSON_FIELD_ID;
	}

	/**
	 * 通过获取到的Cursor转换成Person对象
	 */
	@Override
	public Person getResultFromCursor(Cursor mCursor) {
		// TODO Auto-generated method stub
		Person 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;
	
	@Override
	protected 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() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				mPersonTableBusiness.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;
	}
	
	@Override
	public 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;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		insertPerson();
		return super.onOptionsItemSelected(item);
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		menu.setHeaderTitle("文件操作");
		menu.add(0, 1, Menu.NONE, "修改");
		menu.add(0, 2, Menu.NONE, "删除");
	}

	@Override
	public 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() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				
				String 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();
	}
	
	/**
	 * 当退出当前界面时,关闭数据库
	 */
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.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;
	}
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return mList.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		ViewHolder 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系统中复杂数据的存储引擎,在我们日常的应用开发中使用非常频繁,读者需要深入学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值