当前位置:网站首页>【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);
}
边栏推荐
- There are many ways to realize the pause function in JS
- hellogolang
- Talk about the cloud deployment of local projects created by SAP IRPA studio
- 47_Opencv中的轮廓查找 cv::findContours()
- Laravel 服务提供者实例教程 —— 创建 Service Provider 测试实例
- 【知识小结】PHP使用svn笔记总结
- pycharm 终端部启用虚拟环境
- 通知Notification使用全解析
- Logback日志框架第三方jar包 免费获取
- 安科瑞电网智能化发展的必然趋势电力系统采用微机保护装置是
猜你喜欢

Xingruige database was shortlisted as the "typical solution for information technology application and innovation in Fujian Province in 2021"

Rongyun won the 2022 China Xinchuang digital office portal excellence product award!
![[flower carving experience] 15 try to build the Arduino development environment of beetle esp32 C3](/img/8f/ca9ab042916f68de7994d9f2124da9.jpg)
[flower carving experience] 15 try to build the Arduino development environment of beetle esp32 C3

Three. JS introductory learning notes 18: how to export JSON files with Blender

记一次项目的迁移过程
![Unity drawing plug-in = = [support the update of the original atlas]](/img/b0/92114ffb1f168a1f27125db46c6797.jpg)
Unity drawing plug-in = = [support the update of the original atlas]

企业级日志分析系统ELK

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

Odoo integrated plausible embedded code monitoring platform
通知Notification使用全解析
随机推荐
Use moviepy Editor clips videos and intercepts video clips in batches
星瑞格数据库入围“2021年度福建省信息技术应用创新典型解决方案”
【HCSD大咖直播】亲授大厂面试秘诀-简要笔记
hellogolang
模仿企业微信会议室选择
Mysql database basic operation DQL basic query
Regular expression string
torch. Numel action
PyTorch 中的乘法:mul()、multiply()、matmul()、mm()、mv()、dot()
Enterprise log analysis system elk
Bidding announcement: 2022 Yunnan Unicom gbase database maintenance public comparison and selection project (second) comparison and selection announcement
How does geojson data merge the boundaries of regions?
谈谈 SAP iRPA Studio 创建的本地项目的云端部署问题
Shipping companies' AI products are mature, standardized and applied on a large scale. CIMC, the global leader in port and shipping AI / container AI, has built a benchmark for international shipping
Numpy -- epidemic data analysis case
Sysom case analysis: where is the missing memory| Dragon lizard Technology
What else can an ordinary person do besides working in a factory to make money?
TCP framework___ Unity
prometheus api删除某个指定job的所有数据
What about the pointer in neural network C language