<第一行代码>chapter 6 Saving Data

数据持久化的几种方式

本章学习了三种存储数据的方式。

  1. 文件操作
  2. SharedPreferences存储键值对
  3. SQLite数据库操作

SharedPreferences

如果有一堆键值对需要存储,那么SharedPreferences最合适不过了。

获取SharedReferences对象

有几种方法,记录两种常用的

  1. Contex.getSharedPreferences()方法。这里有两个参数,第一个是存放SharedPreferences文件的文件名,如果文件不存在会自动创建一个。第二个参数是指定操作模式:MODE_PRIVATE代表只有当前应用程序才可以对这个文件进行读写。MODE_MULTI_PROCESS一般用于会有多个进程对同一个文件进行读写的情况。

     Context context = getActivity();
     SharedPreferences sharedPref = context.getSharedPreferences(
     getString(R.string.preference_file_key), Context.MODE_PRIVATE);
    
  2. Activity类中的getPreferences()方法。只接收操作模式参数,因为它会自动以当前类的名字创建文件。

     SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
    

写数据到Shared Preferences
    调用SharedPreferences的edit()方法来获取一个SharedPreferences.Editor对象,向Editor中添加数据,就像putInt(),putString()这样,然后利用commit()提交;

SharedPreferences.Editor editor = SharedPreferences.edit();
//put方法第一个参数是Key,第二个参数是value
editor.putStirng("name","Jack");
editor.commit();

从Shared Preferences

直接调用SharedPreferences的get方法,就像put差不多。

Stirng name;
sharedPref.getString("name",name);

Files

保存数据到文件

😶愚人节快乐啊。Talk is cheap,show you the code :

String FILENAME = "hello_file";
String data = "hello file";

FileOutputStream outputStream = openFileOutput(FILENAME,
                                        Context.MOIDE_PRIVATE);
outputStream.write(data.getBytes());
outputStream.close;

说是这么说还是要解释一下啊哈哈。

Context提供了一个openFileOutput()的方法来返回一个FileOutputStream对象,然后就可以对其操作啦。java.io掌握了,这里也就没问题了。

从文件中读取数据

同上,Context提供的openFileInput()方法返回一个FileInputStream对象,然后操作就可以了。

SQLite

要操作数据库,就需要我们去继承SQLiteOpenHelper这个抽象类来创建自己的数据库帮助类,进而完成对数据库的各种操作。

SQLite拥有的数据类型很简单,integer表示整型,real表示浮点型,text表示文本类型,blob表示二进制类型。

实现自己的SQLiteOpenHelper类

public class TestDbOpenHelper extends SQLiteOpenHelper {


    //create table 语句
    public static final String CREATE_BOOK = "create table Book ("
            + "id integer primary key autoincrement, "
            + "author text, "
            + "price real, "
            + "pages integer, "
            + "name text )";

    //为提示消息创建一个context
    Context mContext;



    public TestDbOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,int version) {
        super(context,name,factory,version);
        mContext = context;
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        //在onCreate方法中进行表的创建或者其他数据库初始化操作
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext,"Create table BOOK!",Toast.LENGTH_SHORT).show();
    }


    //调用构造方法时根据版本号的大小来确定是否进行数据库更新,如果版本号比当前版本号新则执行此方法里的操作
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

创建数据库

当你创建了一个SQLiteOpenHelper对象,然后调用getWritableDatabase()或者getReadableDatabase()方法时,如果数据库不存在,则会创建一个数据库。

对于Helper对象的构造方法的参数:Context context, String name, SQLiteDatabase.CursorFactory factory,int version。第一个context是操作数据库的对象,第二个name是数据库的名字,后面的factory是可以允许我们获取cursor,后面查询会用到,version是版本号,用于更新数据库操作。

添加数据

//添加数据操作很简单,就是向database里插入一条数据,这条数据以ContentValues的形式添加>
SQLiteDatabase database = myDatabaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
//装一条数据
values.put("name","The art of code");
values.put("author","hahaha");
values.put("pages",454);
values.put("price", 100);
database.insert("Book", null, values);
values.clear();

更新数据

//更新数据用到了database的update方法
SQLiteDatabase database = myDatabaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price",10.9);
database.update("Book", values, "name = ?", new String[]{"The art of code"});
values.clear();

database.update();

这里有四个参数,第一个是表名字,第二个是要更新的那条数据,第三四个参数对应了SQL语句里的where语句。

删除数据

SQLiteDatabase database = myDatabaseHelper.getWritableDatabase();
database.delete("Book", "pages > ?", new String[]{"400"});

database.delete()

第一个参数是表名,第二第三个参数指定约束,不指定则默认删除这个表的所有行。

查询数据

SQLiteDatabase database = myDatabaseHelper.getWritableDatabase();
Cursor cursor = database.query("Book",null,null,null,null,null,null);
if (cursor.moveToFirst()){
    do {
        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("MainActivity","book name is " + name);
        Log.d("MainActivity","book author is " + author);
        Log.d("MainActivity","book pages is " + pages);
        Log.d("MainActivity","book price is " + price);
    }while (cursor.moveToNext());
}
cursor.close();

query()方法

query方法有很多参数,源于查询这个功能比较复杂...

public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

table : 指定查询的表名

columns : 指定查询的列名

selection : 指定where的约束条件

selectionArgs : 为where中的占位符提供具体的值

groupBy : 指定需要group by 的列

having : 对group by后的结果进一步约束

orderBy : 指定对查询结果的排序方式

query方法会返回一个Cursor对象,查询到的对象需要从这个对象里面取出。利用其moveToNext()移动,然后getInt()获取这一行的某一列的数据,get方法里传入的是`cursor.getColumnIndex("pages"),是对于这一列数据的一个位置索引,用来定位这个数据在哪一列。

使用SQL操作数据库

除了用提供的API对数据库进行操作以外,我们还可以使用SQL语句来对数据库进行操作。

//添加数据
db.execSQL("insert into Book {name,author,pages,price) valuese(?,?,?,?)",
        new String[] {"hha","d“,"100","10"} );
//更新数据
db.execSQL("update Book set price = ? where name = ?",
        new String[] {"11","hha"} );
//删除数据
db.execSQL("delete from Book where pages > ?",new String {"500"});
//查询数据
db.rawQuery("select * from Book",null);

使用事务

//开启事务
db.beginTransaction();
//在异常捕获的代码块中去执行事务操作
try {
    //do something to db here.

} catch (Exception e) {
    //捕获异常
    e.printStackTrace();
} finally {
    //如果没有异常发生
    db.endTransaction()'
}

升级数据库的最佳写法

在onUpgrade()方法里对版本号进行判断来确定要执行的SQL语句。

switch (oldVersion){
    case 1:
        database.execSQL(CREATE_CATEGORY);
    case 2:
        database.execSQL("alert table Book add column category_id integer");
}

switch语句里是没有break的,这样就可以让版本不同的用户是按升级顺序执行对数据库的每一步操作。

总结

这章总结了数据存储的三种方式。
文件存储,SharedPreferences,数据库存储。
文件存储文本数据或者二进制数据,SharedPreferences存储键值对,数据库存储关系型数据。
要根据实际需要选择存储的方式。

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,078评论 25 707
  • 当生命遭遇病痛 我不想做展翅的雄鹰 搏击教育长空 亦不想做 修剪花圃的园丁 所有的往昔念想都成了泡影 孤独的 在冰...
    荷塘恋雨阅读 255评论 3 0
  • 今天的晨读文章是关于快速阅读的。对于我这个正在挑战100天33本书的人来说是非常实用的。但是,我想跳开这个话题来说...
    Lucky_mama阅读 196评论 1 2
  • 1.山无陵 天地合 乃敢与君绝 2.山有木兮木有枝 心悦君兮君不知 3.奴为出来难 教郎恣意怜 4.相思已是不曾闲...
    缁白阅读 619评论 2 3