Android Studio学习条记——数据库存储

打印 上一主题 下一主题

主题 518|帖子 518|积分 1554

数据持久化技能就是将内存中瞬时数据保存到存储设备中,保证关机大概重启之后不会数据丢失。
6.1持久化技能简介

Android中紧张提供了三种方式用于简单的实现数据持久化功能,即文件存储、SharedPreference存储以及数据库存储。除此之外,另有其他方式,比如说存在SD卡中。文件存储、SharedPreference存储以及数据库存储这三种比存在SD卡中简单,而且更安全。
6.2 文件存储

文件存储不对数据举行任何格式化的处理,得当存储一些简单的文本数据或二进制数据。如果想要存储复杂的数据,就要自定义一套本身的格式规范,如许以后方便从文件中重新解析出来。
将数据存储到文件中

Context类提供了一个openFileOutput()方法,可将数据存到文件中。
这个方法吸收两个参数:


  • 第一个参数:文件名。(不可以包含路径,都默认存储到/data/data/<package name/files/)
  • 第二个参数:文件的使用模式。有两种。

    • MODE_PRIVATE:默认使用模式,指定同名文件会覆盖源文件内容。
    • MODE_APPEND:如果文件存在,则往文件末了追加内容。不存在同名文件则创建新文件。

openFileOutput()返回一个FileOutputStream对象,得到该对象可以使用Java流的方式将数据写入到文件中了。
  1. public void save(){
  2.         String data="Data to save";
  3.         FileOutputStream out=null;
  4.         BufferedWriter writer=null;
  5.         try{
  6.             out=openFileOutput("data", Context.MODE_PRIVATE);
  7.             writer=new BufferedWriter(new OutputStreamWriter(out));
  8.         }
  9.         catch (IOException e){
  10.             e.printStackTrace();
  11.         }
  12.         finally {
  13.             try {
  14.                 if(writer!=null){
  15.                     writer.close();
  16.                 }
  17.                
  18.             } catch (IOException e){
  19.                 e.printStackTrace();
  20.             }
  21.         }
  22.     }
复制代码
从文件中读取数据

  1. public class MainActivity extends AppCompatActivity {
  2.     private EditText edit;
  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         EdgeToEdge.enable(this);
  7.         setContentView(R.layout.activity_main);
  8.         ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
  9.             Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
  10.             v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
  11.             return insets;
  12.         });
  13.         edit=(EditText) findViewById(R.id.edit);
  14.         String inputText=load();
  15.         if(!TextUtils.isEmpty(inputText)){
  16.             edit.setText(inputText);
  17.             edit.setSelection(inputText.length());
  18.             Toast.makeText(this,"Restoring succeeded ",Toast.LENGTH_SHORT).show();
  19.         }
  20.     }
  21.     public void save(String inputText){
  22.         String data="Data to save";
  23.         FileOutputStream out=null;
  24.         BufferedWriter writer=null;
  25.         try{
  26.             out=openFileOutput("data", Context.MODE_PRIVATE);
  27.             writer=new BufferedWriter(new OutputStreamWriter(out));
  28.             writer.write(inputText);
  29.         }
  30.         catch (IOException e){
  31.             e.printStackTrace();
  32.         }
  33.         finally {
  34.             try {
  35.                 if(writer!=null){
  36.                     writer.close();
  37.                 }
  38.             } catch (IOException e){
  39.                 e.printStackTrace();
  40.             }
  41.         }
  42.     }
  43.     public void onDestroy(){
  44.         super.onDestroy();
  45.         String inputText=edit.getText().toString();
  46.         save(inputText);
  47.     }
  48.     public String load(){
  49.         FileInputStream in=null;
  50.         BufferedReader read=null;
  51.         StringBuilder content=new StringBuilder();
  52.         try{
  53.             in=openFileInput("data");
  54.             read=new BufferedReader(new InputStreamReader(in));
  55.             String line="";
  56.             while((line =read.readLine())!=null){
  57.                 content.append(line);
  58.             }
  59.         }catch (IOException e){
  60.             e.printStackTrace();
  61.         }
  62.         finally {
  63.             try {
  64.                 if(read!=null){
  65.                     read.close();
  66.                 }
  67.             } catch (IOException e){
  68.                 e.printStackTrace();
  69.             }
  70.         }
  71.     }
  72. }
复制代码
6.3 SharedPreferences存储

不同于文件的存储方式。这个是使用键值对的方式来存储数据的。保存一条数据的时候,需要给这条数据提供一个对应的键。这个存储方式支持多种不同的数据范例。如果存储的数据范例是整型,那么读取出来的数据也是整形。如果存储的数据是字符串,那么读取出来的数据也是一个字符串。
6.3.1 将数据存储到是SharedPreferences中

如果要想使用SharedPreferences,以是先要获取到SharedPreferences对象。安卓一共的三种方法用来得到是SharedPreferences对象。

  • Context类中的getSharedPreferences()方法。
    此方法吸收两个参数,第一个参数用于指定这个文件的名称,如果指定的文件不存在,则会创建一个新的,SharedPreferences文件都是存放在/data/data/<package name /<shared_prefs目录下。
    第二个参数用于指定使用模式,目前只有MODE_PRIVATE一种模式可选,它是默认的使用模式。和直接传入0的效果是相同的,只有当前的应用步伐才可以对这个SharedPreferences文件举行读写。其他几种使用模式均已被废弃。
  • Activity类中的getPreferences()方法。
    这个方法和第一个Context类中的getSharedPreferences()方法很相似,不过这个方法只接受一个参数。使用这个方法会自动将当前活动的类名作为SharedPreferences文件名。
  • PreferenceManager类的getDefaultSharedPreferences()方法
    是一个静态的方法,它接自动使用当前应用步伐的包名作为前缀来命名这个SharedPreferences文件。得到了这个SharedPreferences对象之后就开始向这个文件中存储数据了。紧张分为以下三个步骤实现:
    第一步,要用这个SharedPreferences对象的edit()方法来获取一个SharedPreferences.Editor对象。
    第二步,向这个SharedPreferences.Editor对象中添加数据,比如添加一个布尔型就用这个putBoolean()方法。添加一个字符串,则使用putString()方法,以此类推。
    第三步,用apply()方法将添加的数据提交,从而完成数据存储。
  1. public class MainActivity extends AppCompatActivity {
  2.     @Override
  3.     protected void onCreate(Bundle savedInstanceState) {
  4.         super.onCreate(savedInstanceState);
  5.         EdgeToEdge.enable(this);
  6.         setContentView(R.layout.activity_main);
  7.         ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
  8.             Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
  9.             v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
  10.             return insets;
  11.             
  12.             
  13.         });
  14.         Button saveData=(Button) findViewById(R.id.save_data);
  15.         saveData.setOnClickListener(new View.OnClickListener() {
  16.             @Override
  17.             public void onClick(View v) {
  18.                 SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
  19.                 editor.putString("name","Tom");
  20.                 editor.putBoolean("married",false);
  21.                 editor.putInt("age",28);
  22.                 editor.apply();
  23.             }
  24.         });
  25.     }
  26. }
复制代码
6.3.2 从SharedPreferences中读取数据

每一种get方法都对应了一种put的方法。
  1. public class MainActivity extends AppCompatActivity {
  2.     @Override
  3.     protected void onCreate(Bundle savedInstanceState) {
  4.         super.onCreate(savedInstanceState);
  5.         EdgeToEdge.enable(this);
  6.         setContentView(R.layout.activity_main);
  7.         ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
  8.             Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
  9.             v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
  10.             return insets;
  11.         });
  12.         Button saveData=(Button) findViewById(R.id.save_data);
  13.         saveData.setOnClickListener(new View.OnClickListener() {
  14.             @Override
  15.             public void onClick(View v) {
  16.                 SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
  17.                 editor.putString("name","Tom");
  18.                 editor.putBoolean("married",false);
  19.                 editor.putInt("age",28);
  20.                 editor.apply();
  21.             }
  22.         });
  23.         Button restoreData=(Button) findViewById(R.id.restore_data);
  24.         restoreData.setOnClickListener(new View.OnClickListener() {
  25.             @Override
  26.             public void onClick(View v) {
  27.                 SharedPreferences pref=getSharedPreferences("data",MODE_PRIVATE);
  28.                 String name=pref.getString("name","");
  29.                 int age=pref.getInt("age",0);
  30.                 boolean married=pref.getBoolean("married",false);
  31.                
  32.             }
  33.         });
  34.     }
  35. }
复制代码
6.3.3 实现记住暗码功能

activity_login.xmll
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     android:layout_width="match_parent"
  3.     android:layout_height="match_parent"
  4.     android:orientation="vertical">
  5.     <LinearLayout
  6.         android:orientation="horizontal"
  7.         android:layout_width="match_parent"
  8.         android:layout_height="60dp">
  9.         <TextView
  10.             android:layout_width="90dp"
  11.             android:layout_height="wrap_content"
  12.             android:layout_gravity="center_vertical"
  13.             android:textSize="18sp"
  14.             android:text="Account"/>
  15.         <EditText
  16.             android:id="@+id/account"
  17.             android:layout_width="0dp"
  18.             android:layout_height="wrap_content"
  19.             android:layout_weight="1"
  20.             android:layout_gravity="center_vertical"/>
  21.     </LinearLayout>
  22.     <LinearLayout
  23.         android:orientation="horizontal"
  24.         android:layout_width="match_parent"
  25.         android:layout_height="60dp">
  26.         <TextView
  27.             android:layout_width="90dp"
  28.             android:layout_height="wrap_content"
  29.             android:layout_gravity="center_vertical"
  30.             android:textSize="18sp"
  31.             android:text="Password:"/>
  32.         <EditText
  33.             android:id="@+id/password"
  34.             android:layout_width="0dp"
  35.             android:layout_height="wrap_content"
  36.             android:layout_weight="1"
  37.             android:layout_gravity="center_vertical"
  38.             android:inputType="textPassword"/>
  39.     </LinearLayout>
  40.     <LinearLayout
  41.         android:orientation="horizontal"
  42.         android:layout_width="match_parent"
  43.         android:layout_height="wrap_content">
  44.         <CheckBox
  45.             android:id="@+id/remember_pass"
  46.             android:layout_width="wrap_content"
  47.             android:layout_height="wrap_content"/>
  48.         <TextView
  49.             android:textSize="18sp"
  50.             android:text="Remeber password"
  51.             android:layout_width="wrap_content"
  52.             android:layout_height="wrap_content"/>
  53.     </LinearLayout>
  54.     <Button
  55.         android:id="@+id/login"
  56.         android:layout_width="match_parent"
  57.         android:layout_height="60dp"
  58.         android:text="Login"/>
  59. </LinearLayout>
复制代码
LoginActivity.java
  1. package com.example.broadcastbestpractice;
  2. import android.content.Context;
  3. import android.content.Intent;
  4. import android.content.SharedPreferences;
  5. import android.os.Bundle;
  6. import android.preference.PreferenceManager;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.CheckBox;
  10. import android.widget.EditText;
  11. import android.widget.Toast;
  12. import java.util.prefs.PreferenceChangeEvent;
  13. public class LoginActivity extends BaseActivity{
  14.     private EditText accountEdit;
  15.     private EditText passwordEdit;
  16.     private Button login;
  17.     private SharedPreferences pref;
  18.     private SharedPreferences.Editor editor;
  19.     private CheckBox rememberPass;
  20.     @Override
  21.     protected void onCreate(Bundle savedInstanceState) {
  22.         super.onCreate(savedInstanceState);
  23.         setContentView(R.layout.activity_login);
  24.         
  25.         pref = PreferenceManager.getDefaultSharedPreferences(this);
  26.         rememberPass=(CheckBox)findViewById(R.id.remember_pass);
  27.         boolean isRemeber=pref.getBoolean("remember_password",false);
  28.         if(isRemeber){
  29.             //将账号和密码都设置到文本框
  30.             String account=pref.getString("account","");
  31.             String password=pref.getString("password","");
  32.             accountEdit.setText(account);
  33.             passwordEdit.setText(password);
  34.             rememberPass.setChecked(true);
  35.         }
  36.         accountEdit=(EditText) findViewById(R.id.account);
  37.         passwordEdit=(EditText) findViewById(R.id.password);
  38.         login=(Button) findViewById(R.id.login);
  39.         login.setOnClickListener(new View.OnClickListener() {
  40.             @Override
  41.             public void onClick(View v) {
  42.                 String account=accountEdit.getText().toString();
  43.                 String password=passwordEdit.getText().toString();
  44.                 if(account.equals("admin")&&password.equals("123")){
  45.                     editor=pref.edit();
  46.                     //如果复选框被选中
  47.                     if(rememberPass.isChecked()){
  48.                         editor.putBoolean("remember_pass",false);
  49.                         editor.putString("account",account);
  50.                         editor.putString("password",password);
  51.                     }else{
  52.                         editor.clear();
  53.                     }
  54.                     editor.apply();
  55.                     Intent intent=new Intent(LoginActivity.this,MainActivity.class);
  56.                     startActivity(intent);
  57.                     finish();
  58.                 }else{
  59.                     Toast.makeText(LoginActivity.this,"account or password id invalid",Toast.LENGTH_SHORT).show();
  60.                 }
  61.             }
  62.         });
  63.     }
  64. }
复制代码
6.4 SQLite数据库存储

这是一款轻量级的关系型数据库,它的运算速率非常快,但资源很少,通常只需要几百kb的内存就足够了,因此特别得当在移动设备上使用。SQLite不但支持标准的SQL语,还依照数据库的acid事务。
6.4.1 创建数据库

安卓为了让我们可以或许更加方便的管理数据库,专门提供了一个SQLiteOpenHelper主类。借助这个类就可以非常简单的对数据库举行创建和升级。


  • SQLiteOpenHelper这一个抽象类,如果要使用这个类的话,就需要创建一个本身的资助类去继续它。
  • SQLiteOpenHelper有两个抽象方法。一个是onCreate(),一个是onupgrade()。需在本身的资助类内里重写这两个方法。分别在这两个方法中去实现创造和升级数据库的逻辑。
  • SQLiteOpenHelper另有两个非常紧张的实例方法。一个是getReadableDatabase(),另一个是getWritableDatabase()。两个方法都可以创建大概打开一个现有的数据库,如果数据库已经存在则打开,否则创建一个新的数据库。并返回一个可对数据库举行读写使用的对象。不同的是,当数据库不可写入的时候,比如磁盘空间已满。getReadableDatabase()方法返回的对象将以只读的方式去带数据。getWritableDatabase()方法则将出现异常。
  • 有两个构造方法可以重写,一般使用参数少一点的谁人构造方法即可。是构造函数方法中吸收四个参数,第一个参数是context,必须有这个才气对数据库举行使用。第二个参数是数据库名,创建数据库时使用的就是这里指定的名称。第三个参数答应我们在查询数据的时候返回一个自定义的Cursor游标,一般都是传入nulll。第四个参数,表示当前数据库的版本号,可用于对数据库举行升级使用。构建出的实例之后再调用它的getReadableDatabase()大概getWritableDatabase()方法就可以或许创建数据库。数据库的文件存放在/data/data/<package name/databases/目录下,此时重写的onCreate的方法也会执行。以是通常会在这里行止理一些创建表的逻辑。
  1. public class MainActivity extends AppCompatActivity {
  2.     private MyDatabaseHelper dbHelper;
  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         EdgeToEdge.enable(this);
  7.         setContentView(R.layout.activity_main);
  8.         ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
  9.             Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
  10.             v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
  11.             return insets;
  12.         });
  13.         
  14.         dbHelper=new MyDatabaseHelper(this,"BookStroe.db",null,1);
  15.         Button createDatabase=(Button) findViewById(R.id.creat_database);
  16.         createDatabase.setOnClickListener(new View.OnClickListener() {
  17.             @Override
  18.             public void onClick(View v) {
  19.                 dbHelper.getWritableDatabase();
  20.             }
  21.         });
  22.     }
  23. }
复制代码
  1. public class MyDatabaseHelper extends SQLiteOpenHelper {
  2.     public final String CREATE_BOOK ="create table book ("
  3.             + "id integer primary key autoincrement, "
  4.             + "author text,"
  5.             + "price real,"
  6.             +"pages integer,"
  7.             +"name text)" ;
  8.     private Context mContext;
  9.     public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){
  10.         super(context,name,factory,version);
  11.         mContext=context;
  12.     }
  13.     @Override
  14.     public void onCreate(SQLiteDatabase db) {
  15.         db.execSQL(CREATE_BOOK);
  16.     }
  17.     @Override
  18.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  19.     }
  20. }
复制代码
6.4.2 升级数据库

再加一个数据库表,记载图书的分类。
  1. public class MyDatabaseHelper extends SQLiteOpenHelper {
  2.     public final String CREATE_BOOK ="create table book ("
  3.             +"id integer primary key autoincrement, "
  4.             +"author text,"
  5.             +"price real,"
  6.             +"pages integer,"
  7.             +"name text)" ;
  8.     public final String CREATE_CATEGORY ="create table Category ("
  9.             +"id integer primary key autoincrement, "
  10.             +"category_name text,"
  11.             +"category_code integer)";
  12.     private Context mContext;
  13.     public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){
  14.         super(context,name,factory,version);
  15.         mContext=context;
  16.     }
  17.     @Override
  18.     public void onCreate(SQLiteDatabase db) {
  19.         db.execSQL(CREATE_BOOK);
  20.         db.execSQL(CREATE_CATEGORY);
  21.         Toast.makeText(mContext,"Create 成功",Toast.LENGTH_SHORT).show();
  22.     }
  23.     @Override
  24.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  25.     }
  26. }
复制代码
看上去挺对的,现在运行一下步伐,点击Create database按钮,没有弹出"Create 成功"的提示。
没有创建成功的缘故原由是因为之前的bookstore数据库已经存在了,不管怎样点Create database按钮,这个oncreate方法中都不会再次执行,因此新添加的表就无法得到。
解决方法有两种。一种是卸载步伐重新运行。另一种方法是在升级功能函数内里加下面几行代码。
  1.     @Override
  2.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  3.         db.execSQL("drop table if exists Book");
  4.         db.execSQL("drop table if exists Category");
  5.         onCreate(db);
  6.     }
复制代码
如何让这个onUpgrage的方法可以或许执行?SQLiteOpenHelper的构造方法吸收四个参数,最后一个参数是版本号,版本号默认传入是1,只要传入一个比1大的数就可以让onUpgrade的方法执行。
。。。
dbHelper=new MyDatabaseHelper(this,“BookStroe.db”,null,2);
Button createDatabase=(Button) findViewById(R.id.creat_database);
createDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
。。。
6.4.3 添加数据

  1. Button addData=(Button) findViewById(R.id.addData);
  2.         addData.setOnClickListener(new View.OnClickListener() {
  3.             @Override
  4.             public void onClick(View v) {
  5.                 SQLiteDatabase db=dbHelper.getWritableDatabase();
  6.                 ContentValues values=new ContentValues();
  7.                 values.put("name","The Da vinci Code");
  8.                 values.put("pages",454);
  9.                 db.insert("Book",null,values);
  10.                
  11.                 values.clear();
  12.                 values.put("name","the lost Symbol");
  13.                 values.put("pages",349);
  14.                 db.insert("Book",null,values);
  15.             }
  16.         });
复制代码
6.4.4 更新数据

找到书名为The Davinci Code的一组数据,将这本书的价格改为17.52
  1. Button updateData=(Button) findViewById(R.id.updateData);
  2.         addData.setOnClickListener(new View.OnClickListener() {
  3.             @Override
  4.             public void onClick(View v) {
  5.                 SQLiteDatabase db=dbHelper.getWritableDatabase();
  6.                 ContentValues values=new ContentValues();
  7.                 values.put("price",17.52);
  8.                 db.update("Book",values,"name=?",new String[]{"The Davinci Code"});
  9.             }
  10.         });
复制代码
6.4.5 删除数据

删除页数超过500页的书
  1. Button deleteData=(Button) findViewById(R.id.deleteData);
  2.         deleteData.setOnClickListener(new View.OnClickListener() {
  3.             @Override
  4.             public void onClick(View v) {
  5.                 SQLiteDatabase db=dbHelper.getWritableDatabase();
  6.                 ContentValues values=new ContentValues();
  7.                 db.delete("Book","pages>?",new String[]{"500"});
  8.             }
  9.         });
复制代码
6.4.6 查询数据

  1. Button queryData=(Button) findViewById(R.id.queryData);
  2.         queryData.setOnClickListener(new View.OnClickListener() {
  3.             @Override
  4.             public void onClick(View v) {
  5.                 SQLiteDatabase db=dbHelper.getWritableDatabase();
  6.                 Cursor cursor=db.query("Book",null,null,null,null,null,null);
  7.                 if(cursor.moveToFirst()){
  8.                     do{
  9.                         @SuppressLint("Range") String name=cursor.getString(cursor.getColumnIndex("name"));
  10.                         @SuppressLint("Range") int pages=cursor.getInt(cursor.getColumnIndex("pages"));
  11.                     }while(cursor.moveToNext());
  12.                 }
  13.                 cursor.close();
  14.             }
  15.         });
复制代码
6.4.7 使用SQL使用数据库

直接使用SQL来完成增删改查。
添加数据
db.execSQL(“insert into Book (name,author,pages,price) values(?,?,?,?)”,new String[]{“The Da Vinci Code”,"Dan ",“454”,“16.35”} );
查询数据
db.rawQuery(“select * from Book”,null);
6.5 使用LitePal使用数据库

6.5.1 LitePal简介

是一个开源的Android数据库框架。接纳了对象关系映射(ORM)的模式,并将我们平时开发最常用的一些数据库功能举行了封装。不消编写SQL就完成增删改查。
6.5.2 配置LitePal

怎样才气在项目中使用开源库?已往的方式比力复杂,下载开源库的jar包大概源码,然后再集成到项目中。现在简单多了,大多数的开源项目都会将版本提交到jcenter上,需要在app/build.gradle文件中声明该开源库的引用就可以了。
后续更新…
6.5.3 创建和升级数据库

6.5.4 增加

6.5.5 更新

6.5.6 删除

6.5.6 查询


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天津储鑫盛钢材现货供应商

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表