Android-持久化技术(一)

文件存储

文件存储是android中最基本的数据存储方式,不需要对存储的内容作任何的格式化处理,所有的数据会被原封不动的保存到文件当中,比较适合存储一些简单的文本文件或者是二进制文件。下面我们看一个简单的案例,分析存储和读取数据的具体实现。

将数据存储到文件中

先看代码:

        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String data = "Data to save";

                FileOutputStream out = null;

                BufferedWriter bufferedWriter = null;

                try {

                    out = openFileOutput("data", Context.MODE_PRIVATE);

                    bufferedWriter = new BufferedWriter(new OutputStreamWriter(out));


                    bufferedWriter.write(data);

                    Toast.makeText(MainActivity.this,"数据存储完成",0).show();

                }catch (Exception e){


                    e.printStackTrace();

                    Toast.makeText(MainActivity.this,"数据存储失败",0).show();

                }finally {

                    try {

                        if (bufferedWriter != null){

                            bufferedWriter.close();
                        }

                    }catch (Exception e){

                        e.printStackTrace();

                    }

                }

            }
        });

代码分析:
通过openFileOutput()方法得到一个FileOutputStream对象,并依此构建OutputStreamWriter对象。然后借助OutputStreamWriter构建出BufferedWriter对象,通过BufferedWriter对象将文本内容写入。

从文件中读取数据

代码如下:

        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                FileInputStream input = null;

                BufferedReader reader = null;

                StringBuilder content = new StringBuilder();

                try {

                    input = openFileInput("data");

                    reader = new BufferedReader(new InputStreamReader(input));

                    String line = "";

                    while ((line = reader.readLine()) != null){

                        content.append(line);

                    }

                }catch (Exception e){

                    e.printStackTrace();

                }finally {

                    try{

                        if (reader != null){

                            reader.close();

                        }

                    }catch (Exception e){

                    }
                }

                Toast.makeText(MainActivity.this, "文本内容" + content,0).show();
            }
        });

首先通过openFileInput("data")方法获取到一个FileInputStream对象,然后借助它构建出一个InputStreamReader对象。我们就可以用过BufferedReader来逐行读取文件中的内容。

SharedPreferences

不同于文件存储方式,SharedPreferences是利用键值对来存储数据的。我们只需要在存储数据的时候,给本条数据对应的一个键值,则在去数据的时候就可以根据这个键来把值取出。
SharedPreferences支持多种不同类型的数据存储。例如:字符串,布尔,整形等。

可存储类型
使用SharedPreferences存储数据

要想使用SharedPreferences来存储数据,首先需要得到SharedPreferences对象。Android主要提供了3中方式用于得到SharedPreferences对象:
1、Context类的getSharedPreferences()
2、Activity的getPreferences()
3、PreferenceManager.getDefaultSharedPreferences()

主要实现步骤
1、调用SharedPreferences的edit()方法来获取SharedPreferences.Editor对象
2、向Editor对象中添加数据。
3、调用Editor的apply()方法提交数据,完成数据存储。

        spSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();

                editor.putString("name","nameStr");

                editor.putInt("age", 20);

                editor.putBoolean("bool",false);

                editor.apply();
            }
        });
使用SharedPreferences读取数据

SharedPreferences的读取数据操作和其存储数据操作对应的,使用get方法把对应类型的数据读取出来相当的方便。android也为我们提供了读取多种类型数据的方法。

SharedPreferences读取数据

读取数据的实现要比存取数据的实现还要简单:

        spRead.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                SharedPreferences sp = getSharedPreferences("data",MODE_PRIVATE);

                String name = sp.getString("name","");

                Integer age = sp.getInt("age",0);

                Boolean bool = sp.getBoolean("bool",false);

                Log.d("MainActivity","name"+name+" age"+age+" bool"+bool);

            }
        });

SQLite数据库存储

SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用内存非常少,在移动端上使用也相当适合的。那么android中的SQLite是如何使用的呢?

android为我们专门提供了一个SQLiteOpenHelper抽象类,用来管理数据库,借助这个类就可以非常简单的对数据库进行创建和升级。
因为SQLiteOpenHelper是一个抽象类,我们需要创建一个自己的帮助类继承它。

SQLiteOpenHelper中有两个抽象方法:onCreate()和onUpgrade(),前者是实现数据库创建,后者是实现数据库升级的逻辑。
SQLiteOpenHelper还有两个非常重要的实例方法:getWritableDatabase()和getReadableDatabase(),两个方法都可以实现创建或者是打开一个现有数据库(如果数据库已经存在直接打开,如果数据库不存在的话先创建一个新的数据库),并返回一个可以对数据库进行读写的对象。

但是不同的是当数据库不可以写入的时候(例如:磁盘已满),getReadableDatabase()返回的数据库将以只读的方式打开数据库,而getWritableDatabase()方法则会出现异常。

创建数据库

我们下面尝试一个实例,来理解数据库的创建过程。

    public class MyDataBaseHelper extends SQLiteOpenHelper{

        //把建表语句定义成一个字符串常量
        public  static final String CREAT_BOOK = "create table Book("+
                "id integer primary key autoincrement, "+
                "auther text,"+"price real,"+"pages integer,"+
                "name text)";

        private Context mContext;

        public MyDataBaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){

            super(context,name,factory,version);

            mContext = context;

        }

        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {

            //execSQL()完成执行语句操作(建表)
            sqLiteDatabase.execSQL(CREAT_BOOK);

            Toast.makeText(MainActivity.this,"create successed",Toast.LENGTH_SHORT).show();

        }
        
        //升级数据库
        //onUpgrade()方法主要用于对数据库进行升级
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        }
    }

紧接着,我们在MainActivity类中声明一个按钮createTable和helper。

private Button createTable;
private MyDataBaseHelper helper;

并在MainActivity的onCreate()方法中初始化

    createTable = (Button)findViewById(R.id.button05);
    helper = new MyDataBaseHelper(this,"BookStore.db",null,1);

按钮点击

        createTable.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                helper.getWritableDatabase();
            }
        });

针对以上代码:onCreate()方法中构建MyDataBaseHelper对象,通过构造函数将数据库名指定为BookStore.db指定数据库版本号为1,我们在createTable按钮的点击事件中调用getWritableDatabase()方法,即按钮在第一次点击的时候会首先判断BookStore.db数据库属否存在,不存在会创建BookStore.db数据库并调用MyDataBaseHelper的onCreate()方法, 如此一来Book表就能创建成功了,当我们在此点击按钮的时候就不会再创建数据库了

升级数据库

假如有这样一种情况,现有的数据库不能满足我们的需求了,我们现在需要在原有数据库的基础上加一张表,在这里以Category表为例。
我们在MyDataBaseHelper类中声明:

public  static final String CREAT_CATEGORY = "create table Category("+
                "id integer primary key autoincrement, "+
                "category_name text,"+"category_code integer)";

与此同时修改其onCreate()方法中的内容为

        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            //execSQL()完成执行语句操作(建表)
            sqLiteDatabase.execSQL(CREAT_BOOK);
            sqLiteDatabase.execSQL(CREAT_CATEGORY);
            Toast.makeText(MainActivity.this,"create successed",Toast.LENGTH_SHORT).show();
        }

点击创建数据库的按钮,结果并没有创建成功,因为数据库已经存在了,onCreate()方法并未执行。那么怎么解决呢?其实啊,我们只需要利用MyDataBaseHelper的升级功能,调用onUpgrade()方法执行一些操作,就能轻松解决这个问题。

        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

            sqLiteDatabase.execSQL("drop table if exists Book");

            sqLiteDatabase.execSQL("drop table if exists Category");

            onCreate(sqLiteDatabase);
        }

但是怎样才能启动onUpgrade()方法的执行呢?我们只需要在获取MyDataBaseHelper对象的时候,设置数据库的版本比之前的版本号大就OK了。

helper = new MyDataBaseHelper(this,"BookStore.db",null,2);
以上工作完成我们就实现了数据库的升级。

增、删、改、查

其实研究数据库是为我们服务的。能够实现数据的增、删、改、查才是我们最终的目的。其实利用SQLIte数据库实现增删改查的功能也是相当的简单。

        //向SQLite数据库添加数据
        insert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                SQLiteDatabase db = helper.getWritableDatabase();

                ContentValues values = new ContentValues();

                values.put("name","liu gaojian");
                values.put("auther","gu hongjuan");
                values.put("pages",770);
                values.put("price",36.5);

                db.insert("Book",null,values);
                values.clear();

                values.put("name","zhao si");
                values.put("auther","liu neng");
                values.put("pages",520);
                values.put("price",1.5);

                db.insert("Book",null,values);

                Toast.makeText(MainActivity.this,"add data successed",Toast.LENGTH_SHORT).show();

            }
        });


        //更新数据
        update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                SQLiteDatabase db = helper.getWritableDatabase();

                ContentValues values = new ContentValues();

                values.put("price",66.6);

                db.update("Book",values,"name = ?",new String[]{"zhao si"});

                Toast.makeText(MainActivity.this,"update data successed",Toast.LENGTH_SHORT).show();

            }
        });



        //删除数据
        delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                SQLiteDatabase db = helper.getWritableDatabase();

                db.delete("Book","pages > ?",new String[]{"600"});

                Toast.makeText(MainActivity.this,"delete data successed",Toast.LENGTH_SHORT).show();

            }
        });



        //查询数据
        select.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                SQLiteDatabase db = helper.getWritableDatabase();

                //查询db中的所有数据
                Cursor cursor = db.query("Book",null,null,null,null,null,null);

                if (cursor.moveToFirst()){

                    do {

                        //遍历cursor对象,取出数据并打印
                        String name = cursor.getString(cursor.getColumnIndex("name"));

                        String auther = cursor.getString(cursor.getColumnIndex("auther"));

                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));

                        double price = cursor.getDouble(cursor.getColumnIndex("pages"));

                        Toast.makeText(MainActivity.this, "name:"+name+"auther: "+auther+"pages:"+pages+"price:"+price, Toast.LENGTH_SHORT).show();


                    }while (cursor.moveToNext());

                }
                cursor.close();
            }
        });

针对以上代码不做过多的解释,只提一点就是我们在进行查询操作的时候会用到query()方法,它有很多个参数,那么每个参数代表什么意义呢?

query方法的参数解释
直接使用SQL操作数据库

一些牛逼的人都是直接通过SQL操作数据库。下面我们举个简单的例子来看一下直接利用SQL是如何操作数据库的。

        select.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                SQLiteDatabase db = helper.getWritableDatabase();

                //添加数据
                db.execSQL("insert into Book (name, auther, pages, price) values(?, ?, ?, ?)", new String[]{"C语言","王二麻子", "334", "48.5"});
                db.execSQL("insert into Book (name, auther, pages, price) values(?, ?, ?, ?)", new String[]{"数据结构","习近平", "256", "49.9"});


                //更新数据
                db.execSQL("update Book set price = ? where name = ? ", new String[]{"5.49", "C语言"});


                //删除数据
                db.execSQL("delete from Book where pages > ?", new String[]{"500"});

                //查询数据
                db.rawQuery("select * from Book",null);

            }
        });

你可能感兴趣的:(Android-持久化技术(一))