SQLite的简单实用

使用Android自带的API操作数据库

创建数据库

openOrCreateDatabase(···)databaseList() 方法是Android提供的Context底层方法,可以用来打开数据库文件并将其转换为 SQLiteDatabase 实例。

不过,实际开发中,建议总是遵循以下步骤:

  • 确认目标数据库实际存在
  • 如果不存在,首先创建数据库,然后创建数据库表以及必需的初始化数据
  • 如果存在,打开并确认数据是否为最新版本
  • 如果是旧版本,就运行相关代码升级到最新版本

Android为我们提供的SQLiteOpenHelper类可以帮我们处理这些。首先 SQLiteOpenHelper 类是抽象类,有两个抽象方法 onCreate()onUpgrade(),我们需要重写这两个方法并且分别在这两个方法中去实现创建和升级数据库的逻辑。

SQLiteOpenHelper 中有两个构造方法可供重写,一般使用参数少一点的那个构造方法即可。这个构造方法接收四个参数:

  • 第一个参数是 Context,有它才能对数据库进行操作。
  • 第二个参数是数据库名,创建数据库时使用的就是这里指定的名称。
  • 第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般都是传入null
  • 第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作

SQLiteOpenHelper 中还有两个非常重要的实例方法, getReadableDatabase()getWritableDatabase()。这两个方法都乐意创建或打开一个现有的数据库(如果数据库已存在就打开,否则创建一个新的数据库),并且返回一个可对数据库进行读写操作的对象。不同的是,当数据库不可写入的时候(如果磁盘空间已满)getReadableDatabase() 方法返回的对象将以只读方式去打开数据库,而getWritableDatabase()方法则会抛出异常。

如果我们想创建一个名为 Student.db 的数据库,然后在这个数据库中新建一张Student表,表中有 学号(主键),名字,性别等列。

Eg:

1
2
3
4
5
create table Bool(
id integer primary key autoincrement,
name text,
gender text
)

在建表语句中使用了 primary key 将 id 列设为主键,并用autoincrement 关键字表示 id 列是自增长。

sqlite 数据库数据类型

  • Integer
  • varchar(10)
  • flaot
  • double
  • char(10)
  • text

又因为SQLite允许存入数据时忽略底层数据列实际的数据类型,因此在编写建表语句时可以省略数据列后面的类型声明,所以下面的写法也是对的,

Eg:

1
2
3
4
5
create table Bool(
id integer primary key autoincrement,
name,
gender
)

所以,我们创建一个 MyDatebaseHelper 类,继承自 SQLiteOpenHelper ,并实现它的两个抽象方法,及一个构造方法,完成建表与执行SQL语句。

Eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MyDatebaseHelper extends SQLiteOpenHelper {

public static final String CREAT_STUDENT = "create table Bool(" +
"id integer primary key autoincrement, " +
"name, " +
"gender " +
")";

public CrimeBaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.exec(CREAT_STUDENT);
}

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

}
}

SQLite数据库的 “增” “删” “改” “查”

“增” —— 添加数据

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

该方法接收三个参数:

  • 第一个参数是表名
  • 第二个参数用于在未指定添加数据的情况下给某些可为空的列自赋值null,一般直接传入null即可
  • 第三个参数是一个 ContentValues 对象,它提供了一系列的 put() 方法重载,用于向 ContentValues 中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。

Eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private MyDatebaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
dbHelper = new MyDatebaseHelper(this, "Student.db", null, 1);
···
// 点击按钮添加数据
onClick(View v){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// 开始组装第一组数据
values.put("id", "001");
values.put("name", "Jacob");
values.put("gender", "male");
db.insert("Student", null, values); // 插入第一条数据
values.clear(); // 若想在下面继续添加数据,这一定要调用该方法
// 开始组装第二组数据
values.put("id", "002");
values.put("name", "Jane");
values.put("gender", "female");
db.insert("Student", null, values); // 插入第二条数据
}
···

“删” —— 删除数据

public int delete(String table, String whereClause, String[] whereArgs)

该方法接收三个参数:

  • 第一个参数是表名
  • 第二,三个参数 用于约束删除某一行或某几行的数据,不指定的话默认就是删除所有行,在第二个参数中我们可以使用占位符 “?”

Eg: (以 Student.db 为例)

删除 “name” 为 “Jacob” 的数据

1
db.dele("Student", "name like ?", new String[]{"Jacob"});

删除所有 “name” 以 “J” 开头的数据

1
db.dele("Student", "name like ?", new String[]{"J_"});

删除所有 “id” 为 “002” 的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  db.dele("Student", "id = ?", new String[]{"002"});
```

> 删除所有 "id" 大于 "001" 的数据

```java
db.dele("Student", "id > ?", new String[]{"001"});
```

### “改” —— 更新数据

public int update(String table, ContentValues values, String whereClause, String[] whereArgs)


该方法接收四个参数:
+ 第一个参数是表名
+ 第二个参数是 ContentValues 对象,要把更新数据在这里组装进去
+ 第三,四个参数 用于约束更新某一行或某几行的数据,不指定的话默认就是更新所有行,在第二个参数中我们可以使用占位符 “?”

_**Eg:**_
```java
private MyDatebaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
dbHelper = new MyDatebaseHelper(this, "Student.db", null, 1);
···
// 点击按钮更新数据,将 "id" 为 "002" 的数据的 "name" 改为 "Mary"
onClick(View v){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", "Mary");
db.insert("Student", values, "id = ?", new String[]{"002"});
}
···

“查” —— 查找数据

SQLite的查询方法有很多,而且参数都很多,这里我们讲一个参数最少却常用的

public Cursor query(String table, String[] columns, String selection,
    String[] selectionArgs, String groupBy, String having,
    String orderBy)
query() 方法参数 对应 SQL 部分 描述
table from table_name 指定查询的表明
columns select column1,column2 指定查询的列名
selection where column = value 指定 where 的约束条件
selectionArgs - 为 where 中的占位符提供具体的值
groupBy group by column 指定需要 group by 的列
having having column = value 对 group by 后的结果进一步约束
orderBy order by column1,column2 指定查询结果的排序方式

如果我们想查询数据库的全部数据,只需要传入表名即可;如果我们想查询单个数据,传入表名后,再在第三,四个参数上指定约束条件即可,也就是说我们没必要指定所有的参数

Eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private MyDatebaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
dbHelper = new MyDatebaseHelper(this, "Student.db", null, 1);
···
// 点击按钮更新数据,将 "id" 为 "002" 的数据的 "name" 改为 "Mary"
onClick(View v){
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("Student
null, // Columns - null selects all columns
"id = ?",
new String[]{"002"},
null, // groupBy
null, // having
null // orderBy
);
cursor.moveToFirst();
String id = getString(getColumnIndex("id"));
String name = getString(getColumnIndex("name"));
String gender = getString(getColumnIndex("gender"));
Log.d("MainActivity", "Student's id is " + id);
Log.d("MainActivity", "Student's name is " + name);
Log.d("MainActivity", "Student's gender is " + gender);
cursor.close();
}
···


那么简单的API操作讲了,还是讲一下如何用原生SQLite语句来操作吧

使用原生SQLite语句操作数据库

创建表

1
2
create table 表名(字段名称 数据类型 约束, 字段名称 数据类型 约束 ... ... )
create table person(_id Integer primary key, name varchar(10), age Integer not null)

删除表

1
2
drop table 表名
drop table person

插入表

1
2
3
insert into 表名[字段, 字段] values{值1, 值2 ... ...}
insert into person{_id, age} values(1, 20) // value在插入时必须与前面的字段相对应
insert into person values(2, "zs", 30) // 若没指定字段,则默认从第一个字段开始

修改数据

1
2
update 表名 set 字段 = 新值 where 修改的条件
update person set name="ls",age=20 where _id=1

删除数据

1
2
delete from 表名 where 删除条件
delete from person where _id=2

查询语句

1
2
3
4
5
6
7
8
9
10
11
select 字段名 from 表名 where 查询条件 group by 分组字段 having 筛选条件 order by 排序字段
select * from person // 查询表中所有数据
select _id,name from person // 查询person表中的id,name字段
select * from person where _id=1 // 查询person表,id为1的情况
select * from person where _id<>1 // 查询person表,id不为1的情况
select * from person where _id=1 and age>18 // 查询person表,id为1和age大于18的情况
select * from person where name like "%小%" // 模糊查询name这个字段中,中间包含“小”(前后可以有任意长的字符)的情况
select * from person where name like "_小%" // 模糊查询name这个字段中,一个字符之后是“小”(后面可以有任意长的字符)的情况
select * from person where name is null // 查询名字为空的情况
select * from person where age between 10 and 20 // 年龄在10到20之间的情况
select * from person where age>18 orderby _id // 年龄大于18并根据id进行排序的情况
文章作者: Inno Fang
文章链接: https://innofang.github.io/2017/02/19/SQLite的简单实用/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来自 Inno's Blog