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. 使用websocket实现在线聊天功能

    很早以前为了快速达到效果,使用轮询实现了在线聊天功能,后来无意接触了socket,关于socket我的理解是进程间通信,首先要有服务器跟客户端,服务的启动监听某ip端口定位该进程,客户端开启socke ...

  2. java常用工具类[待补充]

    生成指定范围指定大小的随机数: String code = String.valueOf((int)(Math.random()*(9999-1000+1))).substring(0,4);

  3. MySQL创建带有编码的数据库

    mysql> create database chao default character set utf8 collate utf8_general_ci;

  4. php使用file_get_contents请求微信接口失败

    windows下的php,只需要到php.ini中把extension=php_openssl.dll前面的;删掉,重启服务就可以了.Linux下的PHP,就必须安装openssl模块,安装好了以后就 ...

  5. 使用VNC+SSH建立安全的远程桌面访问WINDOWS服务器

    用了一段时间的MONO,现在MONO也支持了ENTITY FRAMEWORK 6.但是实际上在LINUX环境里用MYSQL还是会有很多坑.并且之前在网络游戏服务端SCUT上扩展一些功能时候也遇到了一些 ...

  6. href与src 区别

    src 是可替换的文本支撑,将指向的内容引入文档当前标签所在的位置, 当浏览器解析到该标签时,将暂停其它资源的下载处理, 请求该标签的src ,下载指向的外部资源并应用到当前文档, 所以js 脚本一般 ...

  7. composer安装出现proc_open没有开启问题的解决方案

    今天在安装下载项目的时候,使用composer来安装依赖.遇到了 The Process class relies on proc_open, which is not available on yo ...

  8. Opencv 330 如何裁剪图片中大的目标?

    main.cpp cv::Mat CropImage(cv::Mat& src, cv::RotatedRect& rotatedRect); cv::Mat MaxBoxSelect ...

  9. java网络编程(6)——实现一个服务器把小写转大写

    实现一个服务器,通过我们发送的文本数据,然后转回大写放回,实现一个服务端与客户端的交互,用over来作为结束标记,具体代码如下: 客户端: package com.seven.tcp; import ...

  10. spring boot admin + spring boot actuator + erueka 微服务监控

    关于spring boot actuator简单使用,请看 简单的spring boot actuator 使用,点击这里 spring boot admin 最新的正式版本是1.5.3 与 spri ...