当前位置:网站首页>【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);
}
边栏推荐
- 尤雨溪,来了!
- 招标公告:盘锦市人民医院盘锦医院数据库维保项目
- Three. JS introductory learning notes 08:orbitcontrols JS plug-in - mouse control model rotation, zoom in, zoom out, translation, etc
- [excelexport], Excel to Lua, JSON, XML development tool
- 47_Opencv中的轮廓查找 cv::findContours()
- leetcode 241. Different ways to add parentheses design priority for operational expressions (medium)
- 星瑞格数据库入围“2021年度福建省信息技术应用创新典型解决方案”
- SPI master rx time out中断
- three.js打造酷炫下雪效果
- Continuous creation depends on it!
猜你喜欢
AE learning 01: AE complete project summary
2022第四届中国(济南)国际智慧养老产业展览会,山东老博会
Vs tool word highlight with margin
Statistical learning method -- perceptron
Apache Doris just "graduated": why should we pay attention to this kind of SQL data warehouse?
Continuous creation depends on it!
分步式監控平臺zabbix
Eye of depth (VII) -- Elementary Transformation of matrix (attachment: explanation of some mathematical models)
PyTorch 中的乘法:mul()、multiply()、matmul()、mm()、mv()、dot()
Unity3D_ Class fishing project, bullet rebound effect is achieved
随机推荐
航運船公司人工智能AI產品成熟化標准化規模應用,全球港航人工智能/集裝箱人工智能領軍者CIMC中集飛瞳,打造國際航運智能化標杆
Balanced binary tree (AVL)
Unity3d click events added to 3D objects in the scene
Strengthen real-time data management, and the British software helps the security construction of the medical insurance platform
安科瑞电网智能化发展的必然趋势电力系统采用微机保护装置是
Performance measure of classification model
Notification uses full resolution
leetcode 241. Different Ways to Add Parentheses 为运算表达式设计优先级(中等)
laravel 是怎么做到运行 composer dump-autoload 不清空 classmap 映射关系的呢?
【知识小结】PHP使用svn笔记总结
星瑞格数据库入围“2021年度福建省信息技术应用创新典型解决方案”
招标公告:盘锦市人民医院盘锦医院数据库维保项目
融云斩获 2022 中国信创数字化办公门户卓越产品奖!
Plate - forme de surveillance par étapes zabbix
AE learning 02: timeline
Numpy --- basic learning notes
Logback logging framework third-party jar package is available for free
Numpy -- data cleaning
Shader basic UV operations, translation, rotation, scaling
用手机在通达信上开户靠谱吗?这样炒股有没有什么安全隐患