第一行代码——第六章:数据存储全方案——详解持久化技术

目录:

6.1 持久化技术简介

6.2 文件存储

6.2.1 将数据存储到文件中

6.2.2 从文件中读出数据

6.3 SharedPreferences 存储

6.3.1 将数据存储到SharedPreferences中

6.3.2 从SharedPreferences 中读取数据

6.3.3 实现记住密码功能

6.4 SQLite数据库存储

6.4.1 创建数据库

6.4.2 升级数据库

6.4.3 添加数据

6.4.4 更新数据

6.4.5 删除数据

6.4.6 查询数据

6.4.7 使用SQL操作数据库

6.5 使用LitePal操作数据库

6.5.1 LitePal简介

6.5.2 配置LitePal

6.5.3 创建和升级数据库

6.5.4 使用LitePal添加数据

6.5.5 使用LitePal更新数据

6.5.6 使用LitePal删除数据

6.5.7 使用LitePal查询数据

6.6 小结与点评


知识点:

6.1 持久化技术简介

数据持久化是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失。保存在内存中的数据是处于瞬时状态的,而保存在存储设备中的数据是处于持久状态的,持久化技术则是提供了一种机制可以让数据在瞬时状态和持久状态之间进行转换。

Android 系统主要提供了三种方式实现数据持久化功能 即文件存储、SharedPreference 存储以及数据库存储。当然,也可以将数据保存在手机的 SD 卡中,但相对会复杂一些,而且不安全。

6.2 文件存储

文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中的,因而它比较适合用于存储一些简单的文本数据或二进制数据。

6.2.1 将数据存储到文件中

在这里,我们通过Context 类中提供了一个 openFileOutput () 方法,用于将数据存储到指定的文件中。

Context 类中还提供了一个 openFileInput() 方法,用于从文件中读取数据。

 private void save(String string) {
        String data = "Data to save";

        FileOutputStream fos = null;
        BufferedWriter writer = null;
        try {
            fos = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(fos));
            writer.write(string);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

6.2.2 从文件中读出数据

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

        }
    }

6.3 SharedPreferences 存储

不同于文件的存储方式,SharedPreferences 是使用键值对的方式来存储数据的。

获取SharedPreferences 对象

  • Context 类中的 getSharedPreferences()方法
      此方法接收两个参数,第一个参数指定 SharedPreferences 文件的名称,第二个参数指定操作模式,目前只有 MODE_PRIVATE 一种模式,和直接传入 0 效果相同。其他几种模式已被废弃。

  • Activity 类中的 getPreferences()方法
      此方法和上面的方法相似,但只接收一个操作模式参数,使用这个方法时会自动将当前活动的类名作为 SharedPreferences 的文件名。

  • PreferenceManager 类中的 getDefaultSharedPreferences()方法
      这是一个静态方法,它接收一个 Context 参数,并自动使用当前应用程序的包名作为前缀来命名 SharedPreferences 文件。

向sSharedPreferences 中存储内容

调用 SharedPreferences 对象的 edit()方法来获取一个 SharedPreferences.Editor 对象。
向 SharedPreferences.Editor 对象中添加数据,如添加一个布尔型数据使用 putBoolean 方法,添加一个字符串使用 putString()方法,以此类推。
调用 apply()方法将添加的数据提交,完成数据存储。

6.3.1 将数据存储到SharedPreferences中

    SharedPreferences.Editor sp = getSharedPreferences("data", MODE_PRIVATE).edit();
        sp.putString("uid", "1");
        sp.apply();

6.3.2 从SharedPreferences 中读取数据

//        SharedPreferences sp=getSharedPreferences("data", MODE_PRIVATE);
//        sp.getString()

6.3.3 实现记住密码功能

我们首先封装一下SharedPreferences

public class PrefUtils {

    private static final String PREF_NAME = "config";

    /**
     * 读取布尔数据
     * @param ctx 上下文
     * @param key 键
     * @param defaultValue 默认值
     * @return
     */
    public static boolean getBoolean(Context ctx, String key,
                                     boolean defaultValue) {
        SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        return sp.getBoolean(key, defaultValue);
    }

    /**
     * 添加布尔数据
     * @param ctx 上下文
     * @param key 键
     * @param value 添加的数据
     */
    public static void setBoolean(Context ctx, String key, boolean value) {
        SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        sp.edit().putBoolean(key, value).apply();
    }

    /**
     * 读取字符串
     * @param ctx
     * @param key
     * @param defaultValue
     * @return
     */
    public static String getString(Context ctx, String key, String defaultValue) {
        SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        return sp.getString(key, defaultValue);
    }

    /**
     * 添加字符串
     * @param ctx
     * @param key
     * @param value
     */
    public static void setString(Context ctx, String key, String value) {
        SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        sp.edit().putString(key, value).apply();
    }

    /**
     * 读取int类型数据
     * @param ctx
     * @param key
     * @param defaultValue
     * @return
     */
    public static int getInt(Context ctx, String key, int defaultValue) {
        SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        return sp.getInt(key, defaultValue);
    }

    /**
     * 添加int类型数据
     * @param ctx
     * @param key
     * @param value
     */
    public static void setInt(Context ctx, String key, int value){
        SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        sp.edit().putInt(key, value).apply();
    }

    /**
     * 将数据全部清除掉
     * @param ctx
     */
    public static void clear(Context ctx){
        SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        sp.edit().clear().apply();
    }
}

然后来编辑下登录界面,修改 activity_login.xml 中的代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!--***************** 账号 *********************-->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="center"
            android:textSize="18sp"
            android:text="账号:"/>

        <EditText
            android:id="@+id/et_account"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"/>
    </LinearLayout>

    <!--***************** 密码 *********************-->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp">
        <TextView
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="center"
            android:textSize="18sp"
            android:text="密码:"/>

        <EditText
            android:id="@+id/et_password"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:inputType="textPassword"/>
    </LinearLayout>

    <!--***************** 是否记住密码 *********************-->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <CheckBox
            android:id="@+id/cb_remember_pass"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:layout_gravity="center_vertical"
            android:text="记住密码"/>

    </LinearLayout>

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_margin="10dp"
        android:text="登录"/>

</LinearLayout>

只是添加了个 CheckBox 来勾选记住密码,接着修改 LoginActivity 的代码,如下:

public class LoginActivity extends BaseActivity {

    private EditText et_account, et_password;
    private CheckBox cb_remember_pass;
    private Button btn_login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        et_account = (EditText) findViewById(R.id.et_account);
        et_password = (EditText) findViewById(R.id.et_password);
        cb_remember_pass = (CheckBox) findViewById(R.id.cb_remember_pass);
        btn_login = (Button) findViewById(R.id.btn_login);
        
        Boolean isRemember = PrefUtils.getBoolean(this,"remember_pass",false);
        if (isRemember){
            // 将账号和密码都设置到文本框中
            String account = PrefUtils.getString(this,"account","");
            String password = PrefUtils.getString(this,"password","");
            et_account.setText(account);
            et_password.setText(password);
            cb_remember_pass.setChecked(true);
        }

        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String account = et_account.getText().toString();
                String password = et_password.getText().toString();
                // 若账号是 wonderful 且密码是 123456,就认为登录成功
                if (account.equals("wonderful") && password.equals("123456")){
                    // 检查复选框是否被勾选
                    if (cb_remember_pass.isChecked()){
                        // 保存数据到SharePreference文件中
                        PrefUtils.setBoolean(LoginActivity.this,"remember_pass",true);
                        PrefUtils.setString(LoginActivity.this,"account",account);
                        PrefUtils.setString(LoginActivity.this,"password",password);
                    }else {
                        // 清除SharePreference文件中的数据
                        PrefUtils.clear(LoginActivity.this);
                    }
                    // 登录成功跳转到主界面
                    IntentUtils.myIntent(LoginActivity.this,ForceOfflineActivity.class);
                    finish();
                }else {
                    ToastUtils.showShort("账号或密码无效!");
                }
            }
        });

    }

    @Override
    protected int initLayoutId() {
        return R.layout.activity_login;
    }
}

具体代码就不解释了,看注释。

现在运行下程序,输入账号和密码并选中记住密码复选框后,点击登录,就会跳转到 ForceOfflineActivity。接着在 ForceOfflineActivity 中发出一条强制下线广播会让程序重新回到登录界面, 此时你会发现,账号密码都已经自动填充到界面上了,如下:

记住密码功能效果这样我们就使用 SharedPreferences 技术将记住密码功能成功实现了。当然这只是个简单的示例,实际项目中将密码以明文的形式存储在 SharedPreferences 文件中是不安全的,还需配合加密算法进行保护。

6.4 SQLite数据库存储

6.4.1 创建数据库

6.4.2 升级数据库

6.4.3 添加数据

6.4.4 更新数据

6.4.5 删除数据

6.4.6 查询数据

6.4.7 使用SQL操作数据库

以上关于SQLite内容 我单独写了一篇文章 请看:

https://blog.csdn.net/lhk147852369/article/details/83307384

6.5 使用LitePal操作数据库

6.5.1 LitePal简介

LitePal 是一款开源的 Android 数据库框架,它采用了对象关系映射(ORM)的模式,并将我们平时开发最常用到的一些数据库功能进行了封装,使得不用编写一行 SQL 语句就可以完成各种建表和增删查改的操作。LitePal 的项目主页上也有详细的使用文档,地址是:https://github.com/LitePalFramework/LitePal

6.5.2 配置LitePal

使用 LitePal 的第一步,在 app/build.gradle 文件中引入 LitePal 的最新版本:

compile 'org.litepal.android:core:1.4.1'

项目中引入 LitePal 成功后,需要配置 litepal.xml 文件。右击 app/src/main 目录→New→Directory,创建一个 assets 目录,然后在 assets 目录下再新建一个 litepal.xml 文件,接着编辑 litepal.xml 文件中的内容,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <!-- 指定数据库名 -->
    <dbname value="MyBookStore"></dbname>

    <!-- 指定数据库版本号 -->
    <version value="1"></version>

    <!-- 指定所有的映射模型 -->
    <list>

    </list>
</litepal>

最后还要在 Application 中调用 LitePal 的初始化方法:

/**
 * 全局
 * Created by KXwon on 2016/12/9.
 */
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        // 调用 LitePal 的初始化方法
        LitePal.initialize(this);
    }
}

当然别忘了在 AndroidManifest.xml 中配置 Application:

<application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    . . .
 </application>

现在 LitePal 的配置工作完成了,下面正式开始使用它吧。

6.5.3 创建和升级数据库

郭霖专栏:Android数据库高手秘籍(二)——创建表和LitePal的基本用法

https://blog.csdn.net/guolin_blog/article/details/38556989

6.5.4 使用LitePal添加数据

郭霖专栏:Android数据库高手秘籍(五)——LitePal的存储操作

https://blog.csdn.net/guolin_blog/article/details/39345833

6.5.5 使用LitePal更新数据

6.5.6 使用LitePal删除数据

郭霖专栏:Android数据库高手秘籍(六)——LitePal的修改和删除操作

https://blog.csdn.net/guolin_blog/article/details/40083685

6.5.7 使用LitePal查询数据

郭霖专栏:

https://blog.csdn.net/guolin_blog/article/details/40153833

6.6 小结与点评

郭霖总结:

经过了这一章漫长的学习,我们终于可以缓解一下疲劳,对本章所学的知识进行核现和总结了。本章主要是对Android常用的数据持久化方式进行了详细的讲解,包括文件存储器 SharedPreferences存储以及数据库存储。 其中文件适用于存储一-些简单的文本数据或者二进制数适用于存储些键值队 ,而数据库则适用于存储那些复杂的关系型数据。虽然目前你已经掌握了这3种数据持久化方式的用法,但是能够根据项目的实际需求来选择最合适的方式也是你未来需要继续探索的。

那么正如上一章小结里提到的,既然现在我们已经掌握了Anid中的数据持久化技术,接下来就应该继续学习 Adoid中剩余的四大组件了。放松下自己,然后一起踏上内容提供器的学习之旅吧。

我的总结:

存储这一方面也是比较重要的,经过了这章内容的学习,我的能力又有了很大的进步,对于java中的Sterm流 相关的内容 也有了更多的了解。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate是一个开源的Java对象持久化框架,它提供了一种方便的方式来将Java对象映射到数据库中的表,从而实现对象的持久化。下面是对Hibernate进行详细解释。 首先,Hibernate是基于ORM(对象关系映射)的技术。ORM是一种编程技术,它允许开发人员将Java对象与数据库表进行映射。通过Hibernate,开发人员只需要在Java类的注解或XML配置文件中定义对象的映射关系,就能够实现对象与数据库之间的转换。 其次,Hibernate提供了丰富的查询语言。Hibernate提供了一种称为HQL(Hibernate Query Language)的查询语言,它类似于SQL,但更加面向对象。开发人员可以利用HQL进行复杂的查询操作,而不需要直接编写SQL语句。 此外,Hibernate还支持事务管理。在Hibernate中,开发人员可以通过事务来管理数据库操作的一致性和原子性。通过使用Hibernate的事务管理,开发人员能够确保多个数据库操作在一个事务中执行,避免了数据不一致的问题。 另外,Hibernate还具有缓存功能。Hibernate提供了一级缓存和二级缓存,开发人员可以利用这些缓存来提高数据访问的性能。一级缓存是Hibernate默认的缓存机制,它将查询操作的结果缓存到Session对象中,减少了与数据库的交互次数。二级缓存是可选的,它将查询操作的结果缓存到SessionFactory中,用于多个Session之间的共享。 最后,Hibernate还具备透明的数据库操作功能。通过Hibernate,开发人员可以使用面向对象的方式进行数据库操作,而不需要关心底层数据库的细节。Hibernate会自动处理数据库连接、SQL语句的生成和执行等操作,极大地简化了数据库操作的过程。 综上所述,Hibernate作为一种Java对象持久化技术,提供了方便的对象与数据库之间的映射方式,丰富的查询语言,事务管理,缓存机制和透明的数据库操作功能。它的出现极大地简化了开发人员对数据库的操作,提高了开发效率和代码的可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值