Database 笔记

  • SQLiteOpenHelper
  • SQLitDatabase
  • SQLitCursor

虽然很久以前就用上 SQLite,但是一直没有整理,在这里做下笔记
不过最后发现来来去去还是同样的东西,在这篇写完之后研究一下用文件来做对数据的持久化
参考并强力推荐 Android SQLite详解

建库建表

SQLiteOpenHelper 类主要用于帮助建数据库和建表

  • 继承 SQLiteOpenHelper
public class DatabaseHelper extends SQLiteOpenHelper {

    /**
     * 数据库的版本,upgrade 可以实现版本的变更
     */
    private static final int VERSION = 1;

    /**
     * 数据库的名字
     */
    private static final String DATABASE_NAME = "App";

    public DatabaseHelper(Context context){
        super(context,DATABASE_NAME,null,VERSION);
    }
    //数据的类型
    private static final String TEXT = "TEXT";
    private static final String INTEFER = "INTEFER";
    private static final String REAL = "REAL";

    //建表语句
    private static final String CREATE_NEWS_TABLE
            = String.format(Locale.getDefault(),
            "create table if not exists %s (" +
                    "%s %s, "+
                    "%s %s)",
            LocalDatabaseContract.News.NEWS_TABLE_NAME_T,
            LocalDatabaseContract.News.NEWS_TITLE,TEXT,
            LocalDatabaseContract.News.NEWS_IMGURL,TEXT);

    @Override
    public void onCreate(SQLiteDatabase db) {
        //执行建表语句
        db.execSQL(CREATE_NEWS_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //在升级数据库的时候重写该方法

    }
}

上面的 LocalDataBaseContract 以枚举的方式来用来保存表的字段 :

public class LocalDatabaseContract {
    public enum News{
        NEWS_TABLE_NAME,
        NEWS_TITLE,
        NEWS_IMGURL
    }
}

对于数据库的操作

借助 SQLiteOpenHelper 的实例来获取 SQLiteDatabase 类的实例,

mDatabaseHelper = new DatabaseHelper(mContext);
mDatabase = mDatabaseHelper.getWritableDatabase();

一个比较特殊的方法就是

//void execSQL (String sql);
//Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.

mDatabase.execSQL("");

参数里的字符串必须是完整的、标准的 SQL 语句,才可以返回正确的数据。
比如一个插入数据的操作可以这样写:

//往 person 表插入一条 name:UserName,age:18 的数据
mDatabase.execSQL("insert into person(name, age) values('UserName', 18)");
mDatabase.execSQL("insert into person(name, age) values(?,?)", new Object[]{"UserName", 18}); 

但这种方法比较麻烦,一般还是会使用 SQLiteDatabase 封装好的方法

  • 插入数据:
String title = "";
String ImgUrl = "";
//ContentValues 对象,类似一个 map 通过键值对的形式存储值
ContentValues contentValues = new ContentValues();
contentValues.put(LocalDatabaseContract
                        .News.NEWS_TITLE.toString(),title);
contentValues.put(LocalDatabaseContract
                        .News.NEWS_IMGURL.toString(),ImgUrl);
//执行插入操作,如果返回值小于 0 代表操作失败
long rowId = mDatabase.insert(
               LocalDatabaseContract.News.NEWS_TABLE_NAME.toString()
               ,null,contentValues);
if (rowId < 0){
     //数据库存储失败
}

insert 第一个参数是表名;第二个参数表示如果插入的数据每一个值都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;第三个数据就是插入的数据。

  • 删除数据
//开启事务
mDatabase.beginTransaction();
//删除表内 id 为 7 的数据
mDatabase.delete(LocalDatabaseContract.News.NEWS_TABLE_NAME
                      , "Id = ?", new String[]{String.valueOf(7)});
//设置事务执行成功
mDatabase.setTransactionSuccessful();
  • 更新数据
mDatabase.beginTransaction();
//将 id 为 6 的那条数据的 Long 数据更新为 800
ContentValues contentValues = new ContentValues();
contentValues.put("Long ", 800);
mDatabase.update(LocalDatabaseContract.News.NEWS_TABLE_NAME,
        contentValues,
        "Id = ?",
        new String[]{String.valueOf(6)});
mDatabase.setTransactionSuccessful();
  • 查询数据
    在数据库的操作中,查询语句向来是最难的,用 SQLite 也不例外。
    查询的方法有两个:
public Cursor query(String table,String[] columns,String selection
,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);

另一个其实和 execSQL 差不多

//第二个参数照例是对应 sql 语句里的参数集合
public Cursor rawQuery(String sql, String[] selectionArgs)

在 query 中

table:表名称
columns : 列名称数组
selection : 条件字句,相当于 where
selectionArgs : 条件字句,参数数组
groupBy : 分组列
having : 分组条件
orderBy : 排序列
limit : 分页查询限制
Cursor : 返回值,相当于结果集ResultSet

例如,查询 age 为 18 的用户的数据

mDatabase = ordersDBHelper.getReadableDatabase();
cursor = mDatabase.query(LocalDatabaseContract.News.NEWS_TABLE_NAME,
        ORDER_COLUMNS,
        "age = ?",
        new String[] {"18"},
        null, null, null);
if (cursor.getCount() > 0) {
    List<User> userList = new ArrayList<User>(cursor.getCount());
    while (cursor.moveToNext()) {
        User user= parseOrder(cursor);
        UserList.add(user);
    }
    return userList;
}

而这里的返回值是一个 Cursor 类型的数据,这个类是一个游标的作用,可以借助它的方法来遍历查询的结果

getCount();//获取返回结果的总数
isFirst();//是否在第一个
isLast();//是否到了最后
moveToFirst();//移动到第一个
moveToLast();//移动到最后
move(int i);//移动到指定
moveToNext();//移动到下一个
moveToPrevious();//移动到上一个

基本上就这些东西,也不是说很简单,相反查询操作还是很讲究的,但实际上 App 可能更多时候使用文件来缓存数据,只有少数的数据会使用数据库来存储,所以很多时候简单的操作就可以满足要求了。

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

推荐阅读更多精彩内容