Android两种数据库操作方式介绍

本文主要介绍关系型数据库 SQLite 和对象关系映射工具 ORMLite ,两种方式都可以满足Android多数据持久化存储的需求。

  1. SQLite
  • 简介:SQLite是一款Android内置的轻量级的关系型数据库,它的运算速度非常快,占用资源少,通常只需要几百K的内存就足够。SQLite不仅支持标准的SQL语法,还遵循了数据库的ACID事务(ACID,是指在可靠数据库管理系统(DBMS)中,事务(Transaction)所应该具有的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability))。

  • 使用:首先创建数据库我们创建MydataBaseHelper
    类并继承SQLiteOpenHelper(SQLiteOpenHelper是一个抽象类,意味着我们要使用它的话就需要创建一个类去继承它并实现其中的方法,分别是onCreate( )和onUpgrade( ))

MydataBaseHelper.java

public class MyDatabaseHelper extends SQLiteOpenHelper {
   //用于创建Book表
 public static final String CREATE_BOOK = "create table Book ("
         + "id integer primary key autoincrement, "
         + "author text, "
         + "price real, "
         + "pages integer, "
         + "name text, "
         + "catagory_id integer)";
 //用于创建Category表
 public static final String CREATE_CATEGORY = "create table Category ("
         + "id integer primary key autoincrement, "
         + "category_name text, "
         + "category_code integer)";
 private Context mContext;
 public MyDatabaseHelper(Context context, String name,
                         SQLiteDatabase.CursorFactory factory, int version) {
     super(context, name, factory, version);
     mContext = context;
 }
 //第一次创建数据库时会调用此方法
 @Override
 public void onCreate(SQLiteDatabase db) {
     db.execSQL(CREATE_BOOK);
     db.execSQL(CREATE_CATEGORY);
 }
 //数据库版本升级时会调用此方法
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
     /*第一版的数据库只有Book表,第二版的数据库增加了Category表,
     * 为了保证用户体验,在不干扰前一版的数据的情况下,实现对数据
     * 库的平滑升级,简单的可以用此方法进行判断在升级*/
     switch (oldVersion){
         case 1:
             db.execSQL(CREATE_CATEGORY);
         case 2:
             db.execSQL("alter table Book add column category_id integer");
         default:
     }
 }
}

在MainActivity中创建MyDatabaseHelper对象并调用getReadableDatabase( )或者进行数据库的创建getWritableDatabase( ) ,(两者不同点在于,当数据库不可写入时(如磁盘空间已满)getReadableDatabase( )方法返回的对象将以只读的方式去打开数据库,而getWritableDatabase( )方法则将出现异常);对于数据库的操作完成后都要database.close();防止内存泄漏;

//数据库文件名称
private static final String DATABASE_NAME = "BookStore.db";
//数据库版本号private static final int DATABASE_VERSION = 3;
private MyDatabaseHelper mMyDatabaseHelper;
mMyDatabaseHelper = new MyDatabaseHelper(this, DATABASE_NAME, null, DATABASE_VERSION);
mMyDatabaseHelper.getReadableDatabase();
  • 对数据库的增删改查
    向数据库添加数据
 SQLiteDatabase db = mMyDatabaseHelper.getReadableDatabase();
ContentValues values = new ContentValues();

values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
//向数据库插入数据
//**nullColumnHack**
//当values参数为空或者里面没有内容的时候,insert是会失败的(底层[数据库]//(http://lib.csdn.net/base/mysql)不允许插入一个空行),为了防止这种情况,要在这里指定一个列名,到时候如果发现将要插入的行为空行时,就会将你指定的这个列名的值设为null,然后再向数据库中插入。通过观察源码的insertWithOnConflict方法可以看到当ContentValues类型的数据initialValues为null或size<=0时,就会在sql语句中添加nullColumnHack的设置。
若不添加nullColumnHack则sql语句最终的结果将会类似insert into tableName()values();这是不允许的。
若添加上nullColumnHack则sql语句将会变成insert into tableName (nullColumnHack)values(null);这是可以的。
db.insert("Book", null, values);

values.clear();

values.put("name", "The Lost Symbol");
values.put("author", "Dan Brown");
values.put("pages", 510);
values.put("price", 19.96);
db.insert("Book", null, values);

更新数据库的数据

SQLiteDatabase db = mMyDatabaseHelper.getReadableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.56);
//更新数据库的数据
db.update("Book", values, "name=?", new String[]{"The Da Vinci Code"});

删除数据库的数据

SQLiteDatabase db = mMyDatabaseHelper.getReadableDatabase();
//删除数据库的数据
db.delete("Book", "pages > ?", new String[]{"500"});

查询数据(对数据库的查询操作有很多种方式,这里只给出常见的一种)

SQLiteDatabase db = mMyDatabaseHelper.getReadableDatabase();

//对数据库表进行查询,会返回游标
Cursor cursor = db.query("Book", null, null, null, null, null, null);

while (cursor.moveToNext()){
        String name = cursor.getString(cursor.getColumnIndex("name"));
        String author = cursor.getString(cursor.getColumnIndex("author"));
        int pages = cursor.getInt(cursor.getColumnIndex("pages"));
        double price = cursor.getDouble(cursor.getColumnIndex("price"));

        Log.d("Query BookStore.db", name);
        Log.d("Query BookStore.db", author);
        Log.d("Query BookStore.db", pages+"");
        Log.d("Query BookStore.db", price+"");
}
cursor.close();

数据库的事务操作

  • 模拟一个应用场景:进行一次转账操作,银行会将转账的金额先从你的账户中扣除,然后再向收款方的账户中添加等量的金额。看上去好像没有什么问题,可是当你的账户的金额刚刚被扣除,这是由于一些异常原因导致对方收款失败(比如突然断电),这一部分钱就凭空消失了,当然银行自然会考虑到这个问题,它会保证扣钱和收款的操作要么一起完成,要么都不会成功,而使用的技术就是事物了。
SQLiteDatabase db = mMyDatabaseHelper.getReadableDatabase();

//开启事务
db.beginTransaction();

try {
        db.delete("Book", null, null);

        Toast.makeText(MainActivity.this, 删除数据成功",Toast.LENGTH_SHORT).show();

        /*if (true){
            throw new NullPointerException();
        }*/

        ContentValues values = new ContentValues();

        values.put("name", "Game of Thrones");
        values.put("author", "George Martin");
        values.put("pages", 720);
        values.put("price", 20.15);

        db.insert("Book", null, values);

        //事务已经执行成功
        db.setTransactionSuccessful();

        Toast.makeText(MainActivity.this, "插入数据成功", Toast.LENGTH_SHORT).show();

} catch (NullPointerException e) {
    e.printStackTrace();
} finally {
    //结束事务
    db.endTransaction();
}
  • ORMLite
    简介:
    首先可以去它的官网看看www.ormlite.com,它的英文全称是Object Relational Mapping,意思是对象关系映射;如果接触过Java EE开发的,一定知道Java Web开发就有一个类似的数据库映射框架——Hibernate。简单来说,就是我们定义一个实体类,利用这个框架,它可以帮我们吧这个实体映射到我们的数据库中,在Android中是SQLite,数据中的字段就是我们定义实体的成员变量。
    使用:
  1. 下载 ORMLite Jar首先去ORMLite官网下载jar包,对于Android为:ormlite-android-4.48.jar
    和 ormlite-core-4.48.jar
    具体可从参考:http://www.jianshu.com/p/05782b598cf0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容