其他分享
首页 > 其他分享> > 15天快速入门安卓开发(六)持久化存储技术

15天快速入门安卓开发(六)持久化存储技术

作者:互联网

文章目录

六 持久化存储技术

持久化技术则提供了一种机制可以让数据在瞬时状态和持久状态之间进行转换。我们常见的有三种,文件存储,即文件存储、SharedPreferences存储以及数据库存储

6.1 文件存储

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

/**
     * 文件存储
     * @param view
     */
    public void save(View view){
        FileOutputStream outputStream=null;
        BufferedWriter writer=null;
        String data = editText.getText().toString();
        try {
            //Context.MODE_PRIVATE 先建文件,Context.MODE_APPEND追加
            outputStream=openFileOutput("data",Context.MODE_PRIVATE );
            writer=new BufferedWriter(new OutputStreamWriter(outputStream));
            writer.write(data);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
 /**
     * 加载数据
     * @param view
     */
    public void load(View view){
        FileInputStream fileInputStream=null;
        BufferedReader bufferedReader=null;
        StringBuilder stringBuilder=new StringBuilder();
        try {
            fileInputStream=openFileInput("data");
            bufferedReader=new BufferedReader(new InputStreamReader(fileInputStream));
            String line="";
            while((line=bufferedReader.readLine())!=null){
               stringBuilder.append(line);
            }
            Log.d("日志",stringBuilder.toString());
            editText.setText(stringBuilder.toString());
            editText.setSelection(stringBuilder.toString().length());

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

Context类中提供的openFileInput()和openFileOutput()方法,之后就是利用Java的各种流来进行读写操作

6.2 SharedPreferences存储

这个其实可以把他理解为键值对存储

我们来一个简单登录与记住密码案例

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/username"
        android:orientation="horizontal"
        android:layout_centerVertical="true"
        >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="账号:"
            android:textSize="30sp"
            android:gravity="center"
            />
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/account"
            android:hint="请输入账号"
            />
    </LinearLayout>




    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/password"
        android:orientation="horizontal"
        android:layout_below="@id/username"

        >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密码:"
            android:textSize="30sp"
            android:gravity="center"
            />
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/pwd"
            android:hint="请输入密码"
            android:inputType="textPassword"
            />
    </LinearLayout>

    <CheckBox
        android:layout_below="@id/password"
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="记住密码" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录"
        android:layout_below="@id/checkBox"
        android:layout_centerHorizontal="true"
        android:onClick="login"
        />


</RelativeLayout>
package com.shu;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;

public class SharedPreferencesActivity extends AppCompatActivity {

    private EditText username;

    private EditText password;

    private Button button;

    private CheckBox checkBox;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shared_preferences);
        SharedPreferences preferences = this.getSharedPreferences( "data", Context.MODE_PRIVATE );
        String usernames = preferences.getString("username", "");
        Log.d("日志",usernames);
        String passwords = preferences.getString("password", "");
        Log.d("日志",passwords);
        boolean remeber = preferences.getBoolean("remeber", false);
        Log.d("日志", String.valueOf(remeber));
        if(remeber){
            EditText editText = (EditText) findViewById(R.id.account);
            editText.setText(usernames);
            EditText editText1 = (EditText) findViewById(R.id.pwd);
            editText1.setText(passwords);
            CheckBox view = (CheckBox) findViewById(R.id.checkBox);
            view.setChecked(remeber);
        }
    }

    /**
     * 登录
     * @param view
     */
    public void login(View view){
       username= findViewById(R.id.account);
       password=findViewById(R.id.pwd);
       checkBox=findViewById(R.id.checkBox);
        SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
        editor.putString("username",username.getText().toString());
        editor.putString("password",password.getText().toString());
        editor.putBoolean("remeber",checkBox.isChecked());
        editor.apply();
    }

}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

6.3 数据库存储

SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百KB的内存就足够了,因而特别适合在移动设备上使用。SQLite不仅支持标准的SQL语法,还遵循了数据库的ACID事务,所以只要你以前使用过其他的关系型数据库,就可以很快地上手SQLite。

语法

SQLite的语法其实跟Mysql,oracle数据库的语法差不多

数据类型

常用API

方法名称方法表示含义
openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory)打开或创建数据库
insert(String table,String nullColumnHack,ContentValues values)插入一条记录
delete(String table,String whereClause,String[] whereArgs)删除一条记录
query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)查询一条记录
update(String table,ContentValues values,String whereClause,String[] whereArgs)修改记录
execSQL(String sql)执行一条SQL语句
close()关闭数据库
db=SQLiteDatabase.openOrCreateDatabase("/data/data/com.lingdududu.db/databases/stu.db",null);
private void createTable(SQLiteDatabase db){
//创建表SQL语句
String stu_table="create table usertable(_id integer primary key autoincrement,sname text,snumber text)";
//执行SQL语句
db.execSQL(stu_table);
}

在Android中查询数据是通过Cursor类来实现的,当我们使用SQLiteDatabase.query()方法时,会得到一个Cursor对象,Cursor指向的就是每一条数据。它提供了很多有关查询的方法,具体方法如下:

方法名称方法描述
getCount()获得总的数据项数
isFirst()判断是否第一条记录
isLast()判断是否最后一条记录
moveToFirst()移动到第一条记录
moveToLast()移动到最后一条记录
move(int offset)移动到指定记录
moveToNext()移动到下一条记录
moveToPrevious()移动到上一条记录
getColumnIndexOrThrow(String columnName)根据列名称获得列索引
getInt(int columnIndex)获得指定列索引的int类型值
getString(int columnIndex)获得指定列缩影的String类型值
private void query(SQLiteDatabase db) {  
//查询获得游标  
Cursor cursor = db.query ("usertable",null,null,null,null,null,null);  
   
//判断游标是否为空  
if(cursor.moveToFirst() {  
//遍历游标  
for(int i=0;i<cursor.getCount();i++){  
cursor.move(i);  
//获得ID  
int id = cursor.getInt(0);  
//获得用户名  
String username=cursor.getString(1);  
//获得密码  
String password=cursor.getString(2);  
//输出用户信息 System.out.println(id+":"+sname+":"+snumber);  
}  
}  
}
private void insert(SQLiteDatabase db){
//实例化常量值
ContentValues cValue =new ContentValues();
//添加用户名
cValue.put("sname","xiaoming");
//添加密码
cValue.put("snumber","01005");
//调用insert()方法插入数据
db.insert("stu_table",null,cValue);
}

private void insert(SQLiteDatabase db){
//插入数据SQL语句
String stu_sql="insert into stu_table(sname,snumber) values('xiaoming','01005')";
//执行SQL语句
db.execSQL(sql);
}
rivate void update(SQLiteDatabase db) {  
//实例化内容值 ContentValues values = new ContentValues();  
//在values中添加内容  
values.put("snumber","101003");  
//修改条件  
String whereClause ="id=?";  
//修改添加参数  
String[] whereArgs={String.valuesOf(1)};  
//修改  
db.update("usertable",values,whereClause,whereArgs);  
}  


private void update(SQLiteDatabase db){  
//修改SQL语句  
String sql ="update stu_table set snumber = 654321 where id = 1";  
//执行SQL  
db.execSQL(sql);  
} 
private void delete(SQLiteDatabase db) {
//删除条件
String whereClause ="id=?";
//删除条件参数
String[] whereArgs = {String.valueOf(2)};
//执行删除
db.delete("stu_table",whereClause,whereArgs);
}


private void delete(SQLiteDatabase db) {  
//删除SQL语句  
String sql ="delete from stu_table where _id = 6";  
//执行SQL语句  
db.execSQL(sql);  
}  

SQLiteOpenHelper

该类是SQLiteDatabase一个辅助类。这个类主要生成一 个数据库,并对数据库的版本进行管理。当在程序当中调用这个类的方法getWritableDatabase()或者 getReadableDatabase()方法的时候,如果当时没有数据,那么Android系统就会自动生成一个数据库。

package com.shu;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import androidx.annotation.Nullable;

/**
 * @author shu
 * @date 2021/7/20
 * @description
 */
public class SqlLiteUtils extends SQLiteOpenHelper {

    /**
     * sql语句
     */
    private static String sql01="create table user(id integer primary key autoincrement,name text,number text)";

    private static String sql02="create table book(id integer primary key autoincrement,name text,type text)";

    private Context myContext;

    /**
     * @param context 上下文
     * @param name   数据库名
     * @param factory 自定义的Cursor
     * @param version  版本号
     */
    public SqlLiteUtils(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        myContext=context;
    }


    /**
     * 创建数据库
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(sql01);
        db.execSQL(sql02);
        Toast.makeText(myContext,"数据库创建成功",Toast.LENGTH_LONG).show();
    }

    /**
     * 升级数据库
     * @param db
     * @param oldVersion
     * @param newVersion
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists user");
        db.execSQL("drop table if exists book");
        onCreate(db);
    }
}

如何查看Sqlite数据库

在这里插入图片描述

在这里插入图片描述

adb shell  //运行Linux命令
cd data/data/全类名/databases //进入数据库文件所在文件夹
ls //查看文件
sqlite3 数据库名 //进入数据库
.table //查看所有表
select * from 表名 //查看具体表

6.4 开源框架

官网:https://github.com/guolindev/LitePal

LitePal是一款开源的Android数据库框架,它采用了对象关系映射(ORM)的模式,并将我们平时开发最常用到的一些数据库功能进行了封装,使得不用编写一行SQL语句就可以完成各种建表和増删改查的操作。

 implementation 'org.litepal.guolindev:core:3.1.1'

基本使用

package com.shu.pojo;

import org.litepal.crud.LitePalSupport;

/**
 * @author shu
 * @date 2021/7/20
 * @description
 */
public class Goods extends LitePalSupport {
    private String name;
    private String prices;

    public Goods(String name, String prices) {
        this.name = name;
        this.prices = prices;
    }

    public Goods() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPrices() {
        return prices;
    }

    public void setPrices(String prices) {
        this.prices = prices;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", prices='" + prices + '\'' +
                '}';
    }
}

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <!--数据库名称-->
    <dbname value="goods" />
    <!--数据库版本号-->
    <version value="1" />
    <!--用于设定所有的映射模型,即你定义数据库表的类名路径-->
    <list>
        <mapping class="com.shu.pojo.Goods" />
    </list>
</litepal>

感觉有Mybatis的那味了

在这里插入图片描述

好了,基本的配置完成了,我们就可以操作数据库了

package com.shu;

import androidx.appcompat.app.AppCompatActivity;

import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;

import com.shu.pojo.Goods;

import org.litepal.LitePal;
import org.litepal.crud.LitePalSupport;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    private SQLiteDatabase database;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        database = LitePal.getDatabase();
    }

    /**
     * 创建数据库
     * @param view
     */
    public void create(View view){
         database = LitePal.getDatabase();

    }


    /**
     * 保存方法
     * @param view
     */
    public void insert(View view){
        Goods goods = new Goods("小米", "26");
        goods.save();
    }

    /**
     * 查询数据
     * @param view
     */
    public void query(View view){
        List<Goods> list = LitePal.findAll(Goods.class);
        for (Goods goods : list) {
            System.out.println(goods);
        }

    }
}

更多用法请参考教程:https://blog.csdn.net/xxdw1992/article/details/104937107/

标签:15,String,安卓,存储技术,db,public,数据库,import,void
来源: https://blog.csdn.net/weixin_44451022/article/details/119208694