持久化技术是什么?
数据持久化指的是将内存中的数据保存在硬盘等外部存储设备中。
文件存储
文件存储将数据原封不动保存在文件中,适合存储一些简单文本数据或二进制数据。数据默认存储在/data/data/<packagename>/files/目录下。
修改activity_main.xml,设置一个读写按钮:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_write"
android:text="存"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_read"
android:text="读"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
写数据
找到btn_write设置点击事件,其中save()方法通过Context中的openFileOutput()方法返回一个FileOutputStream流,第一个参数为文件名,第二个参数为操作模式,MODE_PRIVATE表示写入的内容会覆盖原文件中的内容,MODE_APPEND表示会在源文件中追加,然后通过java文件读写操作数据:
public class MainActivity extends AppCompatActivity {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.et);
Button button = findViewById(R.id.btn_write);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
save(editText.getText().toString());
}
});
}
public void save(String text) {
FileOutputStream outputStream = null;
BufferedWriter bufferedWriter = null;
try {
outputStream = openFileOutput("data", Context.MODE_PRIVATE);
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write(text);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
读数据
找到btn_read按钮并设置点击事件,读出数据要把光标移动到最后:
Button button_read = findViewById(R.id.btn_read);
button_read.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String string = load();
if (!TextUtils.isEmpty(string)) {
editText.setText(string);
editText.setSelection(string.length());
}
}
});
其中load()方法如下,通过openFileInput()获取FileInputStream流,参数为文件名:
private String load() {
FileInputStream inputStream = null;
BufferedReader bufferedReader = null;
StringBuilder stringBuilder = new StringBuilder();
try {
inputStream = openFileInput("data");
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringBuilder.toString();
}
SharedPreference
SharedPreference通过键值对以xml的方式存储数据。数据默认存储在/data/data/<packagename>/shared_prefs/目录下。
获取SharedPreference
- Context中的getSharedPreference()方法,第一个参数为文件名,第二个参数为MODE_PRIVATE
- Acitivity中的getPreference()方法,参数为操作模式,会自动以当前Acitivity的类名作为文件名
- PreferenceManager的getDefaultSharedPreference()方法,接收Context参数,自动以当前应用程序包名作为前缀命名文件
使用SharedPreference
- 调用SharedPreference的edit()获取Editor实例
- 通过Editor的putXXX()方法添加数据,XXX代表基本数据类型或数组
- 调用apply()提交
写数据
修改btn_write的点击事件:
Button button_write = findViewById(R.id.btn_write);
button_write.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name","tom");
editor.apply();
}
});
在输入框输入123点击存储,找到文件并打开便可以看到数据: 
读数据
修改btn_read的点击事件,通过getXXX()方法获取数据:
Button button_read = findViewById(R.id.btn_read);
button_read.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);
String string = sharedPreferences.getString("inputString", "");
editText.setText(string);
}
});
数据库存储
SQLite是Android内置关系型数据库,支持SQL语法,遵循数据库ACID事务。数据库文件默认存储在/data/data/<packagename>/databases/目录下。
创建数据库
通过继承SQLiteOpenHelper,重写构造方法,参数分别是Context、数据库名、查询时返回的自定义Cursor(一般为null)、数据库版本号;重写onCreate()方法用于创建数据库,重写onUpgrade()方法用于更新数据库。
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(@Nullable Context context, @Nullable String name, @Nullable 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", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
随后可通过getReadableDatabase()或getWritableDatabase()创建或打开一个现有数据库,并返回一个可对数据库读写操作的对象。当数据库不可写入时(如硬盘满了),getReadableDatabase()返回的对象将以只读的方式去打开数据库,而getWritableDatabase()会出现异常。
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper databaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
Button createDb = findViewById(R.id.createDb);
createDb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
databaseHelper.getWritableDatabase();
}
});
}
}
添加数据
添加一个插入按钮:
<Button
android:id="@+id/add"
android:layout_height="wrap_content"
android:text="add"
android:layout_width="match_parent"/>
通过insert()方法插入数据,第一个表名,第二个参数用于对未添加数据且可为空的列自动赋值null(一般为null),第三个参数时ContentValue对象,其提供了put()方法用于向指定列名添加数据。
Button addData = findViewById(R.id.addData);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase writableDatabase = databaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", "tom");
values.put("author", "john");
values.put("price", 10);
values.put("pages", 400);
writableDatabase.insert("Book", null, values);
}
});
更新数据
添加更新按钮
<Button
android:id="@+id/updateData"
android:layout_height="wrap_content"
android:text="updateData"
android:layout_width="match_parent"/>
通过updata()方法更新数据,第一个参数为表名,第二个参数时ContentValue对象,第三第四个参数是约束条件。
Button updateData = findViewById(R.id.updateData);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase writableDatabase = databaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 100);
writableDatabase.update("Book", values, "name=?",new String[]{"tom"});
}
});
删除数据
添加删除按钮:
<Button
android:id="@+id/delData"
android:layout_height="wrap_content"
android:text="delData"
android:layout_width="match_parent"/>
通过delete()方法删除数据,第一个参数为表名,第二三个参数是约束条件,不指定意为删除所有行。
Button delData = findViewById(R.id.delData);
delData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase writableDatabase = databaseHelper.getWritableDatabase();
writableDatabase.delete("Book", "price>?",new String[]{"99"});
}
});
查询数据
添加查询按钮:
<Button
android:id="@+id/queryData"
android:layout_height="wrap_content"
android:text="queryData"
android:layout_width="match_parent"/>
通过query()方法查询数据,第一个参数为表名,第二个指定查询哪几列,不指定则默认查询全部列,第三四个参数指定查询某几行,不指定默认查询全部行,第五个参数对查询结果分组,第六个参数用于分组后的过滤,第七个参数对查询结果分组 获取到游标Cursor,通过Cursor遍历取出数据。
Button queryData = findViewById(R.id.queryData);
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase writableDatabase = databaseHelper.getWritableDatabase();
Cursor cursor = writableDatabase.query("Book", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int page = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getInt(cursor.getColumnIndex("price"));
Log.d("MainActivity", name + author + page + price);
} while (cursor.moveToNext());
}
}
});
使用SQL操作数据库
增加:
writableDatabase.execSQL("insert into Book(name,author,pages,price) values(?,?,?,?)",new String[]{"tom","john","400","10"});
更新:
writableDatabase.execSQL("update Book set price=? where name=?",new String[]{"100","tom"});
删除:
writableDatabase.execSQL("delete from Book where price>?",new String[]{"99"});
查询:
writableDatabase.rawQuery("select * from Book",null);
|