文章类型: DATABASE
关键词: SQLiteOpenHelper,SQLiteDatabase,数据类型,使用
内容摘要: SQLiteOpenHelper与SQLiteDatabase的使用

SQLiteOpenHelper与SQLiteDatabase的使用

2019/4/30 9:39:16    来源:apple    阅读:

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();
)
↑ 上一篇文章:VC中的_WIN32_WINDOWS、_WIN32_WINNT、WINVER等宏定义 关键词:VC,_WIN32_WINDOWS,_WIN32_WIN.. 发布日期:2019/4/26 16:04:17
↓ 下一篇文章:Context与SQLiteDatabase的方法openOrCreateDatabase的区别 (context、SQLiteOpenHelper) 关键词:Context,SQLiteDatabase,方法,op.. 发布日期:2019/4/30 10:05:19
相关文章:
Context与SQLiteDatabase的方法openOrCreateDatabase的区别 (context、SQLiteOpenHelper) 关键词:Context,SQLiteDatabase,方法,openOrCreateDatabase,区.. 发布日期:2019-04-30 10:05
error C3872: "0xa0": 此字符不允许在标识符中使用 关键词:error,C3872,0xa0,此字符不允许在标识符中使用 发布日期:2017-10-12 10:05
html中dl、dt、dd、ul、li标记的使用 关键词:html,HTML,dl,dt,dd,ul,li,标记,使用 发布日期:2015-07-29 12:03
相关目录:.NETANDROIDDATABASEJAVA
我要评论
正在加载评论信息......