本篇介绍 SQLite 在 android 中的运用

1. Sqlite 介绍

SQLite 轻

优点:

  • 轻,体积小,几百 kb,常用于嵌入式设备
  • 绿,不用安装,直接解压就可以使用
  • 跨平台,symbain,linux,windows,mobile android
  • 单一文件

缺点:

  • 多线程操作比较差劲
  • 对 sql 的支持不全面,不支持直接修改表结构

2. SQLiteOpenHelper

2.1 简介

在 android 中,通过 SQLiteOpenHelper 操作 sqlite

public class MyOpenHelper extends SQLiteOpenHelper {
    private final static String TAG = "MyOpenHelper";

    public MyOpenHelper(Context context) {
        // context 上下文
        // name 数据库的名字,若为 null,就是在内存中创建一个临时数据库
        // factory 游标工厂,一般传 null ,使用系统默认游标
        // version 数据库的版本号,从 1 开始
        super(context, "test.db", null, 1);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d(TAG, "onCreate");
        // 数据库文件第一次创建的回调,我们一般做表结构的创建和数据库初始化操作
        // sqlite 中 id 列我们一般命名为 _id
        // 存到数据库中时,都是字符串
        db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20),phone varchar(20))");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 数据库升级的时候执行一些操作
        // db.execSQL("alter table info add age integer");
        // 可根据新旧版本号进行不同的跨版本升级操作
        Log.d(TAG, "onUpgrade, oldVersion = " + oldVersion + ", newVersion = " + newVersion);
    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.d(TAG, "onDowngrade");
        // 默认不允许降级,如果需要降级,重写此回调方法,注释掉下面这句
        // super.onDowngrade(db, oldVersion, newVersion);
    }
}

2.2 sql 增删改查

增删改查操作(通过 sql 语句):

public class MainActivity extends Activity {
    public final static String TAG = "MainActivity";
    MyOpenHelper openHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        openHelper = new MyOpenHelper(this);
        // getReadableDatabase 和 getWritableDatabase 在大部分情况下作用相同
        // 创建(数据库文件不存在的时候)或者打开数据库得到的都是可读可写的数据库
        // 磁盘满的时候 getReadableDatabase 返回只读数据库,getWritableDatabase 报错
        SQLiteDatabase database = openHelper.getReadableDatabase();
        insert();
        query();
    }

    public void insert() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        String sql = "insert into info (name,phone,age) values('zhangsan','123',12)";
        // 没有返回值,无法知道操作是否成功
        database.execSQL(sql);
        database.close();
    }

    public void query() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        String sql = "select * from info";
        // 返回一个游标,通过游标访问所有结果集
        // 游标默认指向所有结果之前的一行
        Cursor cursor = database.rawQuery(sql, null);
        while (cursor.moveToNext()) {
            // 通过列的索引取出当前行某列的值,从 0 开始
            String name = cursor.getString(1);
            // 通过列名获取
            String phone = cursor.getString(cursor.getColumnIndex("phone"));
            Log.d(TAG, "query, name = " + name + ", phone = " + phone);
        }
        cursor.close();
        database.close();
    }

    public void delete() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        String sql = "delete from info where name = 'lisi'";
        database.execSQL(sql);
        database.close();
    }

    public void update() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        String sql = "update info set phone='123' where name='zhangsan'";
        database.execSQL(sql);
        database.close();
    }
}

2.3 api 增删改查

增删改查操作(通过 android 提供的 api):

public class MainActivity extends Activity {
    public void insert() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        // 当 key 为 null 时的默认 key
        String nullColumnHack = null;
        // 每一个 ContentValues 封装一行数据
        ContentValues values = new ContentValues();
        values.put("name", "lisi");
        values.put("phone", "123");
        values.put("age", 22);
        // 返回插入行的 id,id = -1 时插入失败
        long id = database.insert("info", nullColumnHack, values);
        database.close();
    }

    public void query() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        Cursor cursor = database.query("info", new String[]{"name", "phone"}, "name = ?", new String[]{"zhangsan"}, null, null, null);
        while (cursor.moveToNext()) {
            String phone = cursor.getString(1);
        }
        cursor.close();
        database.close();
    }

    public void delete() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        // 表名称
        String table = "info";
        // where 的条件,不能包含 where 关键字
        String whereClause = "name = ?";
        // 参数
        String[] whereArgs = {"lisi"};
        // 返回受影响的行数
        int num = database.delete(table, whereClause, whereArgs);
        database.close();
    }

    public void update() {
        SQLiteDatabase database = openHelper.getReadableDatabase();
        // 用来封装需要修改的列和值
        ContentValues values = new ContentValues();
        values.put("phone", "110");
        int num = database.update("info", values, "name = ?", new String[]{"lisi"});
        database.close();
    }
}

2.4 对比

两种方式对比:

有没有返回值操作大量数据效率sql是否灵活sql是写错概率
execsql,rawqurey除了查询之外都没有sql任意写
封装好的api提供出来api才能用

2.5 事务

事务管理:

public void transact() {
    SQLiteDatabase database = openHelper.getReadableDatabase();
    database.beginTransaction();
    try {
        // sql 操作
        database.setTransactionSuccessful();

    } catch (Exception e) {

    } finally {
        database.endTransaction();
        database.close();
    }
}