说说 Android(安卓)中的 SQLite 数据库
SQLite 是一款轻量级的关系型数据库,它的运算速度非常快, 占用资源很少,通常只需几百 K 的内存就足够了,因而特别适合在移动设备上使用。它不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务。这套数据库可是内置于 Android 系统中的哦O(∩_∩)O哈哈~
当需要存储大量复杂的关系型数据时,就要用到关系型数据库啦。
1 创建数据库
Android 提供了一个 SQLiteOpenHelper 帮助类,借助这个类可以非常简单地对数据库进行创建与升级。
SQLiteOpenHelper 是一个抽象类,所以我们需要创建一个类去继承它并且重写它的两个抽象方法,即 onCreate() 和 onUpgrade(),去实现创建、升级数据库的逻辑。
创建或打开一个现有的数据库(若已存在则打开,否则创建一个新库),并返回一个可对数据库进行读写操作的对象的实例方法有两种(getReadableDatabase、getWriableDatabase),它们之间的区别是,当数据库不可写入的情况下(如磁盘空间已满):
方法 | 区别 |
---|---|
getReadableDatabase() | 返回的对象将以只读的方式去打开数据库。 |
getWriableDatabase() | 抛出异常。 |
SQLiteOpenHelper 中的一个构造函数是这样的:
SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version)
参数 | 说明 |
---|---|
context | 上下文 |
name | 数据库名 |
factory | 自定义游标,不需要就传入 null |
version | 当前数据库的版本号,用于升级数据库 |
构建出 SQLiteOpenHelper 的实例后,再调用它的 getReadableDatabase() 或 getWritableDatabase() 方法就能够创建数据库咯,数据库文件会存放在 /data/data//databases/ 的目录下。 此时,重写的 onCreate() 方法也会得到执行,可以在这里处理一些创建表的逻辑。
假设我们需要建立一个名为 People.db 的数据库,然后在这个数据库中新建一张 people 表,表中有 id(主键)、名字、年龄、体重等字段。建表语句如下:
create table people( id integer primary key autoincrement,name text,age integer,weight real)
数据类型 | 说明 |
---|---|
integer | 整型 |
real | 浮点型 |
text | 文本类型 |
blob | 二进制类型 |
primary key autoincrement:表示设置某个字段为主键并且自增长。
PeopleDatabaseHelper 类:
public class PeopleDatabaseHelper extends SQLiteOpenHelper { /** * 建表语句 */ public static final String CREATE_SQL="create table people( id integer primary key autoincrement,name text,age integer,weight real)"; private Context context; public PeopleDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); this.context=context; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_SQL); Toast.makeText(context, "建表成功", Toast.LENGTH_SHORT).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
我们在 onCreate 方法中 使用了 execSQL 来执行建表语句 ,这样就可以在创建数据库之后,创建需要的表。
调用语句:
final PeopleDatabaseHelper helper=new PeopleDatabaseHelper(this,"People.db",null,1);helper.getWritableDatabase();
可以使用 adb shell 来查看数据库与表的创建情况。
adb 是 Android SDK 自带的调试工具,可以直接对连接在电脑上的手机或者模拟器进行开发调试工作。它的安装方法请参见 在 Android Device Monitor 的 File Explorer 中,无法打开某些文件夹的解决方法
在命令行界面,使用命令 adb shell
进入设备控制台(先使用 adb root
获得访问权限):
进入目录命令的格式为:
cd /data/data/[包名]/databases/
这里为 cd /data/data/net.deniro.android.databasetest/databases/
使用命令 ls
查看当前目录下的文件:
*.db:是我们创建的数据库。
*.db-journal:是为了让数据库能够支持事务所产生的临时日志文件,一般情况下,它为 0 字节。
使用 sqlite3 数据库名
来打开数据库,并使用 .table
命令来查看目前的数据库中有哪些表:
使用命令 .schema
可以查看这些表的创建语句:
键入 .exit 或 .quit 就可以退出 sqlite,再次键入 .exit 就会退出设备控制台,是不是很简单呀O(∩_∩)O哈哈~
2 升级数据库
可以在继承自 SQLiteOpenHelper 类的 onUpgrade 方法中,对数据库进行升级。
假设我们需要新增一张行业表,建表语句为:
create table Industry( id integer primary key autoincrement, industry_name text, industry_code integer)
修改原来的代码:
/** * 创建行业表 */public static final String CREATE_INDUSTRY_SQL = "create table Industry( id integer primary key autoincrement, industry_name text, industry_code integer)"; @Overridepublic void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_PEOPLE_SQL); db.execSQL(CREATE_INDUSTRY_SQL); Toast.makeText(context, "建表成功", Toast.LENGTH_SHORT).show();}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { dropTable(db, "People"); dropTable(db, "Industry"); onCreate(db);}/** * 删除表 * * @param db * @param tableName 表名称 * @return */private void dropTable(SQLiteDatabase db, String tableName) { db.execSQL("drop table if exists " + tableName);}
这里首先在 onCreate 方法中,创建行业表;接着在 onUpgrade 方法中,删除相应的表,并调用 onCreate,重新创建表结构。
最后在 PeopleDatabaseHelper 的构造函数中,把版本号(最后一个参数)改为 2:
创建成功后,可以通过之前介绍的 adb shell 方法查看新创建的表结构:
3 新增数据
对数据进行的操作一般有四种,即 CRUD:添加(Create),查询(Retrieve),更新(Update),删除(Delete)。
SQLiteOpenHelper 中的 getReadableDatabase() 或 getWritableDatabase() 方法都会返回一个 SQLiteDatabase 对象,借助这个对象可以对数据进行 CRUD 操作。
SQLiteDatabase 类包含 insert 方法:
public long insert(String table, String nullColumnHack, ContentValues values)
参数名 | 说明 |
---|---|
table | 表名 |
nullColumnHack | 在未指定添加数据的情况下给某些可为空的列自动赋值,一般传入 null。 |
values | 是一个ContentValues 对象,它包含一系列的 put() 方法重载,用于向 ContentValues 中添加数据(列名与列的内容一一对应)。 |
新增操作:
SQLiteDatabase db= helper.getWritableDatabase();//新增ContentValues values=new ContentValues();values.put("name","deniro");values.put("age",22);values.put("weight",70);db.insert("People",null,values);
因为 id 为自增长的列,所以这里无须赋值。
查看结果:
select * from People;
4 更新数据
SQLiteDatabase 类包含 update 方法:
public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
参数名 | 说明 |
---|---|
table | 表名 |
values | ContentValues 对象,存放要更新的数据 |
whereClause | where SQL 语句(占位符形式) |
whereArgs | where SQL 语句中的参数,与语句中的占位符一一对应 |
调用代码:
SQLiteDatabase db= helper.getWritableDatabase();//修改ContentValues values=new ContentValues();values.put("age",24);db.update("People",values,"name = ?",new String[]{"deniro"});
这里把所有 name = ‘deniro’ 的数据中的 age 都更新为 24。
更新结果:
5 删除数据
SQLiteDatabase 类中包含 delete 方法来删除数据:
public int delete(String table, String whereClause, String[] whereArgs)
参数名 | 说明 |
---|---|
table | 表名 |
whereClause | where SQL 语句(占位符形式)【可选】 |
whereArgs | where SQL 语句中的参数,与语句中的占位符一一对应【可选】 |
调用代码:
SQLiteDatabase db = helper.getWritableDatabase();//删除db.delete("People", "name = ?", new String[]{"deniro"});
执行后,在 sqlite 命令中就会发现,数据被删除咯。
6 查询数据
SQLiteDatabase 中提供了 query() 方法用于查询数据。 这个方法的参数非常复杂,最短的一个方法重载也需要传入七个参数。
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
参数名 | 说明 | 示例 |
---|---|---|
table | 表名 | from table_name |
columns | 列名 | select column1,column2 |
selection | where 条件 | where column = value |
selectionArgs | where 条件中的占位符参数值 | - |
groupBy | 需要分组的列 | group by column |
having | 分组条件 | having column = value |
orderBy | 排序条件 | order by column1,column2 |
返回 Cursor 对象,查询到的数据可以从这个对象中取出。
调用代码:
SQLiteDatabase db = helper.getWritableDatabase();//查询Cursor cursor = db.query("People", null, null, null, null, null, null);if (cursor.moveToFirst()) { do { Log.d(TAG, "name: " + cursor.getString(cursor.getColumnIndex("name"))); Log.d(TAG, "age: " + cursor.getInt(cursor.getColumnIndex("age"))); } while (cursor.moveToNext());}cursor.close();
得到 Cursor 对象后,使用 moveToFirst 把数据指针移到第一行,然后进入循环。getColumnIndex 获取某一列在表中的位置索引,然后把这个索引传入相应类型的取值方法中(比如 int 型,使用 getInt 方法),就可以读取数据啦。最后记得关闭 cursor。
7 使用原生 SQL 操作数据库
我们也可以直接使用原生 SQL 来完成前面说过的新增、修改与删除操作,这就是 SQLiteDatabase 类中的 execSQL 方法:
public void execSQL(String sql, Object[] bindArgs)
参数名 | 说明 |
---|---|
sql | SQL 语句 |
bindArgs | 占位符绑定的参数 |
查询数据可以使用 SQLiteDatabase 类中的 rawQuery方法:
public Cursor rawQuery(String sql, String[] selectionArgs)
参数说明与 execSQL 方法类似,是不是很简单呀O(∩_∩)O哈哈~
更多相关文章
- “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
- Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
- 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
- Flutter插件混编的各种奇葩问题以及Flutter与Native数据交互,Meth
- android Frame动画概述+示例
- android截图事件监听
- Android活动文件夹
- 从原理角度解析Android(安卓)(Java) http 文件上传
- android图表引擎AchartEngine制作柱图源码