AndroidStudio持久化技术
最近正在学习androidstudio,看的第一行代码,每天学了什么还是记下来好,以后忘了也可以看看。
我的理解持久化技术
把数据保存到存储设备中。
有三种方式分别是文件存储、SharedPreferences、数据库。
文件存储
对存储的内容不进行任何处理,适合存储一些简单的文本数据或二进制数据。
输出:Context类提供了一个openFileOutput()方法,两个参数分别为存储数据的指定文件名,不包含路径,第二个是操作模式,MODE_PRIVATE:如果有同名文件,替换。 MODE_APPEND:文件已存在,在后面添加内容。该方法返回一个FileOutputStream字节流对象。一般怎么存储? 先获取这个字节流对象,通过它创建OutputStreamWriter字符流对象,再创建BufferWriter流缓冲对象,最后调用write()方法存储。
输入:Context类提供了一个openFileInput()方法,一个参数是读取的文件名。该方法返回一个FileInputStream字节流对象。一般怎么读取? 先获取这个字节流对象,通过它创建InputStreamReader字符流对象,再创建BufferReader流缓冲对象,最后调用readLine()方法读取,以null结尾。
SharedPreferences
通过键值对存取。
要使用SharedPreferences方式,先获取SharedPreferences对象。
- Context类有getSharedPreferences(),两个参数,第一个指定文件名,第二个存储模式,只有MODE_PRIVATE,其余废弃。
- Activity类有getPreferences(),只有一个模式参数,默认文件名为当前活动类名。
- PreferenceManager类有getDefaultSharedPreferences(),接受context参数,包名为文件前缀。
存储数据:
获取SharedPreferences.Editor对象: 调用SharedPreferences对象的edit()方法获取。
SharedPreferences.Editor editor = getSharedPreferences(“参数一”,参数二).edit()
你要存储什么类型的数据调用相关的put方法:
如存String调用 editor.putString(String key,String value); 其余:putInt(),putBoolean()等。
随后提交editor.apply()
清除数据clear();
读取数据:
调用SharedPreferences对象的get方法
getString(String key, String value),getInt(),getBoolean();等一个参数是键,第二个参数是默认值即当找不到键对应的值时返回这个默认值。
数据库SQLite
SQLite是安卓系统内置的一个数据库。
首先是SQLiteOpenHelper类,是一个抽象类(我个人理解是用这个类来操作创建数据库);子类实现onCreate(),onUpgrade()抽象方法。有两个构造函数,一般重写其中一个有四个参数的,第一个是Context,第二个是数据库名,第三个是自定义的Cursor一般,第四个是版本号。两个实例方法getReadableDatabase()和getWritableDattabase(),打开或创建数据库(没有这个数据库就新建一个),这两个函数返回的是一个SQLiteDatabase对象。
所以一般怎么使用,先创建SQLiteOpenHelper子类的一个对象,调用实例方法getReadableDatabase()或另一个getWritableDatabase(),创建一个数据库,名字就是创建对象时指定的,创建数据库后调用onCreate(SQLiteDatabase db)方法,
通过获取的SQLiteDatabase的db对象进行执行相关sql语句:db.exec(String sql),如创表;一般onCreate()方法就用来创建完数据库后创表;因为建表只建一次,onCreate()方法也只在建表时调用;当你想在加表的时候,可以通过onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法,当你更改对象的版本时自动调用,所以我们就把要加表的sql语句写在里面,改一下版本号就自动调用。
查看我们创的数据库:
先配置环境变量,打开cmd,输入adb shell;
进入相关目录下:cd data/data/项目包名/databases,通过ls查看有哪些数据库(没有权限则先输入su root);
对表进行管理:sqlite3 数据库名.db,之后.tables查看所有表,.schema查看创建语句,或执行sql语句。
对数据的增删改查:
首先getReadableDatabase()和getWritableDatabase()返回的是对象指定创建或操作的SQLiteDatabase对象,要实现对数据库中的表进行增删改查操作,有两种方式:
1.使用SQL语句:
如 SQLiteDatabase db = helper.getWritableDatabase();其中helper是SQLiteOpenHelper子类的对象
增删改:db.execSQL(String sql,new Object[]),db.execSQL(String sql);其中第一个是有两个参数是因为如有需要赋值时需要通过字符串数组来进行如:
insert into book values(“aaa”,“aaa”)语句中又有引号故db.execSQL("insert into book values(?,?),new String[]{“”,“”});类似与javaweb中数据库操作。例子:
db.execSQL(“insert into book(author,name,price,page) values(?,?,?,?)”,new String[]{“hankzz”,“diary”,“25”,“100”});
db.execSQL(“update book set name=? where author=?”,new String[]{“mybook”,“hankzz”});
db.execSQL(“delete from book where id=?”,new String[]{“8”});
查:db.rawQuery(String sql, new Object[]),db.rawQuery(String sql);返回一个Cursor对象类似iterator默认在最前面的位置没有数据,通过getColumnIndex(“列名”)获取查询得到的数据,例子:
db.rawQuery("select * from book);
Cursor cursor = db.rawQuery(“select name from book where author=?”,new String[]{“dongyeguiwu”});
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex(“name”));
Log.d(“MainActivity”,name);
}//如果不先moveToNext()会报错因为起始位置没有数据
2.使用方法
db.insert(),db.delete(),db.update(),db.query(),个人习惯sql语句且方法个人认为繁琐,就是把sql语句各项分解成了各个参数,故不详细记录。
SQLite批处理操作
使用SQLite进行批处理需要开启事务,因为一般默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作,所以SQLiteDatabase.beginTransaction()方法开启事务进行批处理。
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
//开启事务
db.beginTransaction();
try{
//批量处理操作
//do something
db.execSQL("SQL语句", new Object[]{});
db.execSQL("SQL语句", new Object[]{});
//设置事务标志为成功,当结束事务时就会提交事务
db.setTransactionSuccessful();
}
catch(Exception e){
}
finally{
//结束事务
db.endTransaction();
}
详细可查看:https://blog.csdn.net/koozework/article/details/45558127
使用LitePal框架
配置方法及详细使用详见:https://github.com/LitePalFramework/LitePal
<?xml version="1.0" encoding="UTF-8" ?>
<litepal>
<dbname value="Stu"/>
<version value="3"/>
<list>
</list>
</litepal>
dbname为数据库名字,version为版本,list为映射列表(通过mapping标签将类映射为表)
首先需要明白的是LitePal采用的是对象关系映射模式(ORM),简单说就是将面向对象语言和面向关系的数据库建立一种映射。即创建的类可以就是数据库中的一个表,而类中的属性就是表的列,类需继承LitePalSupport才能调用save(),update()方法。
如创建了一个Student类,便可在litepal.xml中的list映射列表中添加:
package com.example.hankzz.litepalproject;
import org.litepal.crud.LitePalSupport;
public class Student extends LitePalSupport {
private String name;
private int age;
private String sex;
private String number;
private int grade;
public int getGrade() {
return grade;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
public String getNumber() {
return number;
}
public void setGrade(int grade) {
this.grade = grade;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setNumber(String number) {
this.number = number;
}
}
<list>
<mapping class="com.example.hankzz.litepalproject.Student"></mapping>
<mapping class="com.example.hankzz.litepalproject.Teacher"></mapping>
</list>
在通过LitePal.getDatabase()方法创建一个数据库,名称在litepal.xml中定义。
当要修改表时直接对相应类的属性进行更改增添或删除,当要增加表时直接新建一个类之后在list中映射即可,再将litepal.xml中的version值+1调用LitePal.getDatabase()便会自动更新数据库。
增:
Student stu = new Student();
调用各种set方法赋值
stu.save(),便增加了一行表中数据
改:
1.如果save()方法是已经调用过的save()的对象即表中已存在的行则会进行更新:
Student stu = LitePal.find(Student.class,1);
stu.setSex("female");
stu.save();
2.调用updata()方法指定id的列:
Student stu = new Student();
stu.setAge(22);
stu.update(1);
3.调用updateall()方法(类似update 表 set 列 where):
Student stu = new Student();
stu.setGrade(150);
stu.updateAll("sex=?","female");
删:
1.直接删除对应id的列:
LitePal.delete(Student.class,1);
2.删除where条件(类似delete from 表 where ):
LitePal.deleteAll(Student.class,"name=?","hankzz");
查
1.查全部:
List<Student> students = LitePal.findAll(Student.class)
2.查第一或最后一个或指定id:
Student stu = LitePal.findFirst(Student.class);
Student stu = LitePal.findLast(Student.class);
Student stu = LitePal.find(Student.class,id);
3.查有条件的(类似select 列 from 表 where…):
List<Student> students =
LitePal.select("name","age").where("sex=?","female").
find(Student.class);