列举了 sqlite 数据库的基本操作


文章目录

  • 一、数据库
  • 1.1 定义
  • 1.2 获取(包括了创建、升级、降级)
  • 二、表
  • 2.1 定义
  • 2.2 操作
  • 2.2.1 创建表
  • 2.2.2 修改表
  • 2.2.3 删除表
  • 三、数据
  • 3.1 定义
  • 3.2 操作
  • 3.2.1 增
  • 3.2.2 删
  • 3.2.3 改
  • 3.2.4 查
  • 四、运行
  • 五、获取数据库文件


一、数据库

1.1 定义

通过 SQLiteOpenHelper 来定义一个 数据库。一般会在 onCreate() 中执行创表语句,生成数据库内的表。

public class ChinaDbHelper extends SQLiteOpenHelper {
    public ChinaDbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    	...
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
    
    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        super.onDowngrade(db, oldVersion, newVersion);
    }
}

1.2 获取(包括了创建、升级、降级)

通过 SQLiteOpenHelper.getWritableDatabase 来获取一个数据库,在 getWritableDatabase 中会调数据库的 onCreate() 、onUpgrade()、onDowngrade() 方法。

public void accessDB() {
    ChinaDbHelper chinaDbHelper = new ChinaDbHelper(this, "china.db", null, 1);
    // getWritableDatabase 时会调 onCreate、onUpgrade、onDowngrade
    chinaDb = chinaDbHelper.getWritableDatabase();
}
  • onCreate:创建回调
    在第一次调用 getWritableDatabase 时回调。
  • onUpgrade:升级回调
    在 version 变高,调用 getWritableDatabase 时回调。
  • onDowngrade:降级回调
    在 version 变低,调用 getWritableDatabase 时回调。

二、表

2.1 定义

通过 sql 语句定义。

一个名为 city1,列为 id、city_id,主键为 id,主键自增长的表:

city1 (id integer primary key autoincrement, city_id text)

2.2 操作

2.2.1 创建表

创建 city1、city2 表

public void createTable() {
    String createCity1 = "create table city1 (" +
        "id integer primary key autoincrement, " +
        "city_id text)";
    chinaDb.execSQL(createCity1);

    String createCity2 = "create table city2 (" +
        "id integer primary key autoincrement, " +
        "city_id text)";
    chinaDb.execSQL(createCity2);
}

2.2.2 修改表

更新 city1 表名至 city
给 city 中增加一列 city_name

public void updateTable() {
    String renameTable = "alter table city1 rename to city";
    chinaDb.execSQL(renameTable);
    String addColumn = "alter table city add column city_name text";
    chinaDb.execSQL(addColumn);
}

2.2.3 删除表

删除 city2 表

public void deleteTable() {
    String deleteTable = "drop table city2";
    chinaDb.execSQL(deleteTable);
}

删除所有表

其中 sqlite_sequence 表是 SQLite 的系统表。该表用来保存其他表的自增 id 最大值,删了会报错。

sqlite_master 也是 SQLite 的系统表。保存了所有表、索引的信息。

public static void deleteAllTable() {
    List<String> list = getAllTable();
    for (String s : list) {
        if ("sqlite_sequence".equals(s)) {
            continue;
        }
        String deleteTable = "drop table " + s;
        chinaDb.execSQL(deleteTable);
    }
}

// 获取库中所有表
public static List<String> getAllTable() {
    List<String> tables = new ArrayList<>();
    String getAllTable = "select name from sqlite_master where type='table' order by name";
    Cursor cursor = chinaDb.rawQuery(getAllTable, null);
    while (cursor.moveToNext()) {
        tables.add(cursor.getString(0));
    }
    cursor.close();
    return tables;
}

三、数据

3.1 定义

public class City {
    private int id;
    private String cityId;
    private String cityName;

3.2 操作

3.2.1 增

插入一条数据

public void insertCity(City city) {
    ContentValues values = new ContentValues();
    values.put("city_id", city.getCityId());
    values.put("city_name", city.getCityName());
    chinaDb.insert("city", null, values);
}

3.2.2 删

删除一条数据

public void deleteCity(City city) {
    chinaDb.delete("city", "city_id = ?", new String[]{city.getCityId()});
}

3.2.3 改

更新一条数据

public void updateCity(City city) {
    ContentValues values = new ContentValues();
    values.put("city_name", city.getCityName());
    chinaDb.update("city", values, "city_id = ?", new String[]{city.getCityId()});
}

3.2.4 查

获取所有数据

public List<City> getAllCity() {
        List<City> list = new ArrayList<>();
        Cursor cursor = chinaDb.rawQuery("select * from city", null);
        while (cursor.moveToNext()) {
            String cityId = cursor.getString(cursor.getColumnIndex("city_id"));
            String cityName = cursor.getString(cursor.getColumnIndex("city_name"));
            City city = new City(cityId, cityName);
            list.add(city);
        }
        cursor.close();
        return list;
    }

获取某条数据

public City getCity(String cityId) {
    Cursor cursor = chinaDb.rawQuery("select * from city where city_id = " + cityId, null);
    if (cursor.moveToNext()) {
        String _cityId = cursor.getString(cursor.getColumnIndex("city_id"));
        String _cityName = cursor.getString(cursor.getColumnIndex("city_name"));
        return new City(_cityId, _cityName);
    }
    cursor.close();
    return null;
}

四、运行

public static void behave(Context context) {
    accessDB(context);
    deleteAllTable();

    createTable();
    Log.d(TAG, "after create table: " + getAllTable());

    updateTable();
    Log.d(TAG, "after update table: " + getAllTable());

    deleteTable();
    Log.d(TAG, "after delete table: " + getAllTable());

    insertCity(new City("1", "北京"));
    insertCity(new City("2", "上海"));
    insertCity(new City("3", "广州"));
    Log.d(TAG, "after insert: " + getAllCity());

    City city = getCity("3");
    city.setCityName("深圳");
    updateCity(city);
    Log.d(TAG, "after update: " + getAllCity());

    deleteCity(city);
    Log.d(TAG, "after delete: " + getAllCity());
}

输出:

D/database-sqlite: after create table: [city1, city2, sqlite_sequence]
D/database-sqlite: after update table: [city, city2, sqlite_sequence]
D/database-sqlite: after delete table: [city, sqlite_sequence]
D/database-sqlite: after insert: [City{id=0, cityId='1', cityName='北京'}, City{id=0, cityId='2', cityName='上海'}, City{id=0, cityId='3', cityName='广州'}]
D/database-sqlite: after update: [City{id=0, cityId='1', cityName='北京'}, City{id=0, cityId='2', cityName='上海'}, City{id=0, cityId='3', cityName='深圳'}]
D/database-sqlite: after delete: [City{id=0, cityId='1', cityName='北京'}, City{id=0, cityId='2', cityName='上海'}]

五、获取数据库文件

数据库文件位于 /data/data/包名/databases 目录

  • 通过 Device File Explorer

Android 数据库 考题 安卓数据库调用_数据库

SQLiteDatabase 默认读写模式是 TRUNCATE,该模式下读写都必须同步。它会使用 journal 文件作为辅助。这时在 data 目录下看到的就是 db 和 db-journal。db 内就是最新数据。如上图所示。

当调用了 SQLiteDatabase 的 enableWriteAheadLogging() 方法,会将读写模式设为 WAL(write-ahead log),该模式下读可以并发,写必须同步。它会使用 shm、wal 文件作为辅助。这时在 data 目录下看到的是 db、db-shm、db-wal。db 内不一定是最新数据(可能还在 wal 文件中)。如下图所示。

关于读写模式,可见这里 和这里。

Android 数据库 考题 安卓数据库调用_Android_02

  • 通过 adb

adb exec-out run-as com.gdeer.gdtesthub cat /data/data/com.gdeer.gdtesthub/databases/china.db > china.db