您当前的位置:首页 > Android教程

Android开发学习教程(31)- Android SQLite使用教程

时间:2022-01-27 07:19:04 阅读数:30,427人阅读
版权声明:转载请注明出处,谢谢!
—— 不为跑赢世界,只为超越自己。

Android提供了四种不同的方式用于本地存储数据,上一篇我们讲了文件存储和SharedPreferences存储,现在我们来看 SQLite 存储。SQLite 是一个结构查询基础数据库,我们可以说它是一个关系数据库。Android 系统有内部已经实现了CRUD(创建、读取、更新、删除)操作,在 Android 的 android.database 和 android.database.sqlite 包中提供了一组可用的类。

在使用 SQLite 时,可能有两种不同的方式来执行不同的操作如创建、读取、更新和删除。一种是编写原始SQL语句,另一种是使用参数化函数,或者我们可以说是参数化查询。

创建数据库

使用 SQLiteOpenHelper 类在 Android 中创建数据库非常简单。SQLiteOpenHelper 是一个抽象类,具有两个抽象方法 onCreate(SQLiteDatabase db) 和 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 以及更多对数据库有用的函数。每当我们需要创建数据库时,我们必须扩展 SQLiteOpenHelper 类,如下所示:

		public class SqliteManager extends SQLiteOpenHelper {
		
			public static final String DATABASE_NAME = "test.db";
			public static final int version = 1;
			 
			public SqliteManager(Context context) {
			   super(context, DATABASE_NAME, null, version);
			}

			@Override
			public void onCreate(SQLiteDatabase sqLiteDatabase) {
			   String dbQuery = "CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT, description TEXT)";
			   sqLiteDatabase.execSQL(dbQuery);
			}

			@Override
			public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
				
			}
			
		}
	  

onCreate(SQLiteDatabase sqLiteDatabase)方法在整个应用程序生命周期中只调用一次,每当第一次调用 SQLiteOpenHelper 类中的 getReadableDatabase() 或 getWritableDatabase() 函数时都会调用它,因此 SQLiteOpenHelper 类在创建后调用 onCreate() 方法数据库并实例化 SQLiteDatabase 对象。数据库名称在构造函数调用中传递。

onUpgrade(SQLiteDatabase db,int oldVersion, int newVersion)仅在升级APP版本并且数据库有更新时调用,因此需要更新版本时我们必须增加version的值,比如app从1.0.0升级到1.0.1的时候数据库需要升级的话,对应的version就要改成大于1的任何整数即可。在 onUpgrade 方法中,我们可以编写SQL语句来执行所需的任何操作。如增加一张新表,增加一条数据记录等等。

在 Sqlite 中插入、读取、删除和更新操作

执行插入、读取、删除、更新操作有两种不同的方式:

1. 编写参数化查询(推荐)

2. 编写原始SQL语句

参数化查询:这些查询使用SDK内置的函数来插入、读取、删除或更新数据。这些操作相关的函数在 SQLiteDatabase 类中提供。

原始SQL语句:这些是类似于 MySql、Sql Server 等其他数据库的 sql 查询语句,将这些SQL语句当做参数传给 rawQuery(String sql,String [] selectionArgs) 或 execSQL(String sql,Object [] bindArgs) 方法来执行操作。

注: Android 官方不建议使用原始SQL语句来执行插入、读取、更新、删除操作,建议始终使用 SQLiteDatabase 类的内置函数执行插入、查询、更新、删除操作。原因如下:

当使用原始SQL语句执行插入操作的时:

	   public void insertItem(Item item) {
		   String query = "INSERT INTO " + ItemTable.NAME + " VALUES (0,?,?)";
		   SQLiteDatabase db = getWritableDatabase();
		   db.execSQL(query, new String[]{item.name, item.description});
		   db.close();
	   }
	  

在使用原始查询时,我们永远不会知道操作的结果,即db.execSQL的返回值是void类型。而使用参数化查询函数则会返回一个值来表示操作成功或失败。所以建议使用参数化查询。

插入操作

使用参数化查询执行插入操作,我们必须调用 SQLiteDatabase 类中内置的插入函数:

		  public long insert(String tableName,String nullColumnHack,ContentValues values)
	  

insert()函数具有三个参数,tableName 是要插入数据表的名称。nullColumnHack可能为空,SQL不允许在插入一个完全空的行时不指定至少一个列名。如果提供的值为空,则不知道列名,并且无法插入空行。如果未设置为null,则nullColumnHack参数提供可为null的列名的名称,以便在值为空的情况下显式插入null。values是包含一行数据的键值对。键应该是列名值是列值。如果插入成功,insert 函数将返回一个 long 值,即插入的行数,否则返回 - 1。

举个栗子:

		public void addItem(Item item) {
		    SQLiteDatabase db = getWritableDatabase();
		    ContentValues contentValues = new ContentValues();
		    contentValues.put("name", item.name);
		    contentValues.put("description", item.description);
		    db.insert("Items", null, contentValues);
		    db.close();
		}
	  

更新操作

更新操作与插入操作非常相似,但它需要两个额外的参数,它不需要 nullColumnHack。它共有四个参数,其中两个类似于插入函数,即 tableName 和 contentValues。另外两个是 whereClause(String) 和 whereArgs(String[]):

		  public int update(String tableName,ContentValues contentValues,String whereClause,String[] whereArgs)
	  

这里 whereClause 是告诉数据库在哪里更新表中的数据,建议在 whereClause 字符串中使用占位符 ? 表示将要传递的值。类似地,whereArgs 数组将包含那些传递给对应的占位符 ? 的值。如果成功,更新函数将返回受影响的行数,否则返回 0。

举个栗子:

		public void updateItem(Item item) {
		    SQLiteDatabase db = getWritableDatabase();
		    ContentValues contentValues = new ContentValues();
		    contentValues.put("id", item.id);
		    contentValues.put("name", item.name);
		    contentValues.put("description", item.description);
		    String whereClause = "id=?";
		    String whereArgs[] = {item.id.toString()};
		    db.update("Items", contentValues, whereClause, whereArgs);
		}
	  

删除操作

与插入和更新类似,SQLiteDatabase 类中提供了删除功能,因此删除与更新功能非常相似,除了 ContentValues 对象,因为它在删除中不需要。delete 函数有三个参数,它们与更新函数的参数完全相似,使用方式与更新函数相同。

举个栗子:

		public void deleteItem(Item item) {
		    SQLiteDatabase db = getWritableDatabase();
		    String whereClause = "id=?";
		    String whereArgs[] = {item.id.toString()};
		    db.delete("Items", whereClause, whereArgs);
		}
	  

这里 whereClause 是可选的,传递 null 将删除表中的所有行。如果 whereClause 传递,删除函数将返回受影响的行数,否则将返回 0。

注:如果要删除所有行并要求返回删除行的计数,则将 1 作为 whereClause 传递。

查询操作

从数据库表中读取与插入、更新和删除等其他函数有点不同。SQLiteDatabase 类提供query()方法来从表中读取数据。query() 方法被不同的参数集重载。它返回Cursor对象,因此 Cursor 是一个带有查询数据的结果集,它提供了不同的功能,在读取数据时非常有用。

以下是一些重载的查询函数:

public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)

public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

查询重载函数中的大多数参数都是可选的,除了 table 和不同的任何其他参数都可以作为 null 传递。如果 distinct 作为 true 传递,则游标数据集将没有任何重复行。

	    public ArrayList readAllItems() {
			ArrayList items = new ArrayList<>();
			SQLiteDatabase db = getReadableDatabase();
			//see above point 2 function
			Cursor cursor = db.query("Items"
			, null// columns - null will give all
			, null// selection 
			, null// selection arguments
			, null// groupBy
			, null// having 
			, null// no need or order by for now;
			if (cursor != null) {
			  while (cursor.moveToNext()) {
			  // move the cursor to next row if there is any to read it's data
					   Item item = readItem(cursor);
					   items.add(item);
				 }
			  }
			return items;
		}

		private Item readItem(Cursor cursor) {
		    Item item = new Item();
		    item.id = cursor.getInt(cursor.getColumnIndex(ItemTable.COL_ID));
		    item.name = cursor.getString(cursor.getColumnIndex(ItemTable.COL_NAME));
		    item.description = cursor.getString(cursor.getColumnIndex(ItemTable.COL_DESCRIPTION));
		    return item;
		}
	  

本篇源码下载地址:https://pan.baidu.com/s/1Bq_LziAfSvf4wlLq8u9Ctg 提取码: helu

------转载请注明出处,感谢您对原创作者的支持------

有偿提供技术支持、Bug修复、项目外包、毕业设计、大小作业

Android学习小站

Q Q:1095817610

微信:jx-helu

邮箱:1095817610@qq.com

添加请备注"Android学习小站"