1. 数据类型

与其它数据库不同,SQLite的数据类型很简单,只有NULL(空类型)、INTEGER(整型)、REAL(浮点型)、TEXT(字符串型)、BLOB(二进制型)。

SQLite为动态数据类型(弱引用),当向数据库中插入某个值时,会检查该值的类型,若类型与插入列不匹配,SQLite会尝试将该值转换成相应类型。

2. 创建数据库

如果对SQL的操作不了解,建议先看看这一块:MySQL入门笔记(一)

Android中提供了一个SQLiteOpenHelper类,使用该类可非常方便地进行数据库的创建与升级。

SQLiteOpenHelper是一个抽象类,必须实现onCreate()、onUpgrade(),这两个方法分别用于数据库的创建与升级,onCreate()在数据库不存在的情况下会调用,而onUpgrade()则是当版本号高于已有数据库时调用。

SQLiteOpenHelper构造函数的第一个参数是context,第二个参数是数据库的名称,第三个参数允许在查询数据时返回一个自定义的Cursor,直接传入null即可,第四个参数是数据库版本号,用于数据库的升级操作。

调用getReadableDtabase()或者getWritableDatabase()方法即可创建或打开数据库,同时返回一个SQLiteDatabase对象,用于操作数据库。这里,SQLiteDatabase对象有两个重要方法,exexSQL方法和rawQuery方法,前者用于执行SQL语句,后者用于查询记录,后面会具体介绍。

拓展:Context与SQLiteDatabase的方法openOrCreateDatabase的区别 (context、SQLiteOpenHelper)

范例:

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); new SQLiteOpenHelper(this, "Library.db", null, 1) { static final String CREATE_BOOK = "create table BOOK ("
+ "id integer primary key autoincrement, "
+ "name text, "
+ "author text)"; @Override
public void onCreate(SQLiteDatabase db) {
// 创建数据表
db.execSQL(CREATE_BOOK);
Toast.makeText(MainActivity.this, "创建成功!", Toast.LENGTH_SHORT).show();
} // 用于升级数据库
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}.getWritableDatabase();
}
}

3. 升级数据库

在进行app的迭代时,往往也会伴随着进行数据库的升级,这就需要通过onUpgrade()方法实现。需要升级数据库时,在实例化SQLiteOpenHelper时传入一个更高的版本号即可。

范例:

假定进行两次迭代:1. 新增一张表catelogy,2. 给表book增加category_id字段。

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); new SQLiteOpenHelper(this, "Library.db", null, 1) { static final String CREATE_BOOK = "create table BOOK ("
+ "id integer primary key autoincrement, "
+ "name text, "
+ "author text,"
+ "category_id integer)";//第二次升级时增加 static final String CREATE_CATEGORY = "create table CATEGORY ("
+ "id integer primary key autoincrement, "
+ "category_name text,"
+ "category_code integer)"; static final String CHANGE_COLUMN = "alter table BOOK column category_id integer"; @Override
public void onCreate(SQLiteDatabase db) {
// 如果用户当前是初次安装本程序,即数据库未被创建,则直接创建两个表
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(MainActivity.this, "创建成功!", Toast.LENGTH_SHORT).show();
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
// 不使用break
case 1:
db.execSQL(CREATE_CATEGORY);
case 2:
db.execSQL(CHANGE_COLUMN);
default:
}
}
}.getWritableDatabase();
}
}

这里注意一个细节,onUpgrade()方法中的switch语句里的并未使用break,这是为了保证在跨版本升级时能顺利依次完成中间的所有升级。

4. 数据操作

4.1 execSQL()和rawQuery()

上面提到,调用getReadableDatabase()或者getWritableDatabase()方法时会返回一个SQLiteDatabase对象,要对数据进行操作,就是使用这一对象。

结合上面的例子,我们可以看到SQLiteDatabase提供了一个调用SQL语句的方法execSQL(),通过这个方法可以调用除查询语句以外的SQL语句,同时SQLiteDatabase类提供了一个rawQuery()方法,用于查询数据。

(1)execSQL()

execSQL(String sql)
execSQL(String sql, Object[] bingArgs)

使用execSQL()方法传入参数有两种方式,第一种直接传入SQL语句,如有参数则直接拼接在一起,例如:

String delete_sql = "delete from test where _id = " + idString;
db.execSQL(sql);

第二种方法则是在参数的位置插入占位符?,而后将具体参数传给execSQL()方法的第二个参数,如有多个参数,则依次放入:

String delete_sql = "delete from test where _id = ?, name = ?";
db.execSQL(sql, new String[] {idString, nameString});

(2)rawQuery()

rawQuery(String sql, String[] selectionArgs)

rawQuery()方法的使用与execSQL()的第二种用法基本一致。

4.2 安卓提供的API

除了execSQL()方法和rawQuery()方法,安卓还针对数据库的CRUD操作封装了API,更加便于操作。

(1)insert()

insert(String table, String nullColumnHack, ContentValues values)

table:表名。

nullColumnHack:若某些允许为空的列没有赋值,则自动赋值为null,传入null即可。

values:ContentValues对象,相当于一个容器的作用,可通过它的put(key, values)方法(key为列名称,values为该列的值)将每一行的数据一一添加,而后再传入数据库。如需插入多条记录,插入下一条记录前要调用clear()方法进行清空。

返回一个id值,即插入记录的id。

范例:

    //获取SQLiteDatabase对象
db = mHelper.getWritableDatabase(); //实例化ContentValues对象并进行数据组装
ContentValues values = new ContentValues();
values.put("name", "A");
values.put("author", "aa"); //插入数据
db.insert("BOOK", null, values); //若需要插入多条记录,在这一步一定要调用values的clear()方法清空现有的数据
values.clear(); values.put("name", "B");
values.put("author", "bb");
db.insert("BOOK", null, values);

(2)delete()

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

whereClausewhereArgs:指定删除条件,若不指定则删除表中所有数据。即SQL中where字句部分,占位符的使用同execSQL()与rawQuery(),例如将age > 30的记录删除,则第二个参数为"age > ?",第三个参数为new String[] {"30"}。

范例:

    //删除数据,?是一个占位符,第二、第三个参数合起来即删除id > 2的记录
db.delete("BOOK", "id > ?", new String[] {"2"});

(3)update()

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

values同Insert()方法,将更新后的数据通过ContentValues对象组装,而whereClause和whereArgs则同delete()方法,指定更新哪些记录。

范例:

    ContentValues values = new ContentValues();
values.put("name", "D");
db.update("BOOK", values, "id < ?", new String[] {"3"});

(4)query()

query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)

如果学过SQL语言的话,相信对上面这一长串的参数是比较容易理解的,基本上可以与SQL中select语句的结构对应上。调用query()方法会返回一个Cursor对象,里面含有所有查询结果。

table:对应SQL中的from table_name,指定查询的表名。

columns:对应select column1, column2, ...,指定查询的列名称。

selection:对应where column = value,指定查询的行的约束条件。

selectionArgs:为selection中的占位符(?)提供具体值。

groupBy:对应group by column,指定对哪一列进行分组。

having:对应having column = value,进一步对分组后的结果进行约束。

orderBy:对应order by column1, column2, ...,指定查询结果的排序方式。

范例:

    db = mHelper.getWritableDatabase();
//查询BOOK中所有数据
Cursor cursor = db.query("BOOK", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
//遍历cursor,取出数据
int id = cursor.getInt(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
//打印数据
Log.d("MySQLiteData", id + ". 《" + name + "》 " + author);
}while (cursor.moveToNext());
//关闭Cursor对象
cursor.close();
}

5. 事务

SQLite是支持事务的,那么什么是事务呢?假定需要更新大量数据,就要先删除旧数据,而后再插入新数据。但是在过程中出现了异常,旧数据被删除之后,新数据没有成功插入,那这一个数据表的信息就全没了。

事务的特性就是保证某一个系列的操作,或者全部完成,或者全部不完成。如果替换数据放在事务中进行,则要么数据替换成功,表内全部换成新数据,要么失败,保留旧数据,不会出现删了旧数据,但是没插入新数据的情况。

事务的使用方法非常简单:

// 通过SQLiteDatabase对象开启事务
db.beginTransaction();
try {
// 在异常捕获的代码块中进行具体的操作
// 在全部操作结束后将事务设置为成功
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
} finally (
// 结束事务
db.endTransaction();
)

SQLiteOpenHelper与SQLiteDatabase的使用的更多相关文章

  1. SQLiteOpenHelper/SQLiteDatabase/Cursor源代码解析

    转载请注明出处:http://blog.csdn.net/y_zhiwen/article/details/51583188 Github地址.欢迎star和follow 新增android sqli ...

  2. 关于android的SQLiteDatabase和Cursor的一些疑问

    android数据库操作的基础有三个类:SQLiteOpenHelper,SQLiteDatabase和Cursor.其中,SQLiteOpenHelper会建立一个数据库连接,它虽然可以调用多次ge ...

  3. Android之SQLite数据库篇

    一.SQLite简介 Google为Andriod的较大的数据处理提供了SQLite,他在数据存储.管理.维护等各方面都相当出色,功能也非常的强大. 二.SQLite的特点 1.轻量级使用 SQLit ...

  4. (转) Android开发性能优化简介

    作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以 ...

  5. Android数据存储之Sqlite的介绍及使用

    前言: 本来没有打算整理有关Sqlite数据库文章的,最近一直在研究ContentProvider的使用,所有觉得还是先对Sqlite进行一个简单的回顾,也方便研究学习ContentProvider. ...

  6. Android之sqlite的使用 (转载)

    Android中的SQLite使用 首先创建数据库类 public class DatabaseHelper extends SQLiteOpenHelper {       private stat ...

  7. Android之数据库的创建

    一.SQLite介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP ...

  8. android内存优化

    背景 虽然android设备的配置越来越高,但是,由于android系统的机制导致(最主要是app程序的主线程不会真正退出而是在后台常驻内存中) ,这样手机中安装过多的app之后,导致内存被大量占用, ...

  9. Android数据存储五种方式总结

    本文介绍Android平台进行数据存储的五大方式,分别如下: 1 使用SharedPreferences存储数据     2 文件存储数据       3 SQLite数据库存储数据 4 使用Cont ...

随机推荐

  1. Javascript原型继承容易忽略的错误

    编写Javascript的开发者都知道,JS虽然没有类(ES6添加了class语法),但是可以模拟出OOP语言的类和面向对象的概念,比如我们都知道的一句话,Javascript中处处是对象,而面向对象 ...

  2. JavaScript正则表达式函数总结

    /* 测试环境:Chrome 63.0.3239.132 */ JS中正则对象修饰符可选值为:"i" "g" "m",即忽略大小写 进行全局 ...

  3. Leetcode刷题C#版之 Length of Last Word

    题目: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return t ...

  4. Spring Boot让开发如此简单

    从html到asp后一直专注.net开发,从.net诞生到如今,从winform到webform,从asp.net到.net mcv,从.net mvc到.net core,从ado.net到linq ...

  5. php常见面试题

    1.如何取得来访者的IP地址? $_SERVER['RRMOTE_ADDR']; $_SERVER['CLIENT_IP']; $_SERVER['HTTP_X_FORWARED_FOR']; 2.$ ...

  6. IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理

    1.前言 一个安全的信息系统,合法身份检查是必须环节.尤其IM这种以“人”为中心的社交体系,身份认证更是必不可少. 一些PC时代小型IM系统中,身份认证可能直接做到长连接中(也就是整个IM系统都是以长 ...

  7. network programming-简单的TCP客户服务器编程

    简单的TCP程序客户端流程:创建套接字(套接字用IP地址:端口号)表示)socket()->请求连接connect()->交换数据 send()/recv()->关闭连接 close ...

  8. hexo持续更新记录

    port:50187

  9. String不可变StringBuffer可变

    String是一个类,也可以表示字符串数据类型 String:是对象不是原始类型.为不可变对象,一旦被创建,就不能修改它的值.对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值 ...

  10. web前端开发工程师工资多少

      做web前端开发工程师工资高不高?下面千锋小编为大家分析一下:作为目前互联网行业中的主流技术,Web前端一直是占有重要的地位.尤其是近年来HTML5技术的突飞猛进,使Web前端技术有了更好的发展. ...