【android_温故知新】android 数据存储

来源:互联网 发布:注册淘宝卖家要钱吗 编辑:程序博客网 时间:2024/05/23 20:59

  • 使用 SharedPreferences
    • SharedPreferences 与 Editor 简介
    • SharedPreferences 的存储位置和格式
      • 实例记录应用程序的使用次数
    • 读写其他应用 SharedPreferences
  • SQLite 数据库
    • SQLiteDatabase 简介
    • 创建数据库和表
    • 使用特定方法操作 SQLite 数据库
      • 使用 insert 方法插入记录
      • 使用 update 方法更新记录
    • 使用 delete 方法删除记录
    • 使用 query 方法查询记录
    • 事务
    • SQLiteOpenHelper 类

使用 SharedPreferences

此处输入图片的描述

SharedPreferences 与 Editor 简介

SharedPreferences 接口主要负责读取应用程序的 Preferences 数据,它提供了如下常用方法来访问 SharedPreferences 中得 key-values 对。

  1. boolean contains(String key):判断 SharedPreferences 是否包含特定的 key 的数据。
  2. abstract Map< String,? > getAll():获取 SharedPreferences 数据里全部的 key-value 对。
  3. boolean getXxx(String key,xxx defValue):获取 SharedPreferences 数据里指定 key 对应的 value。如果该 key 不存在,返回默认值 defValue。其中 xxx 可以使 boolean、float、int、long、String 等各种基本类型的值。

SharedPreferences 接口本身并没有提供写入数据的能力,而是通过 SharedPreferences 的内部接口,SharedPreferences 调用 edit()方法即可获取它所对应的 Editor 对象。Editor 提供了如下方法来向 SharedPreferences 写入数据。

  1. SharedPreferences.Editor clear():清空 SharedPreferences 里所有数据。
  2. SharedPreferences.Editor putXxx(String key,xxx value):向 SharedPreferences 存入指定 key 对应的数据。其中 xxx 可以是 boolean、float、int、long、String 等各种基本类型的值。
  3. SharedPreferences.Editor remove(String key):删除 SharedPreferences 里指定 key 对应的数据项。
  4. boolean commit():当 Editor 编辑完成后,调用该方法提交修改。

SharedPreferences 本身是一个接口,程序无法直接创建 SharedPreferences 实例,只能通过 Context 提供的 getSharedPreferences(String name, int mode)方法来获取 SharedPreferences 实例,该方法的第二个参数支持如下几个值。

  1. Context.MODE_PRIVATE:指定该 SharedPreferences 数据只能被本应用程序独、写。
  2. Context.MODE_WORLD_READABLE:指定该 SharedPreferences 数据能被其他应用程序读、但不能写。
  3. Context.MODE_WORLD_WRITABLE:指定该 SharedPreferences 数据能被其他应用程序读、写。

SharedPreferences 的存储位置和格式

public class MainActivity extends Activity {    SharedPreferences preferences;    SharedPreferences.Editor editor;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        // 获取只能被本应用程序读、写的SharedPreferences对象        preferences = getSharedPreferences("yonga", MODE_PRIVATE);        editor = preferences.edit();        Button read = (Button) findViewById(R.id.read);        Button write = (Button) findViewById(R.id.write);        read.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                // 读取字符串数据                String time = preferences.getString("time", null);                // 读取int类型的数据                int randNum = preferences.getInt("random", 0);                String result = time == null ? "您暂时还未写入数据" : "写入时间为:"                        + time + "\n上次生成的随机数为:" + randNum;                // 使用Toast提示信息                Toast.makeText(MainActivity.this, result                        , Toast.LENGTH_SHORT).show();            }        });        write.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 "                        + "hh:mm:ss");                // 存入当前时间                editor.putString("time", sdf.format(new Date()));                // 存入一个随机数                editor.putInt("random", (int) (Math.random() * 100));                // 提交所有存入的数据                editor.commit();            }        });    }}

此处输入图片的描述

实例:记录应用程序的使用次数

public class MainActivity extends Activity {    SharedPreferences preferences;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        preferences = getSharedPreferences("count"                , MODE_PRIVATE);        // 读取SharedPreferences里的count数据        int count = preferences.getInt("count", 0);        // 显示程序以前使用的次数        Toast.makeText(this, "程序以前被使用了" + count + "次。"                , Toast.LENGTH_LONG).show();        SharedPreferences.Editor editor = preferences.edit();        // 存入数据        editor.putInt("count", ++count);        // 提交修改        editor.commit();    }}

读、写其他应用 SharedPreferences

要读、写其他应用的 SharedPreferences,前提是创建该 SharedPreferences 的应用程序指定相应的访问权限,例如指定了 MODE_WORLD_READABLE,这表明该 SharedPreferences 可被其他应用程序读取;指定了 MODE_WORLD_WRITABLE,这表明该 SharedPreferences 可被其他程序写入。

为了读取其他程序的 SharedPreferences,可按如下步骤进行。
1. 需要创建其他程序对应的 Context
useCount = createPackageContext("org.yonga.io", Context.CONTEXT_IGNORE_SECURITY);
2. 调用其他应用程序的 Context 的 getSharedPreferences(String name, int mode)即可获取相应的 SharedPreferences 对象。
3. 如果需要向其他应用的 SharedPreferences 数据写入数据,调用 SharedPreferences 的 edit()方法获取相应的 Editor 即可。

此处输入图片的描述

SQLite 数据库

SQLiteDatabase 简介

android 提供了 SQLiteDatabase 代表一个数据库(底层就是一个数据库文件),一旦应用程序获得了代表指定数据库的 SQLiteDatabase 对象,接下来就可通过 SQLiteDatabase 对象来管理、操作数据库了。

SQLiteDatabase 提供了如下静态方法来打开一个文件对应的数据库。

  1. static SQLiteDatabase openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags):打开 path 文件所代表的 SQLite 数据库。
  2. static SQLiteDatabase openOrCreateDatabase(File file,SQLiteDatabase.CursorFactory factory):打开或创建(如果不存在)file 文件所代表的 SQLite 数据库。
  3. static SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory):打开或创建(如果不存在)path 文件所代表的 SQLite 数据库。

在程序中获取 SQLiteDatabase 对象之后,接下来就可调用 SQLiteDatabase 的如下方法来操作数据库了。
1. execSQL(String sql,Object[] bindArgs):执行带占位符的 SQL 语句。
2. execSQL(String sql):执行 SQL 语句。
3. insert(String table,String nullColumnHack,ContentValues values):向执行表中插入数据。
4. update(String table,ContentValues values,String whereClause,String[] whereArgs):更新指定表中的特定数据。
5. delete(String table,String whereClause,String[] whereArgs):删除指定表中的特定数据。
6. Cursor query(String table,String[] columns,String whereClause,String[]whereArgs,String groupBy,String having,String orderBy):对执行数据表执行查询。
7. Cursor query(String table,String[] columns,String whereClause,String[]whereArgs,String groupBy,String having,String orderBy,String limit):对执行数据表执行查询。limit 参数控制最多查询几条记录(用于控制分页参数)。
8. Cursor query(boolean distinct,String table,String[] columns,String whereClause,String[]whereArgs,String groupBy,String having,String orderBy,String limit):对指定表执行查询语句。其中第一个参数控制是否去除重复值。
9. rawQuery(String sql,String[] selectionArgs):执行带占位符的 SQL 查询。
10. beginTransaction():开始事务。
11. endTransaction():结束事务。

此处输入图片的描述

  1. move(int offset):将记录指针向上或向下移动指定的行数。offset 为正数就是向下移动;为负数就是向上移动。
  2. boolean moveToFirst():将记录指针移动到第一行,如果移动成功则返回 true。
  3. boolean moveToLast():将记录指针移动到最后一行,如果移动成功则返回 true。
  4. boolean moveToNext():将记录指针移动到下一行,如果移动成功则返回 true。
  5. boolean moveToPosition(int position):将记录指针移动到指定的行,如果移动成功则返回 true。
  6. boolean moveToPrevious():将记录指针移动到第一行,如果移动成功则返回 true。

创建数据库和表

使用 SQLiteDatabase 的静态方法即可打开或创建数据库,例如如下代码:

SQLiteDatabase.openOrCreateDatabase("/mnt/db/temp.db3",null);

上面的代码就用于打开或创建一个 SQLite 数据库,如果/mnt/db/目录下的 temp.db3 文件(该文件就是一个数据库)存在,那么程序就是打开该数据库;如果该文件不存在,则上面的代码将会在该目录下创建 temp.db3 文件(即对应于数据库)。

此处输入图片的描述

    // 定义建表语句    sql = “create table user_inf (”        + “user_id integer primary key ,”        + "user_name text ,"        + "user_pass varchar(255) )";    // 执行 SQL 语句    db.execSQL(sql);

使用特定方法操作 SQLite 数据库

使用 insert 方法插入记录

SQLiteDatabase 的 insert 方法的签名为 long insert(String table,String nullColumnHack, ContentValues values),这个插入方法的参数说明如下。
1. table:代表想插入数据的表名。
2. nullColumnHack:代表强行插入 null 值的数据列的列名。当 values 参数为 null 或不包含任何 key-value 对时该参数有效。
3. values:代表一行记录的数据。

insert 方法插入的一行记录使用 ContentValues 存放,ContentValues 类似 Map,它提供了 put(String key,Xxx value)(其中 key 为数据列的列名)方法用于存入数据、getAsXxx(String key)方法用于取出数据。

ContentValues values = new contentValues();values.put("name","孙悟空");values.put("age",500);// 返回新添记录的行号,该行号是一个内部值,与主键 id 无关,发生错误返回-1long rowid = db.insert("person_inf",null,values);

不管第三个参数是否包含数据,执行 insert()方法总会添加一条记录,如果第三个参数为空,会添加一条除主键之外其他字段值都为 null 的记录。

第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值 null,一般我们用不到这 个功能,直接传入 null 即可。

使用 update 方法更新记录

SQLiteDatabase 的 update 方法的签名为 update(String table, ContentValues values,String whereClause,String[] whereArgs),这个更新方法的参数说明如下。

  1. table:代表想更新数据的表名。
  2. values:代表想更新的数据。
  3. whereClause:满足该 whereClause 子句的记录将会被更新。
  4. whereArgs:用于为 whereClause 子句传入参数。

该方法返回受此 update 语句影响的记录的条数。

例如我们想更新 person_inf 表中所有主键大于 20 的人的人名,可调用如下方法:

ContentValues values = new ContentValues();// 存放更新后的人名values.put("name","新人名");int result = db.update("person_inf",values,"_id>?",new Integer[]{20});

使用 delete 方法删除记录

SQLiteDatabase 的delete 方法的签名为 delete(String table,String whereClause,String[]whereArgs),这个删除的参数说明如下。

  1. table:代表想删除数据的表名。
  2. whereClause:满足该 whereClause 子句的记录将会被删除。
  3. whereArgs:用于为 whereClause 子句传入参数。

该方法返回受此 delete 语句影响的记录的条数。

使用 query 方法查询记录

SQLiteDatabase 的 query 方法的签名为 Cursor query(boolean distinct,String table,String[] columns,String whereClause,String[] selectionArgs,String groupBy,String having,String orderBy,String limit),这个 query 方法的参数说明如下。
1. distinct:指定是否去除重复记录。
2. table:执行查询数据的表名。
3. columns:要查询出来的列名。
4. whereClause:查询条件字句。在条件字句中允许使用占位符“?”
5. whereArgs:用于 whereClause 子句中占位符传入参数值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
6. groupBy:用于控制分组。
7. having:用于对分组进行过滤。
8. orderBy:用于对记录进行排序。
9. limit:用于进行分页。

例如想查询出 person_inf 表中人名以“孙”开头的记录,可使用如下语句:

Cursor cursor = db.query("person_inf",new String[]{"_id,name,age"},"name like ?",new String[]{"孙%"},null,null,"personid desc","5,10");// 处理结果集cursor.close();

事务

SQLiteDatabase 中包含如下两个方法来控制事务。
1. beginTransaction():开始事务。
2. endTransaction():结束事务。

除此之外,SQLiteDatabase 还提供了如下方法来判断当前上下文是否处于事务环境中。
inTransaction():如果当前上下文处于事务中,则返回 true;否则返回 false。
此处输入图片的描述

示例代码如下:

db.beginTransaction();try{    // 执行 DML 语句    ...    // 调用该方法设置事务成功;否则 endTransaction()方法将回滚事务    db.setTransactionSucceessful();}finally{    // 由事务的标志决定是提交事务还是回滚事务    db.endTransaction();}

SQLiteOpenHelper 类

此处输入图片的描述

SQLiteOpenHelper 包含如下常用的方法。
1. synchronized SQLiteDatabase getReadableDatabase():以读写的方式打开数据库对应的 SQLiteDatabase 对象。
2. synchronized SQLiteDatabase getWritableDatabase():以写的方式打开数据库对应的 SQLiteDatabase 对象。
3. abstract void onCreate(SQLiteDatabase db):当第一次创建数据库时回调该方法。
4. abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion):当数据库版本更新时回调该方法。
5. synchronized void close():关闭所有打开的 SQLiteDatabase 对象。

此处输入图片的描述
此处输入图片的描述

getReadableDatabase()和 getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。不同的是,当数据库不可写入的时候(如磁盘空间已满)getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而 getWritableDatabase()方法则将出现异常。

程序清单:Dict.java

public class MainActivity extends Activity {    MyDatabaseHelper dbHelper;    Button insert = null;    Button search = null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        // 创建MyDatabaseHelper对象,指定数据库版本为1,此处使用相对路径即可        // 数据库文件自动会保存在程序的数据文件夹的databases目录下        dbHelper = new MyDatabaseHelper(this, "myDict.db3", 1);        insert = (Button) findViewById(R.id.insert);        search = (Button) findViewById(R.id.search);        insert.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View source) {                // 获取用户输入                String word = ((EditText) findViewById(R.id.word))                        .getText().toString();                String detail = ((EditText) findViewById(R.id.detail))                        .getText().toString();                // 插入生词记录                insertData(dbHelper.getReadableDatabase(), word, detail);                // 显示提示信息                Toast.makeText(MainActivity.this, "添加生词成功!"                        , Toast.LENGTH_LONG).show();            }        });        search.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View source) {                // 获取用户输入                String key = ((EditText) findViewById(R.id.key)).getText()                        .toString();                // 执行查询                Cursor cursor = dbHelper.getReadableDatabase().rawQuery(                        "select * from dict where word like ? or detail like ?",                        new String[]{"%" + key + "%", "%" + key + "%"});                // 创建一个Bundle对象                Bundle data = new Bundle();                data.putSerializable("data", converCursorToList(cursor));                // 创建一个Intent                Intent intent = new Intent(MainActivity.this                        , ResultActivity.class);                intent.putExtras(data);                // 启动Activity                startActivity(intent);            }        });    }    protected ArrayList<Map<String, String>>    converCursorToList(Cursor cursor) {        ArrayList<Map<String, String>> result =                new ArrayList<Map<String, String>>();        // 遍历Cursor结果集        while (cursor.moveToNext()) {            // 将结果集中的数据存入ArrayList中            Map<String, String> map = new HashMap<>();            // 取出查询记录中第2列、第3列的值            map.put("word", cursor.getString(1));            map.put("detail", cursor.getString(2));            result.add(map);        }        return result;    }    private void insertData(SQLiteDatabase db, String word            , String detail) {        // 执行插入语句        db.execSQL("insert into dict values(null , ? , ?)"                , new String[]{word, detail});    }    @Override    public void onDestroy() {        super.onDestroy();        // 退出程序时关闭MyDatabaseHelper里的SQLiteDatabase        if (dbHelper != null) {            dbHelper.close();        }    }}
0 0
原创粉丝点击