数据存储(三) SQLite

一、SQLite简介


        SQLite是一款轻量级的关系型数据库,由于它占用资源较少,所以很多嵌入式设备和移动设备都使用SQLite来存储数据。

       【特点】1. 轻量级 2. 独立性 3. 隔离性 4. 跨平台 5. 多语言 6. 安全性


二、SQLite支持的数据类型


前五种类型为支持的基本类型

三、常用SQL语句


      sql语句不区分大小写,但一般把系统关键字大写,把自定义的表名,字段名(列名)小写。sql语句以“;”作为结尾。

(一)表的操作

1. 创建表

CREATE TABLE IF NOT EXISTS  表名 (

         主键名  INTEGER PRIMARY KEY AUTOINCREMENT,

         字段1 TEXT NOT NULL,

        字段2 TEXT

);

【约束】

创建数据库表的时候可以为表添加约束,这样可以避免非法数据插入到数据库中

-PRIMARY KEY:主键,唯一标识数据库表中的各行记录

-AUTOINCREMENT:自增,一般和主键配合使用

-NOT NULL:确保一列不能有NULL值

-UNIQUE:确保某一列所有值不同(唯一)

-DEFAULT:提供一列的默认值

-CHECK:CHECK约束,确保一列中的所有值满足一定条件

CREATE TABLE IF NOT EXISTS student (

        _id INTEGER PRIMARY KEY AUTOINCREMENT,

        name TEXT NOT NULL DEFAULT stu,

        age TEXT CHECK (age > 18)

);

2. 删除表

DROP TABLE IF EXISTS 表名;

3. 修改表

3.1  修改表名

ALTER TABLE 旧表名 RENAME TO 新表名;

3.2 增加列

ALTER TABLE 表名 ADD COLUMN 列名 列数据类型;

3.3 修改列的数据类型

ALTER TABLE 表名 ALTER COLUMN 列名 列数据类型;

(二)数据操作

1. 插入数据

INSERT INTO  表名 (字段1, 字段2, ...) VALUES (值1, 值2,...);

2. 删除数据

DELETE FROM 表名 WHERE 条件子句;

3. 修改数据

UPDATE 表名 SET 字段1 = 值1, 字段2 = 值2  WHERE 条件子句;

4. 查询数据

4.1 查询所有数据

SELECT * FROM 表名;

4.2 按条件查询

SELECT * FROM 表名 where 条件子句;

常用条件有

AND:age >20 AND sex = 'man'

OR:age >20 OR sex = 'man'

BETWEEN ... AND ...:  age BETWEEN 20 AND 30

4.3 去重查询

SELECT DISTINCT 字段名 FROM 表名;

4.4 模糊查询

SELECT * FROM 表名 WHERE 字段名 LIKE  '_马%'

其中,_表示一个,%表示没有、一个或多个

4.5 排序 - ORDER BY

升序 ASE, 默认升序

倒序 DESC

SELECT * FROM 表名 ORDER BY 字段 ASE|DESC;

4.6 分页查询(限制和偏移量)  LIMIT、OFFSET

    Limit:查询限制数量,offset查询结果中的偏移量

SELECT * FROM 表名 LIMIT 2 OFFSET 3;    偏移3条数据,取2条数据

SELECT * FROM 表名 LIMIT 2 , 4;  偏移2条数据,取4条数据

4.7 聚合函数

4.7.1 查询数据行数

SELECT COUNT(*) FROM 表名;

4.7.2 查询数据行数,起一个别名为count

SELECT COUNT(*) AS 别名 FROM 表名;

4.7.3 最大值、最小值

SELECT MAX(字段名) FROM 表名;

SELECT MIN(字段名) FROM 表名; 

4.7.4 平均值

SELECT AVG(字段名) FROM 表名;

4.7.5 求和

SELECT SUM(字段名) FROM 表名;

4.8 分组、分组条件

SELECT 字段1, SUM(字段2) FROM 表名 GROUP BY 字段名  HAVING  分组条件子句;

如,SELECT name, SUM(age) FROM stu GROUP BY name HAVING age > 20;

(三)多表联合查询、外键

创建班级表

CREATE TABLE classes(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, num INTEGER);

创建学生表

CREATE TABLE stus(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, classID INTEGER, FOREIGN KEY (classID) REFERENCES classes (_id));

【注意】 学生表的classID字段被定义成外键,管理classes的主键_id。

连接查询

SELECT * FROM  stus LEFT JOIN classes ON classes._id = stus.classID  WHERE stus.age > 11;

【LEFT JOIN跟Join的区别】

LEFT JOIN

        如果要查询左边表中的所有符合条件的数据,使用LEFT JOIN。通常查询出来的结果会多,因为右边表不存在的记录,同样可能会被查询出来,查询出来之后,右边表不存在的记录,全部为NULL。结果如上图。

JOIN

        如果要两个表中同时存在的符合条件的数据,使用JOIN。通常查询出来的结果会比左连接少,因为右边表不存在的记录,不会显示出来。结果如下图。


四、SQLiteOpenHelper


         SQLiteOpenHelper是SQLiteDatabase的一个帮助类,用来管理数据库的创建和版本的更新。一般是建立一个类继承它,并实现它的onCreate和onUpgrade方法。

构造方法

SQLiteOpenHelper(

            Context context,  // 上下文对象

            String name, // 数据库的名称

            SQLiteDatabase.CursorFactory factory, // 传入null则代表使用默认的CursorFactory

            int version // 数据库版本

)

两个抽象方法

onCreate(SQLiteDatabase db)

只有第一次创建这个数据库的时候调用。一般在这个方法中创建数据的相应表。

onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

当数据库升级(版本更新)时调用

创建或打开数据库

SQLiteDatabase  getReadableDatabase()

SQLiteDatabase  getWritableDatabase() 

【注意】两个方法当数据库未写满时作用相同。当数据库不存在时,创建并打开数据库,触发onCreate()方法。当数据库存在时,打开数据库。由于getWritableDatabase()获得的数据库,当数据库写满的时候依旧可写,从而产生异常。建议使用getReadableDatabase(),当数据库写满时,只可读。


五、SQLiteDatabase

      

        SQLiteDatabase代表一个数据库(实质就是一个数据库文件,.db文件),可以通过SQLiteDatabase对象来管理、操作数据库。

打开或创建数据库

方式一,通过SQLiteOpenHelper

方式二,通过静态方法,很少用

SQLiteDatabase.openOrCreateDatabase(String path, CursorFactory factory);

常用方法

插入数据

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

【返回值】插入成功,返回数据位置。插入失败,返回-1。

【ContentValues】存放键值对

【示例】

ContentValues cv = new ContentValues();//实例化一个ContentValues用来装载待插入的数据

cv.put("username","abc");//添加用户名

cv.put("age", 20);//添加密码

db.insert("user",null,cv);//执行插入操作

删除数据

(int) delete(String table, StringwhereClause, String[] whereArgs)

【示例】

String whereClause = "username=? AND  age = ?";//删除的条件

String[] whereArgs = {"abc", "20"};//删除的条件参数

db.delete("user",whereClause,whereArgs);//执行删除

更新数据

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

【示例】

ContentValues cv = new ContentValues();//实例化ContentValues

cv.put("age", 20); //添加要更改的字段及内容

String whereClause = "username=?";//修改条件

String[] whereArgs = {"Jack Johnson"};//修改条件的参数

db.update("user",cv,whereClause,whereArgs);//执行修改

关闭数据库

(void) close()

【注意】数据库比较销毁内存,使用完毕应该及时关闭

执行一个非查询SQL语句

(void) execSQL(String sql)

查询数据

public Cursor query (

          String table,  //表名

          String[]  columns,  //字段名数组,null返回所有字段数据

          String selection, //查询条件子句

          String[] selectionArgs,  //查询条件的值

          String groupBy,  //分组

          String having,  // 分组条件

          String orderBy //排序条件

)



六、Cursor

        Cursor就像是位于结果集之上的一个游标,可以对结果集进行向前、向后或随机的访问。而Cursor本身是一个接口类,提供了对结果集访问的一些抽象方法,根据功能的不同在其子类有着不同的实现。  

常用方法

总记录条数

getCount()

移动到下一条记录

boolean moveToNext()

获得指定列的索引

int getColumnIndex(StringcolumnName)

获得指定索引的数据

getXXX(int columnIndex)

关闭Cursor

close()

其他方法

isFirst()判断是否第一条记录

isLast()判断是否最后一条记录

moveToFirst()移动到第一条记录

moveToLast()移动到最后一条记录

move(int offset)移动到指定的记录

moveToPrevious()移动到上一条记录

【注意】Cursor使用完毕后,也应及时关闭

【通过sql语句查询】

Cursor c = db.rawQuery("select * from user where username=?", new Stirng[]{"Jack Johnson"});


七、事务管理

         对于多次数据库的操作(多次执行sql语句),使用事物管理机制,会大大提高程序的运行效率。一般流程如下:

db.beginTransaction();//开始事务

for(inti=1; i<10; i++) {

     //进行批量处理操作

}

db.setTransactionSuccessful();//提交事务

db.endTransaction();//结束事务

【事务回滚】

       在结束事务之前调用setTransactionSuccessful()方法,则当调用结束事务的时候是事务提交。否则事务回滚。


推荐阅读更多精彩内容