Android学习笔记之数据存储

一、文件存储

1.1.将数据存储到文件中

1.运用java的io流将数据写入到手机文件中

/**
 * 保存数据到文件
 * */
public void save(String data){
    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();
            }
        }
    }

在Context类中,提供了一个openFileOutput()方法,可以用于获取一个FileOutputStream的字节流对象,从而实现将数据存储到手机指定文件中的功能。其接收的两个参数中,第一个参数为文件名,(所有文件都默认存储到data/data//files/目录下)第二个参数为操作模式,示例中的MODE_PRIVATE是默认操作模式,表示当指定同样文件名时,所写的内容将会覆盖原内容。常用的另一种模式是MODE_APPEND,它表示如果该文件存在,就在文件里面追加内容,不存在就创建新文件。

1.2.从文件中读取数据

1.运用java的io流将数据从手机文件中读取出来

/**
 * 从文件中读取数据
 * */
public String load(){
    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();
}

类似的,在Context类中,还提供了一个openFileInput()方法,可以用于获取一个FileInputStream的字节流对象,从而实现从手机文件中读取数据的功能。这里只接收一个参数,即文件名。

二、SharedPreferences存储

2.1.将数据存储到SharedPreferences中

1.获取SharedPreferences对象

Android中主要提供了三种方法用于得到SharedPreferences对象:

a.Context类中的getSharedPreferences()方法

getBaseContext().getSharedPreferences("data",MODE_PRIVATE);

此方法接收两个参数,第一个参数为SharedPreferences文件的名称,(文件默认存储到data/data//shared_prefs/目录下)第二个参数为操作模式,目前仅MODE_PRIVATE这一种模式可选,为默认操作模式,表示只有当前应用程序才可以对这个SharedPreferences文件进行读写。

b.Activity类中的getPreferences()方法

getPreferences(MODE_PRIVATE);

此方法和Context类中的getSharedPreferences()方法相似,不过它只接收一个操作模式参数,因为它会用当前活动的类名作为SharedPreferences的文件名。

c.PreferenceManager类中的getDefaultSharedPreferences()方法

PreferenceManager.getDefaultSharedPreferences(getBaseContext());

该方法接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件。

2.获取SharedPreferences.Editor对象

SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();

3.向Editor中添加数据(键值对的形式)

editor.putString("name","Ein");

4.提交数据,完成存储操作

editor.apply();

PS:editor的提交数据除了apply()还有commit()

这两个方法的区别在于: 
1. apply没有返回值而commit返回boolean表明修改是否提交成功 
2. apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。 
3. apply方法不会提示任何失败的提示。 
由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,当然需要确保提交成功且有后续操作的话,还是需要用commit的。 

2.2.从SharedPreferences中读取数据

1.获取SharedPreferences对象(这里就仅以Context类中的getSharedPreferences()方法为例)

SharedPreferences preferences = getSharedPreferences("data",MODE_PRIVATE);

2.根据键去读取值,这里接收两个参数,第一个参数为键,第二个参数为缺省值

String name = preferences.getString("name","");

三、数据库存储(使用LitePal)

3.1.配置LitePal

1.在app/build.gradle文件的dependencies闭包中添加开源库LitePal

implementation 'org.litepal.android:core:2.0.0'

2.配置litepal.xml文件

在app/src/main/assets目录下新建一个litepal.xml文件,并编辑



    
    
    
        
    

其中标签用于指定数据库名称,标签用于指定数据库版本号,标签用于指定所有的映射模型。

3.编辑AndroidManifest.xml文件

修改标签的name属性值为"org.litepal.LitePalApplication"

如果 便签中的name属性已经配置了值,那么我们可以在Application中调用LitePal.initialize(context)方法起到同样的效果。

public class MyOwnApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        LitePal.initialize(this);
    }
    ...
}

3.2.创建和升级数据库

1.新建一个Java bean(这里以Book类为例),类对应于数据库中的表,类中每一个成员变量对应于表中的每一个列。

public class Book {
    private int id;
    private String author;
    private double price;
    private int pages;
    private String name;
...
}

 PS:这里即使不声明private int id这条成员变量,创建数据库的时候仍会为Book表新增主键id。但是需要getId()方法才能获取。

关于注释的补充说明:

//@Column(defaultValue = "unknown")设置缺省值。
//@Column (unique = true) 主键
//@Column (ignore = true) 忽略,创建数据库不会添加该键

2.修改litepal.xml文件,将Book类添加到映射模型列表当中(配置值为其完整类名)


    

3.调用创建数据库的方法

Connector.getDatabase();

 4.升级数据库的时候,如果修改表,则直接在Java bean类中进行修改,比如这里在Book表中添加一个出版社的列:

private int id;
private String author;
private double price;
private int pages;
private String name;
private String press;

如果要新增表,则再新建一个Java bean类与之对应,比如这里新建一张Category表格:

public class Category {
    private int id;
    private String categoryName;
    private int categoryCode;
...
}

同样的,每新建一张表格,都需要将其添加到映射模型列表当中:


    
    

最后让版本号加1:

再重新调用getDatabase()方法时,便会升级数据库了。

Connector.getDatabase();

3.3.使用LitePal添加数据

1.让Java bean类继承 LitePalSupport类

public class Book extends LitePalSupport
public class Category extends LitePalSupport

2.新建Book实例,通过save()方法保存数据

Book book = new Book();
book.setName("The Da Vinci Code");
book.setAuthor("Dan Brown");
book.setPages(454);
book.setPrice(16.96);
book.setPress("Unknow");
book.save();

3.4.使用LitePal更新数据

1.最简单的方法就是通过find()方法找到对应条目,并通过save()方法更新数据。

//第一个参数为查询哪张表,第二个参数为查询第几条数据
Book book = LitePal.find(Book.class,1);
book.setPrice(20.99);
book.save();

2.或者使用update()方法更新数据

Book book = new Book();
book.setName("The Lost Symbol");
book.update(id);

3.或者使用updateAll()方法批量更新数据

Book book = new Book();
book.setPress("Anchor");
book.setPages(576);
book.updateAll("name = ? and author = ?","The Lost Symbol","Dan Brown");

PS:当我们想将某字段更新成缺省值时,我们应该使用setToDefault()方法:

Book book = new Book();
book.setToDefault("pages");
book.updateAll();

3.5.使用LitePal删除数据

1.根据主键删除

LitePal.delete(Book.class, id);

2.批量删除

LitePal.deleteAll(Book.class, "price > ?" , "21");

3.6.使用LitePal查询数据

1.主键查询

Book book = LitePal.find(Book.class, id);

2.查询所有数据

List allBooks = LitePal.findAll(Book.class);

3.条件查询

List books = LitePal.select("name","author","pages")
        .where("pages > ?","400")
        .order("pages")
        .limit(10)
        .offset(10)
        .find(Book.class);

其中,select用于指定查询哪几列的数据;where用于指定查询的约束条件;order用于指定排序方式,desc表示降序排序(例如pages desc),asc或者不写表示升序排列;limit用于指定查询结果的数量;offset用于指定查询结果的偏移量。

你可能感兴趣的:(Android)