当前位置:网站首页>【Android -- 数据存储】使用 SQLite 存储数据
【Android -- 数据存储】使用 SQLite 存储数据
2022-07-07 14:12:00 【Kevin-Dev】

一、前言
在 Android 中一共提供了五种数据存储方式,分别为:
1. Files:通过FileInputStream和FileOutputStream对文件进行操作。具体使用方法可以参阅博文《Android学习笔记34:使用文件存储数据》。
2. Shared Preferences:常用来存储键值对形式的数据,对系统配置信息进行保存。
3. Content Providers:数据共享,用于应用程序之间数据的访问。
4. SQLite:Android自带的轻量级关系型数据库,支持SQL语言,用来存储大量的数据,并且能够对数据进行使用、更新、维护等操作。
5. Network:通过网络来存储和获取数据。
本篇博文主要介绍第一种方式,通过 SQLite 存储数据。
二、实战
在项目开发中,我们或多或少都会用到数据库。在 Android 中,我们一般使用 SQLite,因为 Android 在 android.database.sqlite 包封装了很多 SQLite 操作的 API。
在使用 SQLite 时,我建议先下载一个本地 SQLite 客户端来验证操作,在本地写的 SQL 语句运行正确后,再转移到 Android 中。我用的是 SQLite Expert Personal。
1. 创建一个继承在 SQLiteOpenHelper 的类,并重写 onCreate() 和 onUpgrade() 方法。
public class OrderDBHelper extends SQLiteOpenHelper{
private static final int DB_VERSION = 1;
private static final String DB_NAME = "myTest.db";
public static final String TABLE_NAME = "Orders";
public OrderDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// create table Orders(Id integer primary key, CustomName text, OrderPrice integer, Country text);
String sql = "create table if not exists " + TABLE_NAME + " (Id integer primary key, CustomName text, OrderPrice integer, Country text)";
sqLiteDatabase.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXISTS " + TABLE_NAME;
sqLiteDatabase.execSQL(sql);
onCreate(sqLiteDatabase);
}
}
这个类主要用于建数据库和建表用,我们再创建一个 OrderDao 用于处理所有的数据操作方法。在 OrderDao 中实例化OrderDBHelper:
public OrderDao(Context context) {
this.context = context;
ordersDBHelper = new OrderDBHelper(context);
}
数据库操作无外乎:“增删查改”。对于“增删改”这类对表内容变换的操作,我们需先调用 getWritableDatabase() ,在执行的时候可以调用通用的 execSQL(String sql) 方法或对应的操作 API:insert()、delete()、update() 。而对“查”,需要调用 getReadableDatabase() ,这时就不能使用 execSQL 方法了,得使用 query() 或 rawQuery() 方法。
增加数据
- 初始化数据
在进入 Demo 程序时,先判断表中是否有数据,如果表中没有数据,先添加一些数据。在初始化数据时,因为一次性要添加的数据比较多,所以直接采用的是 execSQL 方法:
db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (1, 'Arc', 100, 'China')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (2, 'Bor', 200, 'USA')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (3, 'Cut', 500, 'Japan')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (4, 'Bor', 300, 'USA')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (5, 'Arc', 600, 'China')");
db.execSQL("insert into " + OrderDBHelper.TABLE_NAME + " (Id, CustomName, OrderPrice, Country) values (6, 'Doom', 200, 'China')");
db.setTransactionSuccessful();
- 插入一条新数据
我们还可以使用 insert(String table,String nullColumnHack,ContentValues values) 方法来插入,ContentValues 内部实现就是HashMap,但是两者还是有差别的,ContenValues Key 只能是 String 类型,Value 只能存储基本类型的数据,像 string,int 之类的,不能存储对象这种东西:
public ContentValues() {
// Choosing a default size of 8 based on analysis of typical
// consumption by applications.
mValues = new HashMap<String, Object>(8);
}
使用 insert() 方法我们插入一条新数据(7, “Jne”, 700, “China”),对于修改数据的操作我们一般当作事务(Transaction)处理:
db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();
// insert into Orders(Id, CustomName, OrderPrice, Country) values (7, "Jne", 700, "China");
ContentValues contentValues = new ContentValues();
contentValues.put("Id", 7);
contentValues.put("CustomName", "Jne");
contentValues.put("OrderPrice", 700);
contentValues.put("Country", "China");
db.insertOrThrow(OrderDBHelper.TABLE_NAME, null, contentValues);
db.setTransactionSuccessful();
删除数据
删除数据的方法除了 execSQL 还有 delete(String table,String whereClause,String[] whereArgs),whereClause是删除条件,whereArgs 是删除条件值数组。
db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();
// delete from Orders where Id = 7
db.delete(OrderDBHelper.TABLE_NAME, "Id = ?", new String[]{
String.valueOf(7)});
db.setTransactionSuccessful();
再看删除的源码,里面会拼装删除条件和删除条件值数组:
public int delete(String table, String whereClause, String[] whereArgs) {
acquireReference();
try {
SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table +
(!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
try {
return statement.executeUpdateDelete();
} finally {
statement.close();
}
} finally {
releaseReference();
}
}
修改数据
修改数据和插入数据很相似,调用的方法除了execSQL还可以是 update(String table,ContentValues values,String whereClause, String[] whereArgs):
db = ordersDBHelper.getWritableDatabase();
db.beginTransaction();
// update Orders set OrderPrice = 800 where Id = 6
ContentValues cv = new ContentValues();
cv.put("OrderPrice", 800);
db.update(OrderDBHelper.TABLE_NAME,
cv,
"Id = ?",
new String[]{
String.valueOf(6)});
db.setTransactionSuccessful();
查找数据
查找数据有两个方法,一是 public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);,另外一个是 public Cursor rawQuery(String sql, String[] selectionArgs)。rawQuery的写法类似上面的execSQL,在此不做介绍,query方法中的参数如下:
- table:表名称
- columns:列名称数组
- selection:条件字句,相当于where
- selectionArgs:条件字句,参数数组
- groupBy:分组列
- having:分组条件
- orderBy:排序列
- limit:分页查询限制
- Cursor:返回值,相当于结果集ResultSet
我们可以看到返回的类型都是 Cursor,Cursor是一个游标接口,提供了遍历查询结果的方法,如移动指针方法move(),获得列值方法。Cursor 游标常用方法如下:
我们先来查一查用户名为"Bor"的信息:
db = ordersDBHelper.getReadableDatabase();
// select * from Orders where CustomName = 'Bor'
cursor = db.query(OrderDBHelper.TABLE_NAME,
ORDER_COLUMNS,
"CustomName = ?",
new String[] {
"Bor"},
null, null, null);
if (cursor.getCount() > 0) {
List<Order> orderList = new ArrayList<Order>(cursor.getCount());
while (cursor.moveToNext()) {
Order order = parseOrder(cursor);
orderList.add(order);
}
return orderList;
}
当然我们也可以查询总数、最大值最小值之类的,以查询Country为China的用户总数为例:
db = ordersDBHelper.getReadableDatabase();
// select count(Id) from Orders where Country = 'China'
cursor = db.query(OrderDBHelper.TABLE_NAME,
new String[]{
"COUNT(Id)"},
"Country = ?",
new String[] {
"China"},
null, null, null);
if (cursor.moveToFirst()) {
count = cursor.getInt(0);
}
边栏推荐
- 分步式監控平臺zabbix
- Vs tool word highlight with margin
- C4D learning notes 1- animation - animation key frames
- PyTorch 中的乘法:mul()、multiply()、matmul()、mm()、mv()、dot()
- Laravel constructor and middleware execution order
- Bidding announcement: Fujian Rural Credit Union database audit system procurement project (re bidding)
- Good news! Kelan sundb database and Hongshu technology privacy data protection management software complete compatibility adaptation
- Bidding announcement: 2022 Yunnan Unicom gbase database maintenance public comparison and selection project (second) comparison and selection announcement
- Rongyun won the 2022 China Xinchuang digital office portal excellence product award!
- 47_ Contour lookup in opencv cv:: findcontours()
猜你喜欢

Sysom case analysis: where is the missing memory| Dragon lizard Technology

10 schemes to ensure interface data security

记一次项目的迁移过程

PyTorch 中的乘法:mul()、multiply()、matmul()、mm()、mv()、dot()

torch.numel作用

统计学习方法——感知机

What about the pointer in neural network C language

Eye of depth (VII) -- Elementary Transformation of matrix (attachment: explanation of some mathematical models)

SysOM 案例解析:消失的内存都去哪了 !| 龙蜥技术

神经网络c语言中的指针是怎么回事
随机推荐
47_ Contour lookup in opencv cv:: findcontours()
AE learning 02: timeline
Vs tool word highlight with margin
[flower carving experience] 15 try to build the Arduino development environment of beetle esp32 C3
Step by step monitoring platform ZABBIX
C4D learning notes 3- animation - animation rendering process case
Apache Doris just "graduated": why should we pay attention to this kind of SQL data warehouse?
How does laravel run composer dump autoload without emptying the classmap mapping relationship?
js中复选框checkbox如何判定为被选中
星瑞格数据库入围“2021年度福建省信息技术应用创新典型解决方案”
Apache Doris刚“毕业”:为什么应关注这种SQL数据仓库?
Good news! Kelan sundb database and Hongshu technology privacy data protection management software complete compatibility adaptation
Unity3D_ Class fishing project, bullet rebound effect is achieved
Xcode Revoke certificate
SysOM 案例解析:消失的内存都去哪了 !| 龙蜥技术
10 schemes to ensure interface data security
平衡二叉树(AVL)
Is it reliable to open an account on Tongda letter with your mobile phone? Is there any potential safety hazard in such stock speculation
应用程序和matlab的通信方式
torch. Numel action