数据持久化技术就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失。而Android的持久化技术主要有三种实现方式:1.文件存储;2.SharedPerferences;3.数据库存储。接下来我们就对这3种数据持久化方式逐一进行介绍。
文件存储是Android中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有数据都是原封不动的保存到文件当中,因而它比较适合用于存储一些简单的文本数据或二进制数据。
使用步骤:
1.调用openFileOutput(文件名称,操作模式)方法获取输出流。
2.使用io操作将数据存储到文件中。
详解openFileOutput()方法:
第一个参数是文件名,注意这里指定的文件名不可以包含路径,因为所有的文件默认都存储到/data/data/< package name >/files/目录下的。第二个参数是文件的操作模式,主要有两种模式可选,MODE_PRIVATE和MODE_APPEND,其中MODE_PRIVATE是默认操作模式,表示当指定同样文件名时,所写入的内容将会覆盖原文件中的内容,而MODE_APPEND则表示如果该文件以存在,就往文件里面追加内容,不存在就创建文件。
示例:
public void save(String data){
OutputStream out;
BufferedWriter writer=null;
try {
out=openFileOutput("data",MODE_PRIVATE);//获取输出流
writer=new BufferedWriter(new OutputStreamWriter(out));
writer.write(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(writer!=null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
查找生成文件的方式
点击As导航栏中的View–>Tool Windows–>Device File Explorer,在这里找到/data/data/< package name >/files/目录,就可以看到生成的文件了。
使用步骤:
1.调用openFileInput(文件名称)方法获取输入流。
2.使用io操作将数据存储到文件中。
示例:
public String read(){
InputStream in;
BufferedReader reader=null;
StringBuilder data=new StringBuilder();
try {
in=openFileInput("data");//获取输入流
reader=new BufferedReader(new InputStreamReader(in));
String line="";
while((line=reader.readLine())!=null){
data.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return data.toString();
}
}
不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的,因此使用SharedPerferences来进行数据持久化要比文件方便很多。而且SharedPreferences还支持多种不同数据类型的存储,如果存储的数据类型是整型,那么读出来的数据也是整型。
使用步骤:
1.获取SharedPreferences实例。
2.获取SharedPreferences.Editor对象
3.调用putString(键,值)一类的方法将数据存储到SharedPreferences中。
4.调用apply()方法保存数据。
获取SharedPreferences实例的方法:
1.Context类中的getSharedPerference()方法。此方法接收两个参数,第一个参数用于指定SharedPreferences文件的名称,如果不存在则会创建一个,SharedPreferences文件都是存放在/data/data/< package name >/shared_prefs/目录下的。第二个参数用于指定操作模式,目前只有MODE_PRIVATE这一种模式可选,它是默认模式,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写。
2.Activity类中的getPreferences()方法。此方法只接收一个操作模式参数,因为使用这个方法会自动将当前活动的类名作为SharedPreferences的文件名。
3.PreferenceManager类中的getDefultSharedPreferences()方法。它是一个静态方法只接受一个Context参数,并自动将当前应用程序的包名作为前缀来命名SharedPreferences文件。
示例:
SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();//步骤一二
editor.putString("name","Tome");//步骤三
editor.putInt("age",18);
editor.apply();//步骤四
查找生成SharedPreferences文件的方式
点击As导航栏中的View–>Tool Windows–>Device File Explorer,在这里找到/data/data/< package name >/shared_prefs/目录,就可以看到生成的SharedPreferences文件了。
使用步骤:
1.获取SharedPreferences实例。
2.调用getString(键,默认值)一类的方法获取数据。
示例:
SharedPreferences preferences=getSharedPreferences("data",MODE_PRIVATE);
String name=preferences.getString("name","");//当传入的键找不到对应的值时,则返回默认值
int age=preferences.getInt("age",-1);
SQLite是一款轻量级的关系型数据库,它运行速度非常快,占用资源也很少,并且SQLite也支持标准的SQL语法。前面我们所学的文件存储和SharedPerferences存储只适合用于保存一些简单的数据和键值对,当需要存储大量复杂的关系型数据时还是需要用SQLite才能应付。
使用步骤:
1.创建类继承SQLiteOpenHelper类并重写构造方法,onCreate()和onUpgrad()方法。
2.在新建类里定义建表语句,并在onCreate()方法中调用execSQL()方法创建表格。
3.在活动中获取新建类的实例,该构造方法共接收四个参数。第一个参数:Context;第二个参数:数据库名;第三个参数:当我们查询数据时返回一个自定义的Cursor,一般传入null;第四个参数:版本号。
4.调用getWritableDatabase()方法即可完成数据库和表格的创建。
示例:
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
//步骤一
private Context mcontext;
private final String CREATE_BOOK="create table Book ("//步骤二
+"id integer primary key autoincrement,"
+"name text,"
+"author text,"
+"price real )";
public MySQLiteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mcontext=context;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_BOOK);//步骤二
Toast.makeText(mcontext,"ok",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MySQLiteOpenHelper helper=new MySQLiteOpenHelper(MainActivity.this,"BookStore.db",null,1);//步骤三
Button button=(Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
helper.getWritableDatabase();//步骤四
}
});
}
}
查找创建的数据库:
cmd查找数据库的方法
SQLiteOpenHelper实现类的onCreate()方法只有在第一次创建数据库时才会调用,倘若当我们想要再向数据库中添加一张新表格时,就要用到升级数据库的方法了。
在4.1操作后的使用步骤:
1.在onCreate()方法中添加新的数据库操作代码。
2.在onUpgrade()方法中调用onCreate()方法,这样当我们升级数据库时就会重新调用onCreate()方法了。
3.更改获取新建类实例的构造方法中的版本号。
示例:
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
private Context mcontext;
private final String CREATE_BOOK="create table Book ("
+"id integer primary key autoincrement,"
+"name text,"
+"author text,"
+"price real )";
private final String CREATE_STUDENT="create table Student ("//步骤一
+"id integer primary key autoincrement,"
+"name text,"
+"age integer )";
public MySQLiteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mcontext=context;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_BOOK);
sqLiteDatabase.execSQL(CREATE_STUDENT);//步骤一
Toast.makeText(mcontext,"ok",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("drop table if exists Book");//这里先将已存在的表删除,因为如果在创建表时发现这张表已存在就会直接报错
sqLiteDatabase.execSQL("drop table if exists Student");
onCreate(sqLiteDatabase);//步骤二
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MySQLiteOpenHelper helper=new MySQLiteOpenHelper(MainActivity.this,"BookStore.db",null,2);//步骤三
Button button=(Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase database=helper.getWritableDatabase();
}
});
}
}
在创建好数据库的前提下的使用步骤:
1.先获取SQLiteDataBase实例。
2.获取ContentValues实例,并调用其put(键,值)方法准备要添加的数据。
3.调用insert(表名,一般赋值null即可,ContentValues实例)方法完成添加。
示例:
SQLiteDatabase database=helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("name","Java");
values.put("price",43.2);
values.put("author","Tom");
database.insert("Book",null,values);
在创建好数据库的前提下的使用步骤:
1.先获取SQLiteDataBase实例。
2.获取ContentValues实例,并调用其put(键,值)方法准备要更新的数据。
3.调用update(表名,ContentValues实例,第三四个参数用于限制要更新的位置若不指定默认更新所有行)方法完成更新。
示例:
SQLiteDatabase database=helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("name","Android");
database.update("Book",values,"id = ?",new String[]{
"1" });//这里表示只修改第一行的数据
在创建好数据库的前提下的使用步骤:
1.先获取SQLiteDataBase实例。
2.调用delete(表名,第二三个数据用于限制要删除的位置若不指定默认删除所有行)方法完成删除。
示例:
SQLiteDatabase database=helper.getWritableDatabase();
database.delete("Book","id = ?",new String[]{
"1" });//这里表示只删除第一行的数据
在创建好数据库的前提下的使用步骤:
1.先获取SQLiteDataBase实例。
2.调用query()方法完成查询,该方法返回一个Cursor实例,查询到的数据就保存在该实例中。query方法详解
3.使用操作链表的方法操作Cursor实例获取数据。
4.关闭Cursor。
示例:
SQLiteDatabase database=helper.getWritableDatabase();
Cursor cursor=database.query("Student",null,null,null,null,null,null);
while(cursor.moveToNext()){
String name=cursor.getString(cursor.getColumnIndex("name"));
int age=cursor.getInt(cursor.getColumnIndex("age"));
Log.e("MainActivity", name );
Log.e("MainActivity", ""+age );
}
cursor.close();
LitePal是一款开源的Android数据库架构,它采用了对象关系映射(ORM)的模式,并将我们平时最常用的一些数据库功能进行了封装,而这个关系映射模式可以使我们用面向对象的思维来操作数据库,使得不用再编写一行SQL语句就可以完成各种建表和增删改查的操作。LitePal的项目主页地址
1.添加依赖。
2.在main目录下新建一个assets文件夹,再新建一个litepal.xml文件,接着配置litepal.xml文件中的内容。
3.配置项目的application。
示例:
//步骤一
dependencies {
implementation 'org.litepal.android:java:3.0.0'
}
//步骤二
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname vaule="People" />
<version value="1" />
<list>
</list>
<!--<dbname>标签用于指定数据库名 <version>标签用于指定版本号 <list>标签用于指定所有的映射模型-->
</litepal>
//步骤三
android:name="org.litepal.LitePalApplication"
创建数据库的步骤:
1.新建一个你想要创建表的类并让它继承LitePalSupport。
2.在litepal.xml文件中的< list >标签下将新建的类添加到映射模型列表当中。
3.任意进行一次数据库操作,数据库和你想要创建的表格就会自动创建成功。
示例:
//步骤一
public class People extends LitePalSupport {
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//步骤二
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="PeopleData" />
<version value="1" />
<list>
<mappping class="com.example.temp.People" />
</list>
</litepal>
//步骤三
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=(Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LitePal.getDatabase();//数据库的一个最基本操作
Toast.makeText(MainActivity.this,"ok",Toast.LENGTH_SHORT).show();
}
});
}
}
升级数据库的步骤:
1.只需要改你想改的任何内容,然后版本号加1即可,剩下的逻辑LitePal会帮你自动完成。
示例(再添加一张新表):
//创建新的类
public class Success extends LitePalSupport {
int math;
int english;
int chinese;
public int getMath() {
return math;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
}
//添加映射关系,修改版本号
<litepal>
<dbname value="PeopleData" />
<version value="2" />
<list>
<mappping class="com.example.temp.People" />
<mappping class="com.example.temp.Success" />
</list>
</litepal>
在创建数据库后的使用步骤:
1.获取一个表格类的实例,再给其设置要添加的数据。
2.调用save()方法完成添加。
示例:
People people=new People();
people.setAge(18);
people.setName("Tom");
people.save();
在创建数据库后的使用步骤:
1.获取一个表格类的实例,再给其设置要更新的数据。
2.调用updataAll(数目不定的参数,用于限制需要更新的位置)方法完成更新。
示例:
People people=new People();
people.setName("Jack");
people.updateAll("id = ?","1");//这里表示只更新第一行的数据
想要更新成默认值的操作
当你想要把一个字段的值更新成默认值时,是不可以用上面的方式来set数据的。等于所有想要将数据更新成默认值的操作,LitePal提供了一个setToDefault()方法,然后传入相应列名就可以实现了。
示例:
People people=new People();
people.setToDefault("age");
people.updateAll();//这里不加任何参数,表示更新所有行
在创建数据库后的使用步骤:
1.调用deleteAll(表格类名,剩下数目不定的参数,用于限制需要删除的位置)方法完成删除。
示例:
LitePal.deleteAll("People","id = ?","1");//这里表示只删除第一行的数据
在创建数据库后的使用步骤:
1.调用findAll(表格类)方法完成查询,该方法返回一个表格类类型的List集合,查询到的数据就存放在这个集合中。
2.操作这个集合获取数据。
示例:
List<People> list=LitePal.findAll(People.class);
for (People people:list){
String name=people.getName();
int age=people.getAge();
}
还记得我们用SQLiteDatabase的query方法查询数据库吗,这个方法总共接收7个参数,其中6个都是用于限制查询位置的。而LitePal怎样限制查询位置呢?
LitePal查询数据的更多知识