Android学习笔记—— 七、Android中三种常用的数据存储方法

Android中常用的三种数据存储方法:
  • 直接进行文件存储
  • 使用SharedPreferences进行文件存储
  • 数据库存储

1. 直接进行文件存储
1. 存储数据

存储数据使用的是Context类中提供的openFileOutput方法,这个方法有两个参数,第一个是文件名,第二个是存储模式,有两种模式:MODE_PRIVATE表示文件已存在时替换文件;MODE_APPEND表示文件已存在时将要存储的内容追加到文件末尾。

		FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            //实例化文件输出流对象out,设置保存文件名为data,输出模式为Private
            out = openFileOutput("data", Context.MODE_PRIVATE);

            //使用BufferedWriter来包裹OutputStreamWriter方法创建的writer对象用于提高效率
            // 原理是避免频繁的转换器调用……(什么意思?)
            writer = new BufferedWriter(new OutputStreamWriter(out));

            //写入数据
            writer.write(data);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
            
                //最后检查writer如果不为null则调用close方法关闭writer
                if (writer != null) {
                    writer.close();
                    
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
2. 读取数据
		FileInputStream in = null;
        BufferedReader reader = null;

        //实例化StringBuilder对象用于保存读取到的数据
        StringBuilder content = new StringBuilder();

        try {
            in = openFileInput(fileName);
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";

            //每次读取文件中的一行数据同时检查是否读取到文件末
            while ((line = reader.readLine()) != null) {

                //将读取到的数据放入实例化的对象content中
                content.append(line);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

2. 使用SharedPreferences进行文件存储

和直接使用文件存储相比使用SharedPreferences进行文件存储的操作步骤就简单多了。不过使用SharePreferences存储需要获取SharePreferences对象,有三种办法可以获取:

  • Context类中的getSharedPreferences方法,第一个参数为文件名,第二个参数为存储模式,这里只有MODE_PRIVATE一种模式可用
  • Activity类中的getPreferences方法,参数只有一个存储模式参数,文件名会默认使用当前活动的类名
  • PrefreencesManager类中的getDefaultSharedPreferences方法,这是一个静态方法,只接收一个Context参数,文件名使用当前程序的包名为前缀命名SharedPreferences文件
1. 存储数据
				//使用getSharedPreferences().edit()方法实例化一个Editor对象
                SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();

                //设置数据
                editor.putString("name","admin");
                editor.putInt("mode",15);

				//将数据存储到文件中
                editor.apply();
2. 读取数据
				//使用getSharedPreferences()方法实例化一个SharedPreferences对象preferences
                SharedPreferences preferences = getSharedPreferences("data",MODE_PRIVATE);

                //获取数据
                String name = preferences.getString("name","");
                int mode = preferences.getInt("mode",0);
3. 数据库存储
1. 使用Android内置的SQLite数据库进行数据库存储

使用SQLite数据库需要自定义类继承抽象类SQLiteOpenHelper,在其内部重写抽象方法onCreate和onUpgrade。

  • onCreate用于创建并初始化数据库
  • onUpgrade升级数据库方法
	//SQLiteOpenHelper的构造方法有两种,一般使用这个参数较少的方法
	//第一个参数是Context,第二个参数是数据库名称,第三个参数允许我们在查询数据时返回一个自定义的Cursor,一般传入null,第四个参数是当前数据库的版本号,用于进行升级操作
	public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

重写onCreate方法

	//使用execSQL方法执行编写好的SQL语句初始化数据库
	@Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
    }

重写onUpgrade方法,和重写onCreate的思路一样

@Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK_1);
    }

  1. 创建SQLite数据库
    SQLiteOpenHelper中有两个实例方法可以用于创建或者当数据库已存在时打开数据库,然后这两个方法会返回一个可对数据库进行读写操作的对象。但是当数据库不可写入时,这两个方法会有不同的结果:
    • getReadableDatabase:返回一个使用只读方式打开的数据库
    • getWritableDatabase:出现异常
private MyDatabaseHelper dbHelper;
……
//实例化一个自定义MyDatabaseHelper对象dbHelper,设置参数数据库名为Test.db,版本号为1,然后使用getWritableDatabase创建或打开数据库
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
dbHelper.getWritableDatabase();
  1. 升级数据库
    使用比原来版本号大的版本重新打开数据库,系统会自动调用onUpgrade方法并执行内部的升级数据库逻辑处理方法升级数据库
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
  1. 添加数据
				//创建SQLiteDatabase对象获得getWritableDatabase方法返回的数据库操作对象
				SQLiteDatabase db = dbHelper.getWritableDatabase();
				
				//使用ContentValues封装数据
                ContentValues values = new ContentValues();
                values.put("name","The Da Vinci Code");

				//插入数据
                db.insert("Book",null,values);
  1. 更新数据
    直接调用数据库操作对象的update方法,有四个参数,第一个表名,第二个更新的数据,剩余两个用于限制更新某一行或者某几行,不指定的话就是默认更新所有行
				db.update("Book",values,"name = ?",new String[] {"The Da Vinci Code"});
  1. 删除数据
    直接调用数据库操作对象的delete方法,参数类似于更新操作
				db.delete("Book","pages>?",new String[]{"500"});
  1. 查询数据
    调用数据库操作对象的query方法,不过这个方法有很多种参数,最少的一个重载方法也有七个参数:
				//实例化一个Cursor对象存储查询到的数据
                /**
                 * 查询方法的参数含义:
                 * 1. 表名
                 * 2. 查询那几列,不指定默认查询所有列
                 * 3和4. 查询某一行或者某几行
                 * 5. 指定需要去group by的列,不指定则不进行group by操作
                 * 6. 对group by后的数据进行过滤,不指定则不过滤
                 * 7. 指定查询结果的排序方式,不指定则使用默认排序方式
                 */
                Cursor cursor = db.query("book",null,null,null,null,null,null);
                
                //将数据的指针移动到第一行
                if(cursor.moveToFirst()){
                    do{
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                    }
                    
                    //读取下一行数据
                    while (cursor.moveToNext());
                }
                
                //关闭cursor对象
                cursor.close();
2. 使用开源库LitePal进行数据库存储操作

LitePal开源库:https://github.com/LitePalFramework/LitePal
LitePal是一款开源的Android数据库框架,它采用了对象关系映射(ORM)的模式,并将我们平常开发最常用到的一些数据库功能进行了封装。

到项目主页看更详细的开发文档!

使用LitePal:
在build.gradle中声明开源库的引用:

implementation 'org.litepal.android:java:3.0.0'

在AndroidManifest.xml的application中配置:

android:name="org.litepal.LitePalApplication"

在main目录下创建assets目录并在该目录下创建litepal.xml:

<?xml version="1.0" encoding="utf-8"?>
<litepal>

    <!--
    设置数据库的名称,如果不添加.db后缀的话系统会自动添加
    -->
    <dbname value="demo" />

    <!--
    设置数据库版本
    -->
    <version value="1" />

    <!--
    使用映射标签在映射模型列表中定义模型,LitePal将为每个映射类创建表。支持的字段模型中定义的内容将映射到列中。
    比如:
    	<list>
    		<mapping class="com.test.model.Reader" />
    		<mapping class="com.test.model.Magazine" />
    	</list>
    -->
    <list>
    </list>
    
</litepal>

  1. 创建和升级数据库
    和SQLite不同的是,因为LitePal使用的是对象关系映射模式,我们可以使用面向对象的思维来操作数据库,而其中的映射则交给LitePal来处理。

创建一个Book表我们只需要定义一个Book类,继承LitePalSupport是用于在后续的数据处理时调用LitePalSupport中的方法。

public class Book extends LitePalSupport {

	//这里表示Book表有几列,比如String name表示一个数据类型为text的name列
    //值得一提的是即使类中不声明id,数据库也会自动添加一个id列并将其设置为自增长的主键。
    // 而如果设置有id则会直接将id设置为自增长的主键。
    private int id;

    private String name;

    private String author;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
    
}

然后在litepal.xml中的list标签中使用mapping标签配置新建的Book类。接下来只要进行任意一次数据库的操作,配置好的数据库就会建立出来。

而升级就更简单了,只需要更改Book类或者新建类配置到litepal.xml中,然后将版本号+1,再进行一次任意的数据库操作即可。

  1. 添加数据
				//实例化一个Book表对应的Book对象并设置数据
                //然后调用save方法就可以将设置好的数据添加到数据库book表中
                Book book = new Book();
                book.setName("The Dan Vinci Code");
                book.setAuthor("Dan Brown");
                book.save();
  1. 更新数据
    更新数据的方法比较多,常用的方法:
				//1. 通过find方法获取到已存储的数据然后重新设值
				Book book = LitePal.find(Book.class, 1);
				book.setName("Lin"); 
				//调用save方法进行更新
				book.save();
				
				//2. 实例化一个对象并设值,然后使用update方法更新指定id的数据库对象
				Book book = new Book();
                book.setName("Lef Thor");
                book.update(1);

				//3. 使用updateAll方法更新符合指定条件的多条语句
				Book book = new Book();
                book.setName("Lef Thor");
                book.updateAll("author = ?","Dan Brown");

这里需要注意的是,如果想要更新的值是对应数据的数据类型的默认值时,使用以上方法并不会更新数据,这个时候需要调用setToDefault方法。比如如果想要将一个int类型的数据更新为0时并不能使用update(0)方法,应当使用setToDefault()将其更新为默认值即0

  1. 删除数据
    第一种方法类似于更新操作的一种。直接查询到想删除的数据行,然后调用delete方法直接删除。
    第二种方法是使用deleteAll方法删除多行数据:
//指定删除符合条件的数据行,或者不指定后缀条件则清空整个数据库的所有数据(删库跑路.gif 2333)
LitePal.deleteAll(Book.class,"pages>?","1000");
  1. 查询数据
    相对的,LitePal的查询操作也是最复杂的,不过相比较SQLite的臃肿,LitePal还是很清爽的。
    • 通过find查询指定id的数据行,返回一个表对应的自定义类类型数据
    • 通过findAll查询指定表的所有数据:
      List<Book> bookList = LitePal.findAll(Book.class);
    • 通过组合多个查询方法,常用的查询方法:
      • select:指定查询那几列,对应SQL语句中的select关键字。比如:select(“name”,“author”);
      • where:指定查询的约束条件,对应SQL语句中的where关键字
      • order:指定查询结果的排序方式,对应SQL语句中的order by关键字
      • limit:指定查询结果的数量
      • offset:指定查询结果的偏移量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值