安卓 SQLite

SQLite学习整理

当程序中需要的数据量较大,且需要进行大量数据的插入、更新、查询等操作时,如果再使用文件方式来保存数据就显得效率低下。这时需要使用关系型数据库来对数据进行存储。SQLite数据库作为轻量级的关系型数据库,且小巧易用、具备关系型数据库的各种优点,因此被广泛用于手机、MP3等各种资源受限设备中。

 

SQLite使用C语言编写,完全独立化,使用时不需要额外的设置。具有如下特点:

·支持大多数ANSI SQL92标准

·支持数据库事务

·数据库位于一个单独的文件内,方便管理

·内存消耗小,且运行速度快

·提供简单且易用的API

·支持最大2TB的数据库等。

 

SQLite的官方网站是:http://www.sqlite.org/

 

数据库基础概念

SQlite 通过文件来保存数据库,一个文件就是一个数据库。

数据库里又包含数个表格;

每个表格里面包含了多个记录;

每个记录由多个字段组成;

每个字段都有其对应的值;

每个值都可以指定类型。

数据库名称即文件名;表格有自己的名称;记录没有名称;每个字段都有名称。在SQlite中,记录没有顺序的概念,不存在第一、第二此类的概念;只能通过查询来获取满足条件的记录。我们通过执行SQL指令来操作数据库

 

SQLite的使用

与SQLite相关的操作API存放在android.database.sqlite包下。Android系统中创建及操作SQLite数据库有两种途径,一是直接通过SQLiteDatabase类的对象来进行,另一种是继承SQLiteOpenHelper类自定义的数据库处理类。

 

几个相关的类

·SQLiteDatabase 数据库访问类:执行对数据库的插入记录、查询记录等操作。

·SQLiteOpenHelper 抽象类:通过从此类继承实现用户类,来提供数据库打开、关闭等操作函数。

·SQLiteCursor 查询结构操作类:用来访问查询结果中的记录。

 

SQLiteDatabase类

这个类是数据库访问类,包含了数据库操作的API,通过调用这些API可以完成对数据库的操作,如添加表格、添加记录、删除记录、查询等。

·openOrCreateDatabase(。。。)静态方法,用来创建一个SQLite数据库文件,方法返回值为数据库SQLiteDatabase对象。有两个不同的重载方法,允许传入作为SQLite数据的File对象或是指定SQLite数据库所在的位置及数据库名。可以通过根据返回值是否为null来判断数据库创建或打开成功。数据库默认在/data/data/<程序包名>/databases/这个目录下

·close()关闭数据库。当不再使用时可以调用这个方法关闭数据库

·deleteDatabase( DATABASE_NAME)删除数据库名为DATABASE_NAME的数据库。根据返回值判断是否删除成功

·execSQL执行SQL语句。这个方法不能执行选择语句或者其他带返回值的SQL。

·beginTransaction启动事务

·setTransactionSuccessful设置事务成功标志

·endTransaction结束事务

·insert(String table ,String nullColumnHack ,ContentValues values)向表格table中插入数据。数据来自于values。成功插入后返回新插入行的ID值,返回-1表示插入失败。ContentValues类似于map,存放键值对。提供了put(String key, Xxx values)key为数据列的列名,这个方法用于存入数据、getAsXxx(String key)方法用于取出数据

·public int update(String table,ContentValues values,String whereClause,String[] whereArgs)更新数据库。Table为表名;values为ContentValues对象,包含更新到表中的行数据;whereClause,where条件语句,用于精确指定要更新的行,不包含Where关键字。当值为null时,表示更新所有数据;whereArgs,where条件语句中表达式占位符?的参数值列表,只支持String类型。

·public int delete(String table,String whereClause,String[] whereArgs)。如果后两参数为null,则表示删除表名为table的表中的所有内容,不会删除这张表

·public Cursor rawQuery(String sql ,String[] selectionArgs)执行查询语句sql,返回的结果保存在Cursor实例中。程序中可以使用这个Cursor实例来实例化一个SimpleCursorAdapter,再将这个SimpleCursorAdapter作为参数传给listView的setAdapter,将结果显示出来。其中sql是要执行的查询语句,selectionArgs是参数列表,对应于sql中的占位符。关于Cursor的使用在Demo里面有介绍

·public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)完成查询操作,是将sql语句分开了,作为query的参数传递进来。返回值也是Cursor实例对象

 

 

SQLiteOpenHelper类

是一个抽象类,主要作用是完成数据库的创建和数据库版本的管理。在创建数据库时这个类用的比较多。使用时需要创建一个extends SQLiteOpenHelper,并实现onCreate、onUpdate抽象方法的子类来完成对数据库的各种操作。数据库文件默认在:/data/data/<程序包名>/databases/这个目录下。数据库名称一般后缀为.db3

·onCreate(SQLiteDatabase db)创建SQLiteOpenHelper子类的实例时,在其构造方法中会调用SQLiteOpenHelper的构造方法,这个方法会创建一个SQLite数据库。如果这个数据库是第一次创建,那么就会执行这个onCreate方法。方法传入的参数是构造方法创建的数据库的实例化。一般在这个方法中使用传入的db,调用它的方法进行表格的创建等。

·onUpdate(SQLiteDatabase db,int oldVersion,int new Version) 当需要对已经存在的数据库结构进行更新时,如修改表字段的名字、新增加表、字段,删除已有的表等,就可以使用这个方法。这个方法不需要显式的调用。当创建SQLiteOpenHelper子类的实例时,如果传入的版本参数与之前的版本不同就会被调用

·close关闭已打开的数据库。一般在onDestroy方法中被调用

·getReadableDatabas()创建或打开数据库

·getWriteableDatabase()以可读写方式创建或打开数据库,返回可读写数据库的SQLiteDatabase对象。如果数据库不能以写方式打开,则抛出SQLiteException异常。

getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。 

注意:getWritableDatabase(),getReadableDatabase的区别是当数据库写满时,调用前者会报错,调用后者不会,所以如果不是更新数据库的话,最好调用后者来获得数据库连接。     

·

 

 

数据库操作程序过程。

首先继承SQLiteOpenHelper,添加构造方法。这个方法中调用父类的构造方法,主要功能是完成数据库的创建。实现其两个虚函数,在这两个虚函数中可以添加一些其他的操作。然后创建这个子类的实例,完成数据库的创建。再调用这个实例的getReadableDatabase()或者getWriteableDatabase方法,返回SQLiteDatabase对象。这样就可以利用这个对象中提供的各种方法来操作数据库了。

 

 

 

 

创建表格操作

·String sql = “CREATE  TABLE  TAB_USER  ( _id  INTEGER  PRIMARY  KEY,  name TEXT  NOT  NULL)”;

·db.execSQL (sql);

添加向表格中一列

·String upgradesql = “ALTER  TABLE  TBL_USER  ADD  COLUMN  created_dt  timestamp  NOT  NULL DEFAULT  ‘2010-10-01  COLLATE  NOCASE;’”;

·db.execSQL(upgradesql);

插入数据

·ContentValues values = new ContentValues();

·values.put(“name” , “孙悟空”);

·values.put(“age” , 500);

·long rowid = db.insert(“person_inf” ,  null  , values);其中第二个参数可以为”_id”

删除表格

·db.delete(TBL_USER , “_id = ?” ,new String[] {5});删除_id = 5的一行

·db.beginTransaction();       

·String sql = "DROP TABLE "+tablename;      

·sqlDb.execSQL(sql); // 执行SQL语句

·sqlDb.setTransactionSuccessful();// 设置事务成功标志

·

 

 

 

常用的SQL语句

1.     create table 创建一个数据库表格

2.     drop table 从数据库中删除一个表格    DROP TABLE tablename;

3.SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;

4

 

 

 

 

Demo1

下面是实现SQLiteOpenHelper抽象类。实现两个抽象方法onCreate和onUpdate。可以写一个构造方法,调用父类的构造方法,传入参数,来创建一个SQLiteDatabase实例。onCreate方法和onUpdate不需要程序显式调用,是系统自动调用的。这两个方法中都可以使用系统传进来的SQLiteDatabase实例对象来进行表格的添加或更新等操作。

public class MyDbHelper extends SQLiteOpenHelper {

    // 声明数据库名字符串常量

    private static final String DB_NAME = "WiFiInfo.db3";  

    /**

     * 定义构造方法,用于创建数据库

     * @param context

     * @param version

     */

    public MyDbHelper(Context context, int version) {

       super(context, DB_NAMEnull, version);

    }

   

    /**

     * 第一次创建数据库后调用,可在此方法中完成数据库表的创建

     */

    @Override

    public void onCreate(SQLiteDatabase db) {

    }

 

    /**

     * 完成数据库结构的更新操作

     */

    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

      

    }

}

 

Demo2

这是一个实现获得数据库中所有表格的方法,返回的结果保存在Cursor中。

    public Cursor showAllTable(){       //显示创建的表格

       Cursor c = null;

       //StringBuffer str = new StringBuffer();

       try{

           // 启用事务

           sqlDb.beginTransaction();         

           String sql = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";    

           // 执行SQL语句

           c = sqlDb.rawQuery(sql, null);    

           // 设置事务成功标志

           sqlDb.setTransactionSuccessful();

       }catch(Exception ex){

           ex.printStackTrace();

       }finally{

           // 结束事务

           sqlDb.endTransaction();

       }

       return c;

Demo3

 

这个方法是使用query获得表名为tbName中所有的数据。相当于select * from tbName

    public Cursor getContacts(String tbName){

       //查询tbl表所有数据,并按照_id升序排列

       Cursor c =sqlDb.query(tbName, nullnullnullnullnull, "_id");

       return c;

    }

 

Demo4

游标Cursor是几乎所有的数据库都会使用。它位于结果集之上,可以对结果集进行前、后或随机的读取。在Android中,Cursor自身是一个标准的Java接口,定义了对结果集进行操作的各种方法。Android系统提供了默认的Cursor实现类,如果想再查询结果返回前进行控制,可以自定义继承自CursorFactory的类来对结果集进行操作。Cursor的值指向结果集中的第一个,如果取结果,首先要moveToNext。如果第一次调用moveToNext返回false也代表没有数据。

·moveToFirst移动游标到查询结果集第一行位置

·moveToLast移动游标到查询结果集最后一行位置

·moveToNext移动游标到结果集下一行

·moveToPosition移动游标到查询结果集指定位置

·getString(int columnIndex)获取columnIndex所指定列数据,并将其转换为String。如getString(0)返回结果中第0列的元素的String值。

·getInt(int columnIndex)获得columnIndex指定列的数据,返回32位int型数据

其他方法可以查看android SDK

下面的程序是将c中第0列的数据取出来,如果不是“android_metadata”存放在String[]类型的数组中。

while(c.moveToNext()){

        if(!c.getString(0).equals("android_metadata"))

        {

              ad[i]=c.getString(0);

            i++;  

        }              

       }

posted @ 2018-01-12 16:52  九间房  阅读(331)  评论(0编辑  收藏  举报