Android复习之旅--SQLite

SQLite的知识点实在是太多了,将其一一整理出来可能会耗费太多时间,实在抱歉,或许以后会推出关于SQLite的其它知识点。在此只整理出SQLite的增删改查还有事务处理,并将它们封装到方法中,便于阅读。

SQLite简介
SQLite是一个轻量级数据库,支持SQL语言、事务处理等功能。SQLite没有服务器进程,它通过文件保存数据,该文件是跨平台的,可以放在其他平台中使用。

SQLite支持NULL、INTEGER、REAL(浮点数)、TEXT(字符串)和BLOB(二进制对象,1为true,0为false)5种数据类型。

但实际上SQLite也接收varchar(n)、char(n)、decimal(p,s)等数据类型,只不过在运算或保存时会转换成对应的5种数据类型。因此可以将各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型。这也是SQLite数据库的最大特点。

数据库文件保存的位置

/data/data/<packagename>/databases/xxx.db
数据库在创建的时候默认会创建一张表(metadata.db)来保存系统语言环境

数据库增删改查的SQL语句

  • 增加:insert into 表名(字段名,...) values(值,...)
  • 删除:delete from 表名 where 条件
  • 更新:update 表名 set 字段名=值,... where 条件
  • 查询:select 字段名 from 表名 where 条件

添加约束

在数据库表中,往往会给某些字段添加约束来满足特定的需求

  • 主键:primary key (字段 ... primary key)
  • 外键:references (字段 ... references data2 (主键))
  • 非空:not null(字段 ... not null)
  • 唯一:unique (字段 ... unique)
  • 默认值:default (字段 ... default 默认值)

SQLiteOpenHelper类的常用方法

这是一个抽象类,该类用于创建数据库和数据库版本更新。需要创建新的类来继承

void onCreate(SQLiteDatabase db);  //创建数据库时调用,子类必须重载此方法
void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);  //数据库版本更新时调用,子类必须重载此方法
SQLiteDatabase getReadableDatabase();  //创建或打开一个只读的数据库
SQLiteDatabase getWritableDatabase();  //创建或打开一个读写的数据库

SQLiteDatabase类的常用方法

  • 执行带占位符的SQL语句实现增删改查

    /** 带占位符的SQL语句;条件值  */
    void execSQL(String sql, Object[] bindArgs); 
    /** 带占位符的SQL语句;条件值  */
    Curosr rawQuery(String sql, String[] selectionArgs); 
    
  • 或调用API中的方法实现增删改查

    /** 表名;一般为null即可;添加的内容*/
    long insert(String table, String nullColumnHack, ContentValues values); // -1为添加失败
    
    /** 表名;条件;条件值*/
    int delete(String table, String whereClause, String[] whereArgs); // 返回受影响的行数
    
    /** 表名;修改的内容;条件;条件值*/
    int update(String table, ContentValues values, String whereClause, String[] whereArgs); // 返回受影响的行数
    
    /** 表名;返回的列;条件;条件值;group by;having;order by */
    Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy); //返回结果集
    
    void close();  //关闭数据库
    

两种增删改查的优缺点

  • 自己写sql语句
    • 灵活
    • 资源占用小
    • 可以实现表的级联查询
  • google的现成API
    • 方便
    • 资源开销比较大
    • 有返回值

Cursor接口的常用方法

Cursor是一个游标接口,在数据库操作中返回值,相当于结果集ResultSet

boolean moveToNext(); //移动光标到下一行
boolean moveToFirst(); //移动光标到第一行
boolean moveToPosition(int position); //移动光标到指定位置
int getCount();  //返回Cursor中的行数
int getPosition();  //返回当前Cursor的位置

int getColumnIndex(String columnName);  //返回指定列的索引值,如不存在则返回-1
int getInt(int columnIndex);  //返回指定列的整数值
String getString(int columnIndex);  //返回指定列的字符串

数据库的常用操作

创建一个类继承自SQLiteOpenHelper,复写父类的方法

  public class PersonDBOpenHelper extends SQLiteOpenHelper {

      public PersonDBOpenHelper(Context context) {
          //上下文,数据库名称,游标工厂(默认为null即可),版本号
          super(context, "rixin", null, 1);
      }

      @Override
      public void onCreate(SQLiteDatabase db) {
          // 创建SQLite数据表(数据库第一次创建时调用)
          db.execSQL("create table info (_id integer primary key autoincrement,name varchar(20),age integer)");
      }

      @Override
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          // 数据库的版本升级时调用
          Log.w("info", "数据库升级了");
      }
  }

实例化数据库类

PersonDBOpenHelper helper = new PersonDBOpenHelper(this);

添加记录

/**
 * 添加记录
 * name:要添加记录中的某个字段名
 * age:要添加记录中的某个字段名
 */
public void insertRecord(String name, int age) {
    SQLiteDataBase db = helper.getWritableDatabase(); // 打开一个读写的数据库
    // db.execSQL("insert into info(name,age) values(?,?)", new String[]{name, age});

    ContentValues values = new ContentValues();
    values.put("name", name);
    values.put("age", age);
    long i = db.insert("info", null, values);
    if (i == -1) {
        Toast.makeText(this, "添加记录失败", 0).show();
    } esle {
        Toast.makeText(this, "添加记录成功", 0).show();
    }
    db.close();
}

删除记录

/**
 * 删除记录
 * name:要删除的记录中的某个字段名
 */
public void deleteRecord(String name) {
    SQLiteDatabase db = helper.getReadableDatabase(); // 打开一个只读的数据库
    // db.execSQL("delete from info where name=?", new String[]{name});

    int i = db.delete("info", "name=?", new String[]{name});
    if (i == 0) {
        Toast.makeText(this, "删除记录失败", 0).show();
    } else {
        Toast.makeText(this, "删除记录成功", 0).show();
    }
    db.close();
}

更新记录

/** 
 * 更新记录
 * name:以name字段查询记录
 * age:要修改的字段
 */
public void updateRecord(String name, int age) {
    SQLiteDatabase db = helper.getReadableDatabase(); // 打开一个只读的数据库
    // db.execSQL("update info set age=? where name=?", new String[]{age, name});

    ContentValues values = new ContentValues();
    values.put("age", age);
    int i = db.update("info", values, "name=?", new String[]{name});
    if (i == 0) {
        Toast.makeText(this, "更新记录失败", 0).show();
    } else {
        Toast.makeText(this, "更新记录成功", 0).show();
    }
    db.close();
}

查询记录

/**
 * 查询记录
 * name:以name字段值查询记录
 */
public void queryRecord(String name) {
    SQLiteDatabase db = helper.getReadableDatabase(); // 打开一个只读的数据库
    //得到数据库查询的结果集的游标(指针)
   
    // Cursor cursor = db.rawQuery("select * from info", null); //查询全部记录
    // Cursor cursor = db.rawQuery("select age from info where name=?", new String[]{name});

    // Cursor cursor = db.query("info", null, null, null, null, null, null);
    Cursor cursor = db.query("info", new String[]{"age"}, "name=?", new String[]{name}, null, null, null);
    List<HashMap<String,int>> list = new ArrayList<HashMap<String,int>>();
    while (cursor.moveToNext()) {
        HashMap<String,int> hm = new HashMap<String,int>();
        hm.put("name", cursor.getString(cursor.getColumnIndex("name")));
        hm.put("age", cursor.getInt(cursor.getColumnIndex("age")));
        list.add(hm);
        hm = null;
    }
    cursor.close();
    db.close();
}

事务操作(银行转账等相关需要同步操作数据库的事务)

public void execTransaction(String name1, String name2) {
    SQLiteDatabase db = helper.getWritableDatabase();
    db.beginTransaction();
    try {
        // 转账
        db.execSQL("update info set money=money-100 where name =?", new String[]{name1});
        // 收到转账
        db.execSQL("update info set money=money+100 where name =?", new String[]{name2});
        // 标识事务执行成功,如果没有执行下面的代码,数据会回滚
        db.setTransactionSuccessful();
    } catch(Exception ex) {
        ex.printStackTrace();
        Log.i("rixin", "事务处理失败");
    } finally {
        db.endTransaction(); //关闭事务
        db.close();  //关闭数据库
    }
}

值得注意的是:操作完数据库后要记得关闭数据库,使用完Cursor对象后,也应及时关闭,否则会造成内存泄漏

利用sqlite3工具查看数据库的内容

sqlite3 xxx.db (进去后输入sql语句查询即可)

如果出现中文乱码 需要修改cmd的编码集,默认是gb2312

chcp 65001 (更改cmd窗口的编码的DOS命令,65001是utf-8)

adb shell   (挂载到Linux的空间)
cd data/data/<packagename>/databases  (进入应用的databases目录下)
ls -l  (列出当前目录下的所有文件的详细信息)
sqlite3 xxx.db  
select * from info;  (SQL语句查询,记得加上分号" ; "结束)

如果觉得使用命令来查看数据库表麻烦,也可以google搜索下载可以查看SQLite数据库的软件。导出数据库文件到电脑后即可使用软件来查看数据库里面的信息。

希望以上的内容对你们有所帮助吧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容