详解持久化技术

详解持久化技术

持久化技术简介

​ 持久化技术就是将内存中的临时数据保存到储存设备中,即使在手机或电脑关机的情况下,这些数据仍然不会丢失,保存在内存中的数据是瞬时状态,保存在设备中的数据则是持久状态的;持久化数据就是让数据在瞬时与持久状态之间进行转换的。android主要提供了三种方法:文件储存;SharePreference储存;数据库储存。


文件储存

将数据保存到文件中

Context类中提供了一个openFileOutput方法,可以用于将数据储存到指定文件中。这个方法接收两个参数,第一个参数是文件名,文件创建的就是这个名称,

这里输入的文件名不包含路径,因为所有的文件都是默认储存到/data/data/<packagename>/file/目录下的。第二个参数是文件的操作模式,有两种操作模式,MODE_PRIVATE(默认模式)表示当指定相同的文件名时会覆盖之前的信息;MODE_APPEND表示如果文件已存在则添加数据,否则新建文件

openFileOutput()返回一个FileOutputStream对象,得到了这个对象后用java流的方式将数据写入到文件中:

EditText editText;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    editText=findViewById(R.id.edit);
}


@Override
protected void onDestroy() {
    super.onDestroy();
    String text=editText.getText().toString();
    save(text);
}



public void save(String text){
    FileOutputStream out =null;
    BufferedWriter writer=null;
    try {
        out=openFileOutput("data", Context.MODE_PRIVATE);
        writer=new BufferedWriter(new OutputStreamWriter(out));
        writer.write(text);
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        try {
            if (writer !=null){
                writer.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输入数据之后点击返回按钮,会在文件中找到名为data的文件,里面就是保存的数据。

读取文件中的数据

Context还提供了一个openFileInput()方法,用于从文件中读取数据,这个方法接收一个参数:要读取的文件的文件名,然后系统会自动加载这个文件,并返回一个FileInputStream对象,得到这个对象后通过java流的方式读取出来。

public String read(){
    FileInputStream in=null;
    BufferedReader reader=null;
    StringBuilder context=new StringBuilder();
    try {
        in=openFileInput("data");
        reader=new BufferedReader(new InputStreamReader(in));
        String line="";
        while((line=reader.readLine())!=null){
            context.append(line);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return context.toString();
}

SharedPreferences储存

SharedPreferences储存是通过键值对的方式来存储数据的,支持多种数据类型储存

将数据储存到SharedPreferences

首先要获取到SharedPreferences对象,android提供了三种方法用于获取。

SharedPreferences文件都是存放在/data/data/<package name>/shared_prefs/目录下的xml文件

  1. Context类中的getSharedPreferences方法

    这个方法接收两个参数,第一个参数用于指定SharePreferences文件的名称,如果指定的文件不存在则会创建一个;第二个参数用于操作模式,可以写MODE_PRIVATE这一模式(其他模式均已废弃),表示只有当前的应用程序才能对文件进行读写,和直接传入0的效果是一样的。

  2. Activity类中的getPreferences方法

    这个方法和Context中的getSharedPreferences()方法很相似,只接收一个操作模式参数,这个方法会自动将当前活动的类名作为SharedPreferences的文件名

  3. PreferenceManager类中的getDefaultSharePreferences方法

    这是一个静态方法,接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件。得到了Sharedpreferences对象之后,就开始向Shared_Preferences文件中储存数据,分三步实现:

    1. 调用SharedPreferences对象的edit()方法来获取一个SharedPreferences.Editor对象;

    2. 向SharedPreferences对象中添加数据;

    3. 调用apply()方法将储存的数据提交,从而完成数据存储操作;

点击事件储存数据

SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
editor.putString("name","makabaka");
editor.putInt("age",20);
editor.putBoolean("married",true);
editor.apply();

Sharedferences中读取数据

put换成get差不多了

SharedPreferences preferences=getSharedPreferences("data",MODE_PRIVATE);
String name=preferences.getString("name","");
int age=preferences.getInt("age",0);
Boolean married=preferences.getBoolean("married",false);
Toast.makeText(this, name+age+married, Toast.LENGTH_SHORT).show();

SQLite数据库

创建数据库

android提供了一个SQLiteOpenHelper帮助类,这是一个抽象类,所以要使用这个类的话需要创建一个自己的帮助类来继承它。其中有两个抽象方法,onCreate()和onUpgrade(),我们需要重写这两个方法,分别在这两个方法中实现创建,升级数据库的方法。

SQLiteOpenHelper提供了两个很重要的实例方法,getReadableDatabase()和getWritableDatabase(),这两个方法都可以创建或打开一个现有数据库(如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。不同的是当数据库不可写入的时候(如磁盘空间已满),getReadableDatabase返回对象将以只读的方式打开数据库,而getWritableDatabase()方法则将出现异常。

  1. 新建MySqlLiteHelper继承SQLiteOpenHelper,重写onCreate()和onUpgrade()方法;
  2. 重写构造函数;(第一个参数:context;第二个参数:数据库名;第三个参数:一般null,第四个参数:当前数据库的版本号,可用于对数据库的升级)
  3. 获取helper对象,新建Constant表

SQLiteOpenHelper:

public class MySqlLiteHelper extends SQLiteOpenHelper {
    public MySqlLiteHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    public MySqlLiteHelper(Context context){
        super(context,Constant.DATABASE_NAME,null,Constant.DATABASE_VERSION);
    }
//创建数据库时调用这个的方法
    @Override
    public void onCreate(SQLiteDatabase db) {

    }
//数据库升级时调用的方法
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        Log.i(TAG, "open");
    }
}

DbManger:

public class DbManger {
    //获取helper对象
    private static MySqlLiteHelper helper;
    public static MySqlLiteHelper getIntance(Context context){
        if (helper==null){
            helper=new MySqlLiteHelper(context);
        }
        return helper;
    }
}

创建数据库:


private MySqlLiteHelper helper;
helper= DbManger.getIntance(this);
SQLiteDatabase db=helper.getReadableDatabase();
//创建表,也可以放在SQLiteOpenHelper中的onCreate方法中
String sql = "create table "+Constant.TABLE_NAME+" ("+Constant._ID+" Integer primary key,"+Constant.NAME+" varchar(20),"+Constant.AGE+" Integer(20))";
db.execSQL(sql);//执行sql语句

升级数据库

onUpgrade()方法是用于对数据库进行升级的,想调用这个方法就需要升级数据库;之前构造函数的第四个参数就是就是数据库版本,之前传入的是1,只用传入一个比1大的数字,就能让onUpgrade()方法执行了


增删改

adroid提供了无需sql语句进行数据库操作的方法:

helper= DbManger.getIntance(this);
        SQLiteDatabase db=helper.getReadableDatabase();
        switch (view.getId()){
            case R.id.zeng:
                /**
                 * insert(String table, String nullColumnHack, ContentValues values)
                 * String table 表示插入数据表的名称
                 * String nullColumnHack
                 * ContentValues values 键为string类型的hashmap集合
                 * 返回lang表示插入数据列数
                 */
//                SQLiteDatabase db=helper.getReadableDatabase();
                ContentValues values=new ContentValues();
                values.put(Constant._ID,3);
                values.put(Constant.NAME,"张三");
                values.put(Constant.AGE,29);
                long result=db.insert(Constant.TABLE_NAME,null,values);
                if (result>0){
                    Toast.makeText(this, "成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
                }
                db.close();
                break;
            case R.id.gai:
                helper= DbManger.getIntance(this);
                db=helper.getReadableDatabase();
                /**
                 * update(String table, ContentValues values, String whereClause, String[] whereArgs)
                 * String table表示插入数据表的名称
                 *ContentValues values键为string类型的hashmap集合
                 *String whereClause 修改条件
                 *String[] whereArgs 修改条件的占位符
                 */

                ContentValues cv=new ContentValues();
                cv.put("name","小爱");//第一个为修改的字段名,第二个为修改后的值
                int count=db.update(Constant.TABLE_NAME,cv,Constant._ID+"=3",null);//返回值为int 修改了多少行
                if (count>0){
                    Toast.makeText(this, "成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
                }
                db.close();
                break;
            case R.id.shan:
                helper= DbManger.getIntance(this);
                db=helper.getReadableDatabase();
                /**
                 *delete(String table, String whereClause, String[] whereArgs)
                 *String table表示插入数据表的名称
                 * String whereClause 修改条件
                 * String[] whereArgs 修改条件的占位符
                 */
                int count2=db.delete(Constant.TABLE_NAME,Constant._ID+"=3",null);
                if (count2>0){
                    Toast.makeText(this, "成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(this, "失败", Toast.LENGTH_SHORT).show();
                }
                db.close();
                break;

SQLiteDatabase中提供了一个query()方法用于查询数据。这个方法一共需要传入7个方法

alt query方法参数

虽然参数很多,但大部分情况都只需要少数参数就可以了;

case R.id.cha:
    helper= DbManger.getIntance(this);
    db=helper.getReadableDatabase();
    Toast.makeText(this, "cha", Toast.LENGTH_SHORT).show();
    Cursor cursor=db.query(Constant.TABLE_NAME,null,null,null,null,null,null,null);
    if (cursor.moveToFirst()){
        do{
        //便利cursor
            int id=cursor.getInt(cursor.getColumnIndex("_id"));
            String name=cursor.getString(cursor.getColumnIndex("name"));
            int age=cursor.getInt(cursor.getColumnIndex("age"));
            Log.i("1", id+name+age);
        }while (cursor.moveToNext());
    }

    db.close();
    break;

posted @ 2021-08-13 13:47  踩红帽的小姑娘  阅读(362)  评论(0)    收藏  举报