【移动开发】SQLite数据库使用 数据类型小结
在我们平时做Android项目,不管是应用还是游戏,都会用到SQLite数据库,在这里我还是简单的整理了一下。 1.简介 SQLite 是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。 其特点是高度便携、使用方便、结构紧凑、高效、可靠。 与其他数据库管理系统不同,SQLite 的安装和运行非常简单,在大多数情况下 - 只要确保SQLite的二进制文件存在即可开始创建、连接和使用数据库。如果您正在寻找一个嵌入式数据库项目或解决方案,SQLite是绝对值得考虑。
一般的数据库采用的是固定的静态数据类型,SQLite采用动态数据类型,创建一个表时,可以在 CREATE TABLE 语句中指定某列的数据类型,但是你可以把任何数据类型放入任何列中。当某个值插入到数据库时,SQLite将会检查它的类型,如果该类型与关联的列不匹配,SQLite则会尝试将该值转换成该列的类型,如果不能转换,则该值将作为本身的类型存储,比如可以把一个字符串(String)放入 INTEGER 列。SQLite称这为“弱类型”。但有一个特例,如果是INTEGER PRIMARY KEY,则其他类型不会被转换,会报一个“datatype missmatch”的错误。 在事务处理方面,SQLite通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只有一个可以写入数据。在某个进程或线程想数据库执行写操作之前,必须获得独占锁。在获得独占锁之后,其他的读或写操作将不会再发生。 此外,SQLite 不支持一些标准的 SQL 功能,特别是外键约束(FOREIGN KEY constrains),嵌套 transcaction 和 RIGHT OUTER JOIN 和 FULL OUTER JOIN,还有一些 ALTER TABLE 功能。 除了上述功能外,SQLite 是一个完整的 SQL 系统,拥有完整的触发器,交易等等。 2.Android 集成了 SQLite 数据库 Android 在运行时(run-time)集成了 SQLite,所以每个 Android 应用程序都可以使用 SQLite 数据库。对于熟悉 SQL 的开发人员来时,在 Android 开发中使用 SQLite 相当简单。但是,由于 JDBC 会消耗太多的系统资源,所以 JDBC 对于手机这种内存受限设备来说并不合适。因此,Android 提供了一些新的 API 来使用 SQLite 数据库,Android 开发中,程序员需要学使用这些 API。 数据库存储在 data/data/<项目文件夹>/databases/ 下。 A.数据类型 1.NULL 空值 2.INTEGER 带符号的整型 3.REAL 浮点型 4.TEXT 字符串文本 5.BLOB 二进制对象
但实际上,sqlite3也接受如下的数据类型: smallint 16 位元的整数。 interger 32 位元的整数。 decimal(p,s) p 精确值和 s 大小的十进位整数,精确值p是指全部有几个数(digits)大小值,s是指小数点後有几位数。如果没有特别指定,则系统会设为 p=5; s=0 。 float 32位元的实数。 double 64位元的实数。 char(n) n 长度的字串,n不能超过 254。 varchar(n) 长度不固定且其最大长度为 n 的字串,n不能超过 4000。 graphic(n) 和 char(n) 一样,不过其单位是两个字元 double-bytes, n不能超过127。这个形态是为了支援两个字元长度的字体,例如中文字。 vargraphic(n) 可变长度且其最大长度为 n 的双字元字串,n不能超过 2000 date 包含了 年份、月份、日期。 time 包含了 小时、分钟、秒。 timestamp 包含了 年、月、日、时、分、秒、千分之一秒。 datetime 包含日期时间格式,必须写成'2010-08-05'不能写为'2010-8-5',否则在读取时会产生错误! B.简单使用 Android平台下数据库相关类: Activites 可以通过 Content Provider 或者 Service 访问一个数据库。 C.创建数据库
Android不自动提供数据库。在 Android 应用程序中使用 SQLite,必须自己创建数据库,然后创建表、索引,填充数据。Android 提供了 SQLiteOpenHelper 帮助你创建一个数据库,你只要继承 SQLiteOpenHelper 类,就可以轻松的创建数据库。 SQLiteOpenHelper 类根据开发应用程序的需要,封装了创建和更新数据库使用的逻辑。SQLiteOpenHelper 的子类,至少需要实现三个方法: package com.dandan.fm.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; /** * 可以通过SQLiteOpenHelper的以下两个方法来或得SQLiteDatabase的对象: * getReadableDatabase() 创建或者打开一个查询数据库 * getWritableDatabase() 创建或者打开一个可写数据库 */ public class DBHelper extends SQLiteOpenHelper { /** * 构造函数,必须实现 * @param context 上下文路径 * @param name 数据库名称 * @param factory 可选游标工厂,通常为NULL * @param version 当前数据库版本号 */ public DBHelper(Context context,String name,CursorFactory factory,int version) { super(context,name,factory,version); } //数据库第一次创建时会调用,一般在其中创建数据库表 @Override public void onCreate(SQLiteDatabase db) { //使用execSQL()方法执行DDL语句,如果没有异常,这个方法没有返回值 db.execSQL("create table user(id INTEGER PRIMARY KEY AUTOINCREMENT," + "name varchar(20),address TEXT)"); } //当数据库需要修改的时候,Android系统会主动的调用这个方法。 @Override public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion) { //数据库版本升级时,更新数据库操作 } //打开数据库时的回调函数,一般不会用 @Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); } @Override public synchronized void close() { super.close(); } } 说明: 创建表和索引
db.execSQL("create table user(id INTEGER PRIMARY KEY AUTOINCREMENT," + "name varchar(20),address TEXT)"); 给表添加数据 有两种方式添加数据: db.execSQL("INSERT INTO user (name,address) VALUES ('woniu'," + "'http://http://smallwoniu.blog.51cto.com/')"); 2.SQLiteDatabase 对象的 insert(),update(),delete() 方法。这些方法把 SQL 语句的一部分作为参数。如:
private SQLiteDatabase mDataBase = null; private static final String USER_TABLE = "user"; public void getDB() { //创建DBHelper对象 DBHelper db = new DBHelper(this,USER_TABLE,null,1); //获取可写SQLiteDatabase mDataBase = db.getWritableDatabase(); } public void insert() { //ContentValues对象,向其中插入键值对,键是数据库列名,值是插入到这一列的值 ContentValues cv = new ContentValues(); cv.put("name","LiuMing"); cv.put("address","ShangHai"); mDataBase.insert(USER_TABLE,cv); } public int update() { ContentValues cv = new ContentValues(); cv.put("name","MaLi"); //第三个参数where语句,相当于sql语句中where后面的语句,?是占位符 //第四个参数是占位符的值 return mDataBase.update(USER_TABLE,cv,"id = ?",new String[]{"1"}); } public int delete() { //和udate()类似 return mDataBase.delete(USER_TABLE,"id = ? and name = ?",new String[]{"1","MaLi"}); } 查询数据库 /** * 使用rawQuery()直接调用SELECT语句,最简单的查询方法 * 如果查询是动态的,使用rawQuery就会非常复杂 * @return Cursor可以迭代查询结果 */ public Cursor rawQuery() { return mDataBase.rawQuery("select * from user where id = ? and name = ?","LiuMing"}); } //使用SELECT语句段构建查询,SELECT语句内容做为query()方法的参数 public Cursor query() { String[] columns = {"name","address"}; //第二个参数: 要查询的列名 //第三个参数:where语句 //第三个参数:where语句中占位符的值 //第四个参数:对查询结果进行分组 //第五个参数:对分组结果进行限制 //第六个参数:对查询结果进行排序 return mDataBase.query(USER_TABLE,columns,new String[] {"1"},null); } 最后着重提及一下使用游标,不管如何执行查询,都会返回一个Cursor,Curosr主要方法如下: |