第一行代码-第二版(郭霖著)笔记六(持久化技术)

目录

一、持久化技术简介

二、文件存储

1.将数据存储到文件中

2.从文件中读取数据

三、SharedPreference存储

1.将数据存储到SharedPreferences中

2.从SharedPreferences中读取数据

3.实现记住密码的功能

四、SQLite数据库存储

1.创建数据库

2.升级数据库

3.添加数据

4.更新数据

5.删除数据

6.查询数据

7.使用SQL操作数据库

 五、使用LitePal操作数据库

1.配置LitePal

2.创建和升级数据库

3.使用LitePal添加数据

4.使用LitePal更新数据

5.使用LitePal删除数据

6.使用LitePal查询数据


一、持久化技术简介

持久化技术提供了一种机制可以让数据从内存转换到存储设备中

Android提供了3种方式实现数据持久化功能:文件存储、SharedPreference存储和数据库存储

二、文件存储

1.将数据存储到文件中

Context类提供了一个openFileOutput()方法,可以将数据存储到指定的文件。

第一个参数是文件名(不包含路径),第二个参数是文件的操作模式,MODE_PRIVATE是默认操作模式,表示指定同样文件名时,写入的内容会覆盖原有的内容;MODE_APPEND表示文件名已存在时追加内容,不存在时创建新文件。

public class MainActivity extends AppCompatActivity {

    private EditText edit;

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

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

    public void save(String s) {
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            //openFileOutput是ContextWrapper类的方法
            out = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(s);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2.从文件中读取数据

public class MainActivity extends AppCompatActivity {

    private EditText edit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edit = findViewById(R.id.edit);
        String s = load();
        //TextUtils.isEmpty()方法可以一次性进行两种空值的判断,传入的字符串等于null或等于空字符串时都会返回true
        if(!TextUtils.isEmpty(s)){
            edit.setText(s);
            //调用setSelection()方法将输入光标移动到文本的末尾位置以便继续输入
            edit.setSelection(s.length());
            Toast.makeText(this, "Restoring succeeded", Toast.LENGTH_SHORT).show();
        }
    }

    ...

    private String load(){
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder builder = new StringBuilder();
        try {
            in = openFileInput("data");
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine())!=null){
                builder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return builder.toString();
    }
}

三、SharedPreference存储

以键值对的方式存储数据

获取Sharedpreferences对象的三种方法:

  1. Context类中的getSharedPreferences()方法第一个参数指定SharedPreferences文件的名称,指定的文件不存在则会创建一个,第二个参数指定操作模式,只有MODE_PRIVATE一种模式可选,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写
  2. Activity类中的getPreferences()方法:只接收一个操作模式参数,因为这个方法会自动将当前活动的类名作为SharedPreferences的文件名
  3. PreferenceManager类中的getDefaultSharedPreferences()方法:这是一个静态方法,接收一个Context参数,自动使用当前应用程序的包名作为前缀来命名Sharedpreferences文件

1.将数据存储到SharedPreferences中

  1. 调用SharedPreferences对象的edit()方法获取SharedPreferences.Editor对象
  2. 使用putString()或putBoolean()方法向SharedPreferences.Editor对象添加数据
  3. 调用apply()方法将添加的数据提交
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button save = findViewById(R.id.save);
        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SharedPreferences.Editor editor = getSharedPreferences("data", Context.MODE_PRIVATE).edit();
                editor.putString("name", "jack");
                editor.putInt("age", 28);
                editor.putBoolean("married", false);
                //提交,完成数据存储操作
                editor.apply();
            }
        });
    }
}

2.从SharedPreferences中读取数据

调用SharedPreferences对象的getString(),getInt()和getBoolean()方法,这些get方法接收两个参数,第一个参数是键,第二个参数是默认值

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Jack";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...

        Button restore = findViewById(R.id.restore);
        restore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SharedPreferences pref = getSharedPreferences("data", Context.MODE_PRIVATE);
                String name = pref.getString("name", "");
                int age = pref.getInt("age", 0);
                boolean married = pref.getBoolean("married", false);
                Log.d(TAG, "name is " + name);
                Log.d(TAG, "name is " + age);
                Log.d(TAG, "name is " + married);
            }
        });
    }
}

3.实现记住密码的功能

public class LoginActivity extends BaseAcitvity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_layout);
        Button login = findViewById(R.id.login);
        EditText account = findViewById(R.id.account);
        EditText password = findViewById(R.id.password);
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        CheckBox rememberPassword = findViewById(R.id.remember_password);
        boolean aBoolean = pref.getBoolean("remember_password", false);
        if(aBoolean){
            String account1 = pref.getString("account", "");
            String password1 = pref.getString("password", "");
            account.setText(account1);
            password.setText(password1);
            rememberPassword.setChecked(true);
        }
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String s_acount = account.getText().toString();
                String s_password = password.getText().toString();
                if ("admin".equals(s_acount) && "123456".equals(s_password)) {
                    SharedPreferences.Editor editor = pref.edit();
                    if(rememberPassword.isChecked()){
                        editor.putString("account",s_acount);
                        editor.putString("password",s_password);
                        editor.putBoolean("remember_password",true);
                    }else {
                        editor.clear();
                    }
                    editor.apply();
                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                    startActivity(intent);
                    finish();
                }else {
                    Toast.makeText(LoginActivity.this, "account or password is invalid", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

四、SQLite数据库存储

1.创建数据库

SQLiteOpenHelper抽象类

两个抽象方法:onCreate()和onUpgrade()分别实现创建数据库和升级数据库的逻辑

两个实例方法:getReadableDatabase()和getWritableDatabase(),两个方法都可以创建或打开一个现有的数据库,并返回一个可对数据库进行读写操作的对象SQLiteDatabase

两个构造方法,一般使用参数少一点的构造方法:第一个参数是Context,第二个参数是数据库名,第三个参数一般是null,第四个参数表示当前数据库的版本号

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, "创建Book表成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
    Button createDatabase = findViewById(R.id.create_database);
    createDatabase.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dbHelper.getWritableDatabase();
        }
    });
}

//sqlite3加上数据库名的路径就可以打开数据库
C:\Users\51074>sqlite3 "D:\it\zklianxi\BookStore.db"
SQLite version 3.32.2 2020-06-04 12:58:43
Enter ".help" for usage hints.
//查看数据库目前有哪些表
sqlite> .table
Book              android_metadata
//查看建表语句
sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE Book (id integer primary key autoincrement,author text,price real,pages integer,name text);
CREATE TABLE sqlite_sequence(name,seq);
//.exit或.quit命令可以退出数据库的编辑
sqlite> .exit

2.升级数据库

在onUpgrade()方法中先将存在的表drop掉,再在里面调用onCreate()方法

构造方法的第四个参数传一个比之前大的数,就可以让onUpgrade()方法运行

3.添加数据

调用SQLiteDatabase实例的insert()方法可以添加数据,第一个参数是表名,第二个参数传入null,第三个参数是一个ContentValues对象,它提供了一系列的put()方法重载

Button addData = findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SQLiteDatabase database = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("name","harry");
        values.put("author","jack");
        values.put("pages",19);
        values.put("price",19.99);
        database.insert("Book",null,values);
        values.clear();
        values.put("name","potter");
        values.put("author","jack");
        values.put("pages",20);
        values.put("price",20.00);
        database.insert("Book",null,values);
    }
});

4.更新数据

update()方法对所有数据进行更新,第一个参数是表名,第二个参数是ContentValues对象,第三四个参数用于约束更新某一行或某几行的数据,不指定默认更新所有行

Button updateData = findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("price",2000);
        db.update("Book",values,"name = ?",new String[]{"potter"});
    }
});

5.删除数据

delete()方法对数据进行删除,第一个参数是表名,第二三个参数用于约束删除某一行或某几行的数据,不指定默认删除所有行

Button deleteData = findViewById(R.id.delete_data);
deleteData.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Log.d("123123","11111");
        db.delete("Book","pages < ?",new String[]{"70"});
    }
});

6.查询数据

query()方法对数据进行查询,第一个参数是表名,第二个参数用于指定去查哪几列,第三四个参数用于约束查询某一行或某几行的数据,第五个参数用于指定需要group by的列,第六个参数对group by进行过滤,第七个参数指定查询结果的排序方式

query()方法返回一个Cursor对象

Button queryData = findViewById(R.id.query_data);
queryData.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Cursor cursor = db.query("Book", null, null, null, null, null, null);
        if(cursor.moveToFirst()){
            do{
                String author = cursor.getString(cursor.getColumnIndex("author"));
                Double price = cursor.getDouble(cursor.getColumnIndex("price"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                String name = cursor.getString(cursor.getColumnIndex("name"));
                Log.d("Mainactivity","author is : "+author);
                Log.d("Mainactivity","price is : "+price);
                Log.d("Mainactivity","pages is : "+pages);
                Log.d("Mainactivity","name is : "+name);
            }while (cursor.moveToNext());
        }
    }
});

7.使用SQL操作数据库

除了查询数据的时候调用的是SQLiteDatabase的rawQuery()方法,其他操作都是调用execSQL()方法

        Button queryData = findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
//                Cursor cursor = db.query("Book", null, null, null, null, null, null);
                Cursor cursor = db.rawQuery("select * from Book", null);
                if(cursor.moveToFirst()){
                    do{
                        String author = cursor.getString(cursor.getColumnIndex("author"));
                        Double price = cursor.getDouble(cursor.getColumnIndex("price"));
                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        Log.d("Mainactivity","author is : "+author);
                        Log.d("Mainactivity","price is : "+price);
                        Log.d("Mainactivity","pages is : "+pages);
                        Log.d("Mainactivity","name is : "+name);
                    }while (cursor.moveToNext());
                }
            }
        });

 五、使用LitePal操作数据库

LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式

1.配置LitePal

  • 编辑app/build.gradle文件,在dependencies闭包中添加

implementation 'org.litepal.android:core:2.0.0'
  • 右击app/src/main,创建assets目录,在目录下新建litepal.xml文件,编辑内容如下

<?xml version="1.0" encoding="utf-8" ?>
<litepal>
    <dbname value="BookStroe"></dbname>
    <version value="1"></version>
    <list>
        
    </list>
</litepal>
  • 修改AndroidManifest.xml中的代码

<application
    android:name="org.litepal.LitePalApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.LitePalTest">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

2.创建和升级数据库

创建数据库:

  1. 创建一个Java bean,比如Book类

  2. 将Book类添加到映射模型列表中,修改litepal.xml中的代码

  3. 调用Connector.getDatabase()方法就是一次最简单的数据库操作

<?xml version="1.0" encoding="utf-8" ?>
<litepal>
    <dbname value="BookStore"></dbname>
    <version value="1"></version>
    <list>
        <mapping class="com.jack.litepaltest.Book"></mapping>
    </list>
</litepal>

升级数据库:

  1. 修改Book类,再创建一个Category类

  2. 将Category类也添加到映射模型列表中,并且将版本号加1

3.使用LitePal添加数据

  1. Java bean类继承DataSupport类

  2. 创建Java bean的实例,调用set方法,最后调用save()方法完成数据库添加操作

4.使用LitePal更新数据

第一种更新方式:

对已存储对象重新设值,已存储对象是根据调用model.isSaved()方法的结果来判断

第二种更新方式:

Book book = new Book();
book.setPrice(3000.0);
book.setPress("potter");
book.updateAll("name = ? and author = ? ","harry","jack");

5.使用LitePal删除数据

和更新数据一样也有两种,第二种是:

DataSupport.deleteAll(Book.class,"name = ?","potter");

6.使用LitePal查询数据

List<Book> books = DataSupport.findAll(Book.class);

LitePal还有很多查询API,详见书内,就不记笔记了


完! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值