数据存储

记录一下Android中的三种数据存储方式的学习过程

目录

文件存储

  • 文件存储作为Android中最基本的一种数据存储方式,它不对存储的内容做任何的格式化处理,所有的数据都是原封不动保存到文件的,使用于存储简单的文本数据或者二进制数据。
写入数据到文件
步骤:
  • 一 获得一个FileOutPutStream对象:FileOutPutStream对象可以通过Context类中的openFileOutput()方法来获取,用法如下:
    FileOutPutStream out=context.openFileOutput("data",Context.MODE_PRIVATE);

可以看到,openFileOutput() 方法接收两个参数,第一个参数在创建文件的时候使用的文件名,第二个参数是固定的文件操作模式:MODE_PRIVATE(默认模式,当指定同样文件名的时候,所有写入的文件会覆盖原文件中的内容)MODE_APPEND(追加模式,如果指定的文件已经存在,则直接往里追加内容,如果不存在则创建新文件);

  • 二 获得一个BufferedWriter对象:
    BufferedWriter writer=new BufferedWriter(new OutPutStreamWriter(out));

其中out就是第一步中获取到的FileOutPutStream对象;

  • 三 调用BufferedWriter对象的write()函数开始写入数据:
    writer.write(data);

其中data即需要写入到文件的数据;

  • 四 释放BufferedWriter 对象:
    if(writer!=null)
        {
            writer.close();
        }
需要注意的问题
  • 在写入数据的第一个步骤 ,传入的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data/<packagename/files/>目录下的。

  • 使用完BufferedWriter对象要记得即使释放。

完整例子:
    private void saveData(String data)
    {
        FileOutPutStream out=null;
        BufferedWeiter writer=null;
        try
        {
            out=context.openFileOutPut("data",Context.MODE_PRIVATE);
            writer=new BufferedWriter(new OutPutStreamWriter(out));
            writer.write(data);
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if(writer!=null)
                {
                    write.close();
                }
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
    }
  • 在使用的时候直接调用这个方法就行。
从文件中读取数据
步骤
  • 从文件中读取数据的步骤跟写入数据到文件的步骤大同小异,至少思路是一样的:先获取相关对象,在调用相关方法写入数据;

  • 一 获取FileInputStream对象:通过调用ContextopenFileInput()函数获取,该函数值接收一个参数,该参数代表的是要读取的文件名,系统会自动到之前提到的目录/data/tata/<packageName>/files/目录下加载这个文件:

    FileInputStream in=context.openFileInput("data");
  • 二 获取BufferedReader对象:
    BufferedReader reader=new BufferedReader(new InputStreamReader(in));

其中in为第一步中获取到的FileInPutStream对象;

  • 三 调用BufferedReaderreadLine()方法,逐行读取数据并存入StringBuilder中:
    StringBuilder content=new StringBuilder();
    String line="";
    while((line=reader.readLine())!=null)
    {
        content.append(line);
    }
完整例子
    private void loadData()
    {
        FileInputStream in=null;
        BufferedReader reader=null;
        StringBuilder content=new StringBuilder();
        try
        {
            in=context.openFileInput("data");
            reader=new BufferedReader(new InputStreamReader(in));
            String line="";
            while((line=reader.readLine())!=null)
            {
                content.append(line);
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if(reader!=null)
                {
                    reader.close(); 
                }   
            }       
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
    }
  • 同样,使用时直接调用该方法即可。

SharedPreferences存储

  • 不同于文件的存储方式,SharedPreferences使用键值对的方式来存取数据。也就是说当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候通过这个键把相应的值取出来。(发现Android中不光SharedPreferences使用键值对,其他的很多譬如数据传递之类的也是以键值对的方式来实现的,例如intent.putExtra(“key”,”value”);)
写入数据到SharedPreferences
步骤
  • 一 获取一个SharedPreferences对象:Android中主要提供了三种方法用于得到SharedPreferences 对象:

    • 1)Context类中的getSharedPreferences()方法:
          SharedPreferences spf=context.getSharedPreferences("data",MODE_PRIVATE);

    getSharedPreferences()方法接受两个参数,第一个用于指定SharedPreferences文件(如果该文件不存在则会新建一个)的名称,第二个参数用于指定操作模式(和文件存储中openFileOutput()方法接受的第二个参数类似),主要有MODE_PRIVATE(默认,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写)MODE_MULTI_PROCESS(一般用于会有多个进程中队同一个SharedPreferences文件进行读写的情况)

    • 2)Activity类中的getPreferences()方法:

          SharePreferences pref=activity.getPrefreces(MODE_PRIVATE);

      getPreferences()getSharedPreferences()方法类似,区别是前者会自动将当前Activity的类名作为SharedPreferences的文件名,只需要传入一个指定操作模式的参数

    • 3)PreferenceManager类中的getDefaultSharedPreferences()方法:

          SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);

      这是一个接收Context参数的静态方法,它会自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件

  • 二 获取一个SharedPreferences.Editor对象:通过调用SharedPreferences对象的edit()方法来获取:

    SharedPreferences.Editor editor=spf.edit();

步骤一、步骤二可以合起来写:

    SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
  • 三 向获取到的SharedPreferences.Editor对象中添加数据:
    editor.putString("key","value");
    editor.putInt("key",value);
    editor.putBoolean("key",value);

可见,SharedPreferences支持多种不同的数据类型存储,对应地,想存入什么类型的数据,就put一下。
- 四 调用commit()方法提交第三步添加的数据,完成数据存储操作:

    editor.commit();
完整例子
    private void saveDataBySharedPreferences()
    {
        SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
        editor.putString("key","value");
        editor.putInt("key",20);
        editor.putBoolean("key",true);  
        editor.commit();
    }
需要注意的问题

-第一个步骤中获取SharedPreferences对象的三种方法应该根据程序的实际情况来选择。

从SharedPreferences中读取数据
步骤
  • 一 第一步仍然是先获取到一个SharedPreferences对象,方法同存储数据到SharedPreferences的步骤一

  • 二 获取到SharedPreferences对象之后就简单了。SharedPreferences对象中提供了一系列的get方法,每种get方法都对应了SharedPreferences.Editor中的put方法。直接看完整的例子吧~~~

完整例子
    private void loadDataBySharePreferences()
    {
        SharedPreferences spf=context.getSharedPreferences("data",MODE_PRIVATE);
        String value=spf.getString("key","");//第二个参数为当该键不存在对应的值的时候返回的默认值
        int valueInt=spf.getInt("keyInt",0);
        boolean valueBoolean=spf.getBoolean("keyBoolean",false);
    }

SQLite数据库存储

创建和升级数据库
  • SQLite支持标准的SQL语法。哈哈哈···表示不怕,毕竟SQL还是学过的~~

  • 不仅如此,Android中还提供了一系列的工具来让我们能够更加方便地管理数据库。

  • SQLiteOpenHelper类就是Android专门提供的帮助类,借助这个类就可以非常简单地对数据库进行创建和升级。SQLiteOpenHelper是一个抽线类,使用时需要创建一个自己的帮助类去继承它,然后重写其中的onCreate()onUpgrade()方法,并分别在两个方法中实现创建、升级数据库的逻辑。此外还有getReadableDatabase()getWritableDatabase()方法,这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象,不同的是,当数据库不可写入时(如磁盘空间已满)getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而getWritableDatabase()方法则将出现异常

步骤
  • 创建一个MyDatabaseHelper并继承自SQLiteOpenHelper,然后实现创建、升级数据库的逻辑:
package com.example.databasetest;

import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

public class MyDatabaseHelper extends SQLiteOpenHelper
    {
        private static final String CREATE_DATABOOK = "create table Book(id integer primary key autoincrement,author text,price real,pages integer,name text,category_id integer)";//创建数据库语句
        private static final String CREATE_DATABOOK_CATEGORY = "create table Category(id integer primary key autoincrement,catagory_name text,category_code integer)";//创建表语句

        private Context myContext;
        /*
        *创建MyDatabaseHelper构造函数,用于实例化MyDatabaseHelper对象
        *在使用时应给该方法传入相关参数,获得一个MyDatabaseHelper对象。
        *其中第二个参数databaseName为指定的数据库名,如"myDatabase.db",注意数据库后缀名也要加上。第四个参数为指定
        *数据库版本号。
        *当在程序中第一次执行getReadableDatabase()或getWritableDatabase()方法时就会检测当前程序中是否已存在
        *databaseName这个数据库,如果不存在则会创建该数据库,并调用MyDatabaseHelper的onCreate()方法。
        *如此,MyDatabaseHelper中的三个方法都能得到执行,创建、更新数据库也不在话下了。
        */
        public MyDatabaseHelper(Context context, String databaseName,
                CursorFactory factory, int version)
            {
                super(context, name, factory, version);
                // context
                // name:数据库名
                // factory:允许在查询数据的时候返回一个自定义的Cursor,一般传入null
                // version:数据库的版本号,可用于对数据库进行升级操作
                // TODO Auto-generated constructor stub
                myContext = context;
            }
        /*
        *onCreate()方法会在构建出MyDatabaseHelper实例并调用它的getReadableDatabase()或getWritableDatabase()
        *方法后得到执行,应当在这里执行创建数据表的操作。
        */
        @Override
        public void onCreate(SQLiteDatabase db)
            {
                db.execSQL(CREATE_DATABOOK); // 执行创建表语句
                db.execSQL(CREATE_DATABOOK_CATEGORY);
            }
        /*
        *onUpgrade()方法会在传入新的数据库版本号大于上一个数据库版本号(newVersion>newVersion)时得到执行,应当在这执行更新数据库的操作。
        */
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
            {
                //这里用switch来根据不同的版本来更新数据库,这样可以保证在跨版本升级的时候,每一次的数据库修改都能被全部执行
                switch (oldVersion)
                    {
                    case 1:
                        db.execSQL(CREATE_DATABOOK_CATEGORY);
                    case 2:
                        db.execSQL("alter table Book add column category_id integer");
                    default:

                    }
            }


    }

  • 数据库操作,说到底无非就四种:CRUD,即增(C–Create)、删(D–Delete)、改(U–Update)、查(R–Retrieve),对应的SQL命令就是insert、delete、update、select。哈哈哈~所以也多大难度了,构建好sql命令,并执行这个sql命令即可。具体怎么构建怎么执行,就看Android提供的方法啦~万变不离其宗,Android提供的方法也只是对操作sql命令的过程进行封装,将其简化而已。
增加数据
步骤
  • 一 获取MyDatabaseHelper对象:
    private MyDatabaseHelper dbHelper=new MyDatabaseHelper(context,"database.db",null,1);
  • 二 获取SQLiteDatabase对象:通过调用SQLiteOpenHelper的getReadableDatabase()getWritableDatabase()方法来获取:
    SQLiteDatabase database=dbHelper.getWritableDatabase();

因为MyDatabaseHelper继承自SQLiteOpenHelper,所以可以直接dbHelper从调用getWritableDatabase()方法。

  • 三 构建ContentValues对象,并传入需要添加的数据,调用SQLiteDatabase中的insert()方法执行插入数据操作:ContentValues提供一些列的put()方法重载,用于向ContentValues中添加数据,只需要将表中的每个列名以及相应的待添加的数据传入即可,最后调用insert()方法。insert()方法接收三个参数,第一个为需要插入数据的表的名字,第二个参数用于在未指定添加数据的情况下给某些可空的列自动赋值NULL,第三个为ContentValues对象:
ContentValues values=new ContentValues();
// 第一条数据
// values.put(KeyId, 2);
values.put(keyAuthor, "xiongda");
values.put(KeyPrice, 53.0);
values.put(KeyName, "The Da Vinci Code");
values.put(KeyPages, 500);
db.insert("Book", null, values);//调用insert()
values.clear();//注意每次insert()之后都要清空一下ContentValues对象,以便装入新的数据
// 第二条数据
// values.put(KeyId, 3);
values.put(keyAuthor, "Dan");
values.put(KeyPrice, 19.5);
values.put(KeyPages, 265);
values.put(KeyName, "The Symbol");
db.insert("Book", null, values);
values.clear();
删除数据
步骤
  • 一 获取MyDatabaseHelper对象:
    private MyDatabaseHelper dbHelper=new MyDatabaseHelper(context,"database.db",null,1);
  • 二 获取SQLiteDatabase对象:通过调用SQLiteOpenHelper的getReadableDatabase()getWritableDatabase()方法来获取:
    SQLiteDatabase database=dbHelper.getWritableDatabase();

因为MyDatabaseHelper继承自SQLiteOpenHelper,所以可以直接dbHelper从调用getWritableDatabase()方法。

  • 三 调用SQLiteDatabase的delete()方法执行删除操作:delete()方法接收三个参数,第一个参数为操作的表名,第二、第三个参数用来约束删除某一行或某几行的数据,不指定的话则默认删除所有行:
    database.delete("Book","pages>?",new String[]{"500"});//其中第二个参数中的?号相当于占位符,第三个参数中的数据为填充到该占位符的数据。
修改数据
步骤
  • 第一第二步和增加、删除数据的前两个步骤相同

  • 二 调用SQLiteDatabase的update()方法执行更新数据的操作:该方法接收四个参数,第一个为操作的表名,第二个为装载更新数据的ContentValues对象,第三、第四个参数用来约束更新某一行或某几行中的数据,如果不指定则默认更新所有行:

    db.update("Book",values,"name=?",new String[]{"The Davinci Code"});
查询数据
步骤
  • 第一第二步和增加、删除数据的前两个步骤相同

  • 二 调用SQLiteDatabase的query()方法执行查询数据的操作:这个方法有很多的重载,而且参数非常多,不过参数的用法和前面增删改三个函数的参数大同小异啦~~
    query()方法参数
    然后,创建一个Cursor对象来接收query()返回的cursor对象:

    //查询Book表中所有数据
    Cursor cursor=database.query("Book",null,null,null,null,null,null);
  • 三 遍历cursor,取出所有数据:
    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"));
                    textView.setText(name + "\n"
                            + author + "\n" + pages
                            + "\n" + price + "\n");
                }
            while (cursor.moveToNext());
        }
    cursor.close();//使用完cursor之后要及时释放cursor对象
  • 最后,其实也可以直接调用SQLiteDatabaseexecSQL(String sqlString)方法来执行增删改查操作,只需要传入SQL命令即可~~~

20151122 03:27 By Xiong

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值