数据存储
瞬时数据会在程序关闭时销毁
文件存储
Context类下的文件处理方法
//获取/data/data/<包名>/files
getFilesDir();
//读取files文件夹下的某文件
openFileInput("files文件夹下的某文件");
//写入files文件夹下的某文件,不存在则新建,(private是若存在则覆盖,append是若存在则追加)
openFileOutput("想放在files文件夹下的文件",MODE_PRIVATE);
//获取/data/data/<包名>/子目录
getDir("子目录",MODE_PRIVATE);
//获取文件列表
fileList();
//获取/data/data/<包名>/cache
getCacheDir();
Tips:可以使用Java的File类对文件进一步处理
将数据存入文件
文件位置在设备的/data/data/包名/files/文件名
![](https://juejin.cn/)
private void save(String s) {
BufferedWriter writer = null;
try {
//Context类中的openFileOutput方法返回一个FileOutputStream,参数为文件名,模式
FileOutputStream fm = openFileOutput("data", MODE_PRIVATE);//拿到字节流
OutputStreamWriter or = new OutputStreamWriter(fm);//字节流转字符流的桥梁
writer = new BufferedWriter(or);//转为字符流,效率高
writer.write(s);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
从文件中读取
private EditText edit;//为了下次启动在输入框里还原数据
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = findViewById(R.id.edit);
String data_in = load();
if(!TextUtils.isEmpty(data_in)){//传入的字符串是null或者是空字符串时都会返回true
edit.setText(data_in);
edit.setSelection(data_in.length());//移动光标到文末
}
}
private String load() {
BufferedReader reader = null;
StringBuilder builder = null;
try {
//Context类中的openFileInput方法返回一个FileInputStream,参数为文件名
FileInputStream fm = openFileInput("data");
InputStreamReader ir = new InputStreamReader(fm);
reader = new BufferedReader(ir);
builder = new StringBuilder();
String next = reader.readLine();
while (next != null) {
builder.append(next);
next = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return builder.toString();
}
SharedPreferences存储
键值对存储
文件位置在设备的/data/data/包名/Shared_prefs/文件名
得到SharedPreferences对象
①Context类中的getSharedPreferences("filename",操作模式)
②Activity类中的getPreferences(操作模式)
,自动把当前活动的类名当做文件名
将数据存入SP
SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
editor.putString("name","Ethan");//键值对
editor.putInt("age",18);
editor.apply();//异步提交;commit()是同步提交
从SP中读取
SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE);
String name = pref.getString("name","");//类似于getOrDefault()
int age = pref.getInt("age",0);
使用JSON存储List
Gson gson = new Gson();
String js = pref.getString("json", "default");//从SP存储中得到json字符串
List<Item> list = gson.fromJson(js, new TypeToken<List<Item>>() { }.getType());//json->List
mEditor.putString("json", gson.toJson(list));//List->json再放回SP存储
SQLite存储
4种数据类型:integer
,real
(浮点数),text
,blob
(二进制)
设为主键:primary key
自动递增:autoincrement
创建与升级
存储路径/data/data/包名/databases
新建类继承自抽象类SQLiteOpenHelper
public class MyDatabaseHelper extends SQLiteOpenHelper {
//两条建表语句
private String createBook="create table Book(id integer primary key autoincrement,author text,price real,pages integer,name text)";
private String createCategory="create table Category(id integer primary key autoincrement,category_name text,category_code integer)";
public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
//执行建表语句
db.execSQL(createBook);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//数据库迭代的最佳写法,每升级一次数据库版本加一条if语句
//(假设第2版数据库想增加Category表,第3版数据库想为Book表增加category_id列)
if(oldVersion<=1)
db.execSQL(createCategory);
if(oldVersion<=2)
db.execSQL("alter table Book add column category_id integer");
}
}
在活动中使用
//最后一个参数如果增加,那么就执行MyDatabaseHelper的onUpgrade方法
MyDatabaseHelper dbHelper=new MyDatabaseHelper(this,"BookStore.db",null,1);
button.setOnClickListener((View v)->{
dbHelper.getWritableDatabase();//如果存在就返回,不存在则新建;getReadableDatabase()也可
});
增C
在活动中执行,id设置的自动递增所以不用加
public static final class Cols{//内部类,存储各列名,便于拓展
public static final String AUTHOR="author";
public static final String NAME="name";
public static final String PAGES="pages";
public static final String PRICE="price";
}
SQLiteDatabase db=dbHelper.getWritableDatabase();
ContentValues values1=new ContentValues();
values1.put(Cols.AUTHOR,"Ethan");
values1.put(Cols.NAME,"I'm the king");
values1.put(Cols.PAGES,999);
values1.put(Cols.PRICE,0.1);
//参数为(表名,在未指定添加数据为哪些列自动赋值,ContentValues对象)
db.insert("Book",null,values1);
删D
在活动中执行,把页数大于500的书全删掉
SQLiteDatabase db=dbHelper.getWritableDatabase();
db.delete("Book",Cols.PAGES+">?",new String[]{"500"});//之所以使用new String[],是因为使用SQL语句可能会破坏数据库,即SQL脚本注入
改U
在活动中执行,把Ethan的所有书价格改为9.99
SQLiteDatabase db=dbHelper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(Cols.PRICE,9.99);
//参数为(表名,ContentValues对象,?是占位符,占位符内容)
db.update("Book",values,Cols.AUTHOR+"=?",new String[]{"Ethan"});
查R
在活动中执行,查找到pages符合67的author和name
SQLiteDatabase db = dbHelper.getWritableDatabase();
//参数为(表名,查询哪些列的信息,约束,占位符内容,需要groupBy的列,对groupBy后的结果进行约束,指定查询结果的排序方式),返回光标
Cursor cursor = db.query("Book", new String[]{Cols.AUTHOR,Cols.NAME}, Cols.PAGES+"=?", new String[]{"67"}, null, null, null);
if (cursor.moveToFirst()) {
do {
//此处代码可以放在继承自CursorWrapper类的类中
String author = cursor.getString(cursor.getColumnIndex(Cols.AUTHOR));
Log.d("wxc", author);
} while (cursor.moveToNext());
}
cursor.close();
使用此类,可以完成从数据库中取出数据之后新建实体对象等操作,这个类继承了Cursor的一切,并且可以添加自定义方法;使用时将上文Cursor替换
public class MyCursorWrapper extends CursorWrapper {
public MyCursorWrapper(Cursor cursor) {
super(cursor);
}
...
}
事务
事务的特性是保证一系列操作要么全部完成,要么一个都不会完成
SQLiteDatabase db=dbHelper.getWritableDatabase();
db.beginTransaction();
try {
db.delete("Book",null,null);
ContentValues values=new ContentValues();
//如果在此处抛出异常,就执行不到setTransactionSuccessful()
values.put("author", "Ethan");
values.put("name", "I'm the king");
values.put("pages", 999);
values.put("price", 0.1);
db.insert("Book", null, values);
db.setTransactionSuccessful();//通知数据库:事务执行成功
}catch (Exception e){
e.printStackTrace();
}finally {
db.endTransaction();//如果没收到事务执行成功的通知,那么整个事务都不会执行
}
Glance调试工具
在手机上对应应用生成一个数据库查看器,可以手动修改数据
debugImplementation 'com.guolindev.glance:glance:1.1.0'
最后
在这里插入图片描述全套视频资料:
一、面试合集
二、源码解析合集 在这里插入图片描述
三、开源框架合集 在这里插入图片描述
网友评论