Android数据持久化数据存储

来源:互联网 发布:高达 知乎 编辑:程序博客网 时间:2024/06/09 13:54

三种:文件存储 SharePreference存储 数据库存储     当然 除了这三种还可以将数据存储在SD卡  网络上

本文主要探究前三种存储方式以及开源库 LitePal

一. 文件存储

将所有数据原封不动的保存到文件当中

适用于: 存储一些简单的文本数据或二进制数据

如何做: 通过 Context类的 openFileOutput() 方法  

两个参数:    

1.文件名不可以包含路径,默认存储到/data/data/<packagename>/files/目录下

2.文件操作模式       

2.1 MODE_PRIVATE 文件名相同时会覆盖原文件内容  

   2.2 MODE_APPEND  如果该文件存在,就向里面追加内容;,不存在就新建;

        下面两个4.2版本后因为可以让其他应用程序进行读写而存在安全性漏洞 已经废弃 

具体是: MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE) 

返回FileOuputStream对象,得到此对象即可使用Java流的方式将数据写入文件

代码示例:

写入文件:

/** * 通过openFileOutput()方法获得一个FileOutputStream对象 * 再构建一个OutputStreamWriter对象 * 再使用OutputStreamWriter构建一个BufferWriter对象 * 通过BufferWriter将文本内容写入到文件中 */
public void save(){    String data = "Data to save";    FileOutputStream out = null;    BufferedWriter writer = null;    try{        out = openFileOutput("data", Context.MODE_PRIVATE);        writer = new BufferedWriter(new OutputStreamWriter(out));        writer.write(data);    }catch (IOException e){        e.printStackTrace();    }finally {        {            try {                if(writer != null){                    writer.close();                }            } catch (IOException e) {                e.printStackTrace();            }                    }    }}
读取文件:

public String read(){    FileInputStream in = null;    BufferedReader reader = null;    StringBuilder content = new StringBuilder();    try{        in = openFileInput("data");        reader = new BufferedReader(new InputStreamReader(in));        String line = "";        while ((line = reader.readLine()) != null){            content.append(line);        }    }catch (IOException e){        e.printStackTrace();    }finally {        if(reader != null){            try {                reader.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    return content.toString();}

二.   SharedPreferences 

SharedPreferences :采用键值对存储数据,支持多种不同数据类型存储。

1.存储 

存储路径:/data/data/<package name>/shared_prefs/

1.1获取Sharedpreference对象:

三种方式: 

a. Context类中的getSharedPreferences()方法

    b. Activity类中的getPreferences()方法

c. PreferenceManager 类中的 getDefaultSharedPreferences()方法

举例:

SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();editor.putString("name","HaHa");editor.putInt("number",18);editor.putBoolean("Human",true);editor.apply();
2.读取:

SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE);String  name = pref.getString("name","");int number = pref.getInt("number",0);boolean human = pref.getBoolean("Human",false);

三.SQLite数据库存储

当需要存储大量复杂的关系型数据时可以用到

+:SQLite数据类型:     

integer  整型

real       浮点型

text       文本类型

blob      二进制类型

1.创建数据库  

利用Android提供的SQLiteOpenHelper 帮助类:

a.  SQLiteOpenHelper是一个抽象类  自己创建一个帮助类继承SQLiteOpenHelper并重写 onCreat() 和 onUpdate()方法 进而实现创建、升级数据库的逻辑

b.  SQLiteOpenHelper两个重要方法:getReadableDatabase() getWritableDatabase() 可以创建或打开一个数据库 注意存储空间满时报错

c. SQLiteOpenHelper有两个构造方法可供重写:

一般使用参数少的那个,包含四个参数,

分别是(Context, 数据库名, 查询数据时返回的一个自定义Cursor 一般写null就好, 当前数据库版本号 用于对数据库进行升级等操作)

构建好SQLiteOpenHelper 的实例后,再调用 getReadableDatabase() 和 getWritableDatabase() 创建数据库

实例: 

  创建名为 BookStore.db的数据库 并在此数据库中新建一张Book表

   创建MyDataBaseHelper

public class MyDataBaseHelper extends SQLiteOpenHelper{        public static final String CREATE_BOOK = "create table Book("            +"id integer primary key autoincrement,"            +"author text,"            +"price real,"            +"pages integer,"            +"name text)";    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);        Toast.makeText(mContext,"Create SQLite数据库 succeeded",Toast.LENGTH_SHORT).show();    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}
调用:

private MyDataBaseHelper myDataBaseHelper;
myDataBaseHelper = new MyDataBaseHelper(this,"BookStore.db",null,1);
myDataBaseHelper.getWritableDatabase();

2.升级数据库

在MyDataBaseHelper中的onUpgrade方法中执行

例:

再添加一张 Category 表用于记录图书的分类 Category中有 id(主键) 分类名 分类代码几个列

将建表语句: 

 create table Category(        id integer primary key autoincrement,        category_name text,        category_code integer)

添加到 MyDataBaaseHelper中:

public static final String CREATE_CATEGORY = "create table Category("        +"id integer primary key autoincrement,"        +"category_name text,"        +"category_code integer";
@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    db.execSQL("drop table if exists Book");    db.execSQL("drop table if exists Category");    onCreate(db);}

调用时:
private MyDataBaseHelper myDataBaseHelper;
myDataBaseHelper = new MyDataBaseHelper(this,"BookStore.db",null,2);//将版本号增加
myDataBaseHelper.getWritableDatabase();


3.增删改查       

CRUD create  retrieve  update   delete  

SQLite: insert   select    update   delete

3.1添加数据 SQLiteDatabase中提供了一个insert()方法 

三个参数(表名,

在未指定添加数据情况下给某些可为空的列自动赋值NULL 一般直接传入null, 

Contentvalues对象 提供了一系列put方法重载,用于向ContentValues中添加数据)

SQLiteDatabase db = myDataBaseHelper.getWritableDatabase();ContentValues values = new ContentValues();//开始组装第一条数据values.put("name","DaVinci");values.put("author","bicaso");values.put("pages","666");values.put("price",10.16);db.insert("Book",null,values);// 插入/添加 第一条数据values.clear();//开始组装第二条数据values.put("name","hahaha");values.put("author","bicaso");values.put("pages","888");values.put("price",100.66);db.insert("Book",null,values);// 插入/添加 第二条数据//附:这里只对Book表里其中四列数据进行了组装 id没有赋值 因为在创建表的时候 将id设置为自增长了//SQLite语言添加数据db.execSQL("insert into Book(name,author,pages,price) values(?,?,?,?)",new String[] {"DaVinci","hahaha","666","10.16"});db.execSQL("insert into Book(name,author,pages,price) values(?,?,?,?)",new String[] {"mikailangqiluo","hahaha","888","100.66"});

3.2 删除数据

SQLiteDatabase db = myDataBaseHelper.getWritableDatabase();db.delete("Book","pages>?",new String[]{"500"});//SQLite语言db.execSQL("delete from Book where pages > ?",new String[]{"500"});

3.3 更改数据

//参数: 表名 ContentValues对象 约束更新某一行或某几行的数据
SQLiteDatabase db = myDataBaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price",18.88); //将价格price改变
db.update("Book",values,"name=?",new String[]{"DaVinci"});

//SQLite语言db.execSQL("update Book set price = ? where name = ?",new String[]{"10.16","DaVinci"});

3.4 查询数据

/** *  参数: 1: table      表名 *        2: columns    用于指定查询那一列 不指定则查询所有列 *      3-4: selection  selectionArgs 用于约束查询某一行或某几行数据 不指定则默认所有行数据 *        5: group by   指定需要去group by的列 不指定则表示不对查询结果进行group by操作 *        6: having     对group by后的数据进一步过滤 不指定则不过滤 *        7: orderBy    指定查询结果的排序方式 不指定则为默认 * *        调用query()方法后会返回一个Cursor对象 查询到的所有数据都将从这个对象中取出 */SQLiteDatabase db = myDataBaseHelper.getWritableDatabase();//查询Book中的所有数据Cursor cursor = db.query("Book",null,null,null,null,null,null);if(cursor.moveToFirst()){    do{        //    }while (cursor.moveToNext());}cursor.close();//SQLite 语言db.rawQuery("select * fromBook",null);

四.LitePal

LitePal 开源Android数据库框架  采用对象关系ORM模式 将常用的数据库功能进行封装 具体参考:http://github.com/LitePalFramework/LitePal

4.1 配置 LitePal

因为大多数开源项目都会将版本提交到jcenter上 所以只需在app/build.gradle文件中声明该开源库

4.1.1 编辑build.gradle文件 在dependencies 闭包中添加:

dependencies {...    compile 'org.litepal.android:core:1.3.2'...}
4.1.2配置litepal.xml文件

右击 app/src/main 目录->New->Directory 创建assets目录 然后在assets目录下创建literal文件 添加内容如下:

dbname 指定数据库名

version  数据库版本号

list      标签用于指定所有的映射类型

<?xml version="1.0" encoding="utf-8"?><litepal>    <dbname value="BookStore"></dbname>    <version value="1"></version>    <list>       <mapping class="com.demo.androidlearn01.Book"></mapping>    </list></litepal>

4.1.3 在AndroidManifest.xml中配置LitePalApplication  

android:name="org.litepal.LitePalApplication"

如果已经有了自定义的Application 只需在其中添加

private static Context context;
以及onCreate()方法中
context = getApplicationContext();
LitePalApplication.initialize(context);

4.2 使用LitPal

对象关系映射ORM 将面向对象的语言和面向关系的数据库之间建立一种映射关系

4.2.1 创建Book javabean类  Book类对应数据库中的Book表 类的每一个字段对应了表中每一个列

public class Book {    private int id;    private String author;    private double price;    private int pages;    private String name;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getAuthor() {        return author;    }    public void setAuthor(String author) {        this.author = author;    }    public double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }    public int getPages() {        return pages;    }    public void setPages(int pages) {        this.pages = pages;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}

正式操作: 增删改查

Connector.getDatabase();//自动创建数据库   //增   1.如在Book表中添加 press 列  直接修改代码 添加一个press字段就好 get set //    2.添加一张category表 只需新建一个Category类 然后在litepal.xml中<mapping ...></mapping> 添加 以及更改version版本号 //    3.添加数据  让Book类 继承 DataSupport :进行CRUD时必须继承    Book book = new Book();         book.setName("DaVinci");         book.setPages(666);         book.setAuthor("lalala");         book.setPrice(12.34);         book.setPress("Unkonw");         book.save(); //删DataSupport.deleteAll(Book.class,"price<?","15"); //改//更新Book book1 = new Book();book1.setName("DaVinci1");book1.setPages(999);book1.setAuthor("lalala");book1.setPrice(22.34);book1.setPress("Unkonw");book1.save();book1.setPrice(32.34);book1.save();Book book2 = new Book();book2.setPrice(42.34);book2.setPress("Auto");book2.updateAll("name = ? and author = ?","DaVinci","lalala");//注意 当把字段改为默认值时 是不能用set方法的 而是:Book book4 = new Book();book4.setToDefault("pages");book4.updateAll(); //查List<Book> books = DataSupport.findAll(Book.class);

List<Book> books1 = DataSupport.select("name","author").find(Book.class);//查询指定name author 两列数据List<Book> books2 = DataSupport.where("pages > ?","400").find(Book.class);//查询页数大于400的数据List<Book> books3 = DataSupport.limit(2).find(Book.class);//只查询前2条数据List<Book> books4 = DataSupport.limit(3).offset(1).find(Book.class);//查询表中 第2,3,4条数据 offset为位置偏移//也可以通过连缀组合完成复杂查询 下面这段表示查询Book表中 第11——20条 页数大于300 的name author pages这3列数据 并按照页数升序排列List<Book> books5 = DataSupport.select("name","author","pages")                                .where("pages > ?","300")                                .order("pages")                                .limit(10)                                .offset(10)                                .find(Book.class);//当然 LitePal也支持原生的SQLite进行查询Cursor cursor = DataSupport.findBySQL("select * from Book where pages > ? and price > ?","300","200");



















1 0