SQLite 数据库简介
SQLite 是一个轻量级数据库, 它是 D. Richard Hipp 建立的公有领域项目, 在 2000 年发布了第一个版本. 它的设计目标是嵌入式的, 而且占用资源非常低, 在内存中只需要占用几百 kB 的存储空间, 这也是 Android 移动设备采用 SQLite 数据库的重要原因之一.
SQLite 是遵守 ACID 的关系型数据库管理系统. 这里的 ACID 是指数据库事务正确执行的 4 个基本要素, 即原子性(Atomicity), 致性 ( Consistency), 隔离性( lolation). 持久性( Durabilily ). 它能够支持 Windows/Linux/UNIX 等主流的操作系统, 能够跟很多程序语言, 例如 Tcl,C#,PHP, Java 等相结合. 比起 MySQL,PostgreSQL 这两款开源数据库管理系统来讲, SQLite 的处理速度更快.
SQLite 没有服务器进程, 它通过文件保存数据, 该文件是跨平台的, 可以放在其他平台中使用. 并且在保存数据时, 支持 null(零) ,integer (整数),real (浮点数字) ,text (字符串文本)和 blob(二进制对象)5 种数据类型. 但实际上 SQLite 也接收 varchar(n), char(n),decimal(p,s)等数据类型, 只不过在运算或保存时会转换成对应的 5 种数据类型. 因此, 可以将各种类型的数据保存到任何字段中, 而不用关心字段声明的数据类型.
SQLite 数据库创建
在 Android 系统中, 创建 SQLite 数据库是非常简单的. Android 系统推荐使用 SQLiteOpenHelper 的子类创建数据库, 因此需要创建一个继承自 SQLiteOpenHelper, 并重写该类中的 onCreate()方法和 onUpgrade()方法即可.
为什么要使用 SQLiteOpenHelper 的子类呢, 因为 SQLiteOpenHelper 为抽象类 (abstract), 必须使用其子类进行继承, 同时还需要重写父类的抽象方法, onCreate() 方法和 onUpgrade()方法都是其父类中的抽象方法.
- public class MyHelper extends SQLiteOpenHelper {
- @Override
- private static String DATABASE_NAME = "alan.db";
- private static int DATABASE_VERSION = 2;
- public MyHelper(Context context){
- super(context,DATABASE_NAME,null,DATABASE_VERSION); // 调用父类的构造方法
- }
- // 数据库第一次被创建时调用该方法
- public void onCreate(SQLiteDatabase db){
- // 初始化数据库的表结构, 执行一条建表的 SQL 语句
- db.execSQL("CREATE TABLE IF NOT EXISTS person(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20), price INTEGER);
- }
- // 当数据库版本增加时调用
- public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){
- }
- }
- //SQLiteOpenHelper 类的构造函数有四个参数
- //context 代表上下文, name 是数据库名字, factory 是游标工厂, 一般情况下为 null 值, version 是数据库版本, 软件在今后的升级中会用到.
- public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
- this(context, name, factory, version, null);
- }
SQLite 数据库使用
前面介绍了 SQLite 数据库及如何创建数据库, 接下来将针对 SQLite 数据库的增, 删, 改, 查操作进行详细讲解.
一, SQLite 基本操作方法 一
1. 增加一条数据
下面以 alan.db 数据库中的 person 表为例, 介绍如何使用 SQLiteDatabase 对象的 insert()方法向表中插入一条数据, 示例代码如下.
- public void insert(String name, String price){
- SQLiteDatabase db = myHelper.getWritableDatabase(); // 获取可写入的 SQLiteDatabase 对象
- ContentValues values = new ContentValues(); // 创建 ContentValues 对象
- values.put("name",name); // 将数据添加到 ContentValues 对象
- values.put("price",price);
- long id = db.insert("person",null,values); // 插入一条数据到 person 表
- db.close(); // 关闭数据库
- }
在上述代码中, 通过 getWritableDatabase()方 法得到 SQLiteDatabase 对象, 然后获得 ContentValues 对象并将数据添加到 ContentValues 对象中, 最后调用 inser()方法将数据插入到 person 表中.
insert()方法接收 3 个参数, 第一个参数是数据表的名称, 第二个参数表示如果发现将要插入的行为空行时, 会将这个列名的值设为 null, 第三个参数为 ContentValues 对象. ContentValues 类类似于 Map 类, 通过键值对的形式存入数据, 这里的 key 表示插入数据的列名, value 表示要插入的数据.
需要注意的是, 使用完 SQLiteDatabase 对象后定要调用 close()方法关闭, 否则数据库连接会一直存在, 不断消耗内存, 当系统内存不足时将获取不到 SQLiteDatabase 对象, 并且会报出数据库未关闭异常.
2. 修改一条数据
下面介绍如何使用 SQLiteDatabase 的 update()方法修改 person 表中的数据, 示例代码如下.
- public int update(String name, string price) {
- SQLiteDatabase db = myHelper.getwritableDatabasel;
- ContentValues values = new ContentValues();
- values.put ("price", price);
- int number = db.update("person",values,"name =?",new String[]{
- name
- });
- db.close();
- return number;
- }
在上述代码中, 通过 SQLiteDatebase 对象 db 调用 update()方法用来修改数据库中的数据, update()方法接收 4 个参数, 第一个参数表示表名, 第二个参数接收一个 ContentValues 对象, 第三个参数可选择 where 语句, 第四个参数表示 whereClause 语句中的占位参数列表, 这些字符串会替换掉 where 条件中的 "?".
3. 删除一条数据
下面介绍如何使用 SQLiteDatabase 的 delete()方法修改 person 表中的数据, 示例代码如下.
- public int delete(long id) {
- SQLiteDatabase db = myHelper.getwritableDatabasel;
- int number = db.delete("person",_id =?,"name =?",new String[]{
- id
- });
- db.close();
- return number;
- }
从上述代码中可以看出, 删除数据不同于增加和修改数据, 因为删除数据不需要 ContentValues 来添加数据.
4. 查询一条数据
在进行数据查询时使用的是 SQLiteDatabase 的 query0 方法, 该方法返回的是一个行数集合 Cursor. Cursor 是一个游标接口, 提供了遍历查询结果的方法, 如移动指针方法 move(), 获得列值方法 getString()等, 通过这些方法可以获取集合中的属性值以及序号等.
需要注意的是, 在使用完 Cursor 对象后, 一定要及时关闭, 否则会造成内存泄露. 下面介绍如何使用 SQLiteDatabase 的 query()方法查询数据, 示例代码如下.
- public boolean find(long id) {
- SQLiteDatabase db = helper .getReadableDatabase ();// 获取可读取的 SQLiteDatabase 对象
- Cursor cursor = db.query("person", null,"_id =?", new String[]{
- id
- }),null, null, null) ; boolean result = cursor.moveToNext () ; cursor.close(); // 关闭游标 db.close() ; return result;
- }
- //Cursor 中的的重要方法:
- c.move(int offset); // 以当前位置为参考, 移动到指定行
- c.moveToFirst(); // 移动到第一行
- c.moveToLast(); // 移动到最后一行
- c.moveToPosition(int position); // 移动到指定行
- c.moveToPrevious(); // 移动到前一行
- c.moveToNext(); // 移动到下一行
- c.isFirst(); // 是否指向第一条
- c.isLast(); // 是否指向最后一条
- c.isBeforeFirst(); // 是否指向第一条之前
- c.isAfterLast(); // 是否指向最后一条之后
- c.isNull(int columnIndex); // 指定列是否为空(列基数为 0)
- c.isClosed(); // 游标是否已关闭
- c.getCount(); // 总数据项数
- c.getPosition(); // 返回当前游标所指向的行数
- c.getColumnIndex(String columnName);// 返回某列名对应的列索引值, 如果不存在返回 - 1
- c.getString(int columnIndex); // 返回当前行指定列的值
- c.getColumnIndexOrThrow(String columnName) // 从零开始返回指定列名称, 如果不存在将抛出 IllegalArgumentException 异常.
- c.close() // 关闭游标, 释放资源
在上述代码中, 介绍了使用 query()方法查询 person 表中的数据, query()方法接收 7 个参数, 第一个参数表示表名称, 第二个参数表示查询的列名, 第三个参数接收查询条件子句, 第四个参数接收查询子句对应的条件值, 第五个参数表示分组方式, 第六个参数接收 having 条件, 即定义组的过滤器, 第七个参数表示排序方式.
二, SQLite 基本操作方法 二
这种操作方法类似于执行 SQL 语句 (语法和 SQL server 类似).
1. 增加一条数据
db.execSQL("insert into perosn (name, price) values(?,?)",new String[]{name,price})
2. 修改一条数据
db.execSQL("update person set price =? where name =?", new String[]{price,name});
3. 删除一条数据
db.execSQL("delete from person where _id = ?",new String[]{id});
4. 查询一条数据
Cursor cursor = db.rawQuery("select _id,name,price from person where id =?",new String[]{id});
从上述代码可以看出, 查询操作与增, 删, 改操作有所不同, 前面三个操作都是通过 execSQL()方法执行 SQL 语句, 而查询操作使用的是 rawQuery()方法. 这是因为查询数据库会返回一个结果集 Cursor, 而 execSQL()方法则没有返回值.
来源: http://www.linuxidc.com/Linux/2019-03/157688.htm