初学Android:数据存储技术小结

来源:互联网 发布:上海it helpdesk招聘 编辑:程序博客网 时间:2024/04/30 15:05

第三篇博客

学习Android的第一本书是郭霖大神的《第一行代码Android》第二版,根据自己对这本书的理解,在总结上会有一些对这本书内容上的借鉴。

  • 本着总结学习成果的方面去考虑,希望自己能够有所进步
  • 之后写的“书中”均指的是《第一行代码Android》第二版

目录

  • 第三篇博客
  • 目录
  • 数据存储
    • 文件存储
    • SharedPreferences存储
      • 存储数据至SharedPreferences中
      • 从SharedPreferences中读取数据
    • SQLite数据库存储
      • 创建数据库
      • 升级数据库
      • 增删改查
        • 添加数据
        • 更新数据
        • 删除数据
        • 查询数据
    • 使用LitePal操作数据库
      • 创建与升级数据库
      • 增删改查



数据存储

在Android中数据存储技术分为三种:文件存储、SharedPreferences存储、SQLite数据库存储。


文件存储

Android语法是Java,因此Android的文件存储与Java的文件存储类似。


SharedPreferences存储

不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的。也就是说,当保存一条数据的时候,需要给这条数据提供一个对应的键值,这样在存储数据的时候就可以通过这个键把相应的值取出。而且SharedPreferences还支持多种不同的数据类型存储,如果存储的数据类型是整形,那么读取出来的数据也是整形。

获取SHaredPreference类对象方法

  1. Context类中的getSharedPreference()方法
  2. Activity类中的getPreferences()方法
  3. PerferenceManager类中的getDefaultSharedPreference()方法

Context类中的getSharedPreference()方法接收两个参数,第一个参数用于指定SharedPreferences文件的名称,如果指定的文件不存在则会创建一个,SharedPreferences文件都是存放在/data/data/< package name>/shared_prefs/目录下。第二个参数用于指定操作模式,目前只有MODE_PRIVATE一种模式。

Activity类中的getPreferences()方法与Context中的getSharedPreferences()方法类似,只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为SharedPreferences的文件名。

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

存储数据至SharedPreferences中

得到SharedPreferences对象后,便可以开始向SharedPreferences文件中存储数据,分为三步。

  1. 调用SharedPreferences对象的edit()方法来获取一个SharedPreferences.Editor对象
  2. 向SharedPreferences.Editor对象中添加数据,由于是键值对的方式,例如:putBoolean()/putString()方法
  3. 调用apply()方法将添加的数据提交,从而完成数据存储操作。

书上代码例:

    SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();    editor.putString("name", "Tom");    editor.putInt("age", 28);    editor.putBoolean("married", false);    editor.apply();

从SharedPreferences中读取数据

SharedPreferences提供了一系列的get方法,对于存储的数据进行对去,每种get对应了SharedPreferences.Editor中的一种put方法,利用键值对的方式就可以读取数据。get方法中第一个参数是键值对,第二个参数是对应数据无法找到时返回的默认值(Default处理)。

书中示例代码:

    SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);    String name = pref.getString("name", "");    int age = pref.getInt("age", 0);    boolean married = pref.getBoolean("married", false);

SQLite数据库存储

Android内置了数据库,为SQLite,它是一款轻量级的关系型数据库。运算速度快、占用资源少(通常只需要几百KB的内存就足够了),因而适合在移动设备上使用。

创建数据库

Android专门提供了一个SQLiteOpenHelper帮助类。

SQLiteOpenHelper是一个抽象类,有两个抽象方法,分别是onCreate()和onUpgrade(),在实现类中重写这两个方法,分别在这两个方法中实现创建、升级数据库的逻辑。

SQLiteOpenHelper中海油两个非常重要的实例方法:getReadableDatabase()和getWritableDatabase(),这两个方法都可以创建或打开一个现有的数据库,并返回一个可对数据库进行读写操作的对象。不同的是,当数据库不可写入时(如磁盘空间已满),getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而getWritableDatabase()方法则将出现异常。

SQLiteOpenHelper中有两个构造方法可供重写,一般使用参数少一点的那个构造方法即可。这个构造方法中接收4个参数,第一个参数是Context,第二个参数是数据库名,创建数据库时使用的就是这里指定的名称。第三个参数允许我们在查询数据时返回一个自定义的Cursor,一般都是传入null。第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作。构建出SQLiteOpenHelper实例后,调用getReadableDatabase()或getWritableDatabase()方法就可以创建数据库。数据库文件会存放在/data/data/< package name>/databases/目录下。此时,重写的onCreate()方法也会得到执行,所以通常会在这里去处理一些创建表的逻辑。

创建表的代码(书中)如下:

public static final String CREATE_BOOK = "create table Book("    + "id integer primary key autoincrement, "    + "author text, "    + "price real, "    + "pages integer, "    + "name text)";

重写的onCreate()方法:

@Overridepublic void onCreate(SQLiteDatabase db) {    db.execSQL(CREATE_BOOK);    //....}

SQLiteDatabase的execSQL()方法去执行这条建表语句。

而在Activity中无非是利用抽象类重写后的类的构造器构造一个对象,在构造器中传入指定的参数:
书中示例代码如下:

dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);

之后可以利用adb工具查看是否生成了数据库文件。

升级数据库

升级数据库用到了是需要重写的onUpgrade()方法
书中代码示例如下:

@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    db.execSQL("drop table if exists Book");    db.execSQL("drop table if exists Category");    onCreate(db);}

如代码中所示
这里如需更新数据库,则需把原来的数据库中的存在的表删除,再调用onCreate()方法重写创建
若想要onUpgrade()方法得到调用,则在创建抽象类SQLiteOpenHelper重写后的类对象中传入的version参数更新便可升级。

增删改查

  • 添加(Create)—insert
  • 查询(Retrieve)—select
  • 更新(Update)—updata
  • 删除(Delete)—delete

添加数据

SQLiteDatabase类中提供了insert()方法,接收三个参数,第一个是表名,第二个用于在未指定添加数据的情况下给某些可为空的列表自动复制NULL(一般直接传入null),第三个是ContentValues对象,提供了一系列的put()方法重载,用于向ContentValues中添加数据,只需要将表中的每个列名以及相应的待添加数据传入即可。

书中示例代码:

    SQLiteDatabase db = dbHelper.getWritableDatabase();    ContentValues values = new ContentValues();    //组装数据    values.put("name", "The Da Vinci Code");    ...    db.insert("Book", null, values);//插入数据    values.clear();    //组装数据    values.put("name", "The Lost Symbol");    ...

id一栏不需要赋值,会自动随添加数据而增加。

更新数据

更新数据同样适用的是ContentValues对象,书中如理代码如下:

values.put("price", 10.99);db.update("Book", values, "name = ?", new String[] {"The Da Vinci Code"});

代码中可以看出,update()方法第一个参数指定表名,values为传入的ContentValues对象,第三第四个参数来指定具体更新哪几行(即限制条件)。

删除数据

与更新数据类似,需要限制条件书中示例代码如下:

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

查询数据

其中查询数据为数据库最为主要的部分。
查询数据使用的是query()方法:

query()方法参数 对应SQL部分 描述 table from table_name 指定查询的表名 columns select column1, column2 指定查询的列名 selection where column = value 指定where的约束条件 selectionArgs - 为where中的占位符提供具体的值 groupBy group by column 指定需要group by的列 having having column = value 对group by后的结果进一步约束 orderBy order by column1, column2 指定查询结果的排序方式

调用query()方法后会返回一个Cursor对象,查询到的所有数据都将从这个对象中取出。

书中代码示例

 Cursor cursor = db.query("Book", null, null, null, null, null, null); if(cursor.moveToFirst()) {     do{//遍历Cursor对象,取出数据         String name = cursor.getString(cursor.getColumnIndex("name"));         ...//逻辑操作     } while(cursor.moveToNext()); } cursor.close();

moveToFirst()方法将数据指正移动到第一行,进入循环获取处理数据。获取时利用键值对的方式获取。


同时支持数据库操作即利用.execSQL()方法加数据库语句进行操作。


使用LitePal操作数据库

相比于Android提供的方法,LitePal方法更为简便
但由于使用开源库,则需要在app/build.gradle文件中的dependencies闭包中添加一行代码

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

并且需创建litepal.xml文件并编辑,并且需要在AndroidManifest.xml中添加如下代码:

android:name="org.litepal.LitePalApplication"

对开源库的应用注册。

创建与升级数据库

LitePal采取的是对象映射(ORM)的模式,简单来说,我们所使用的编程语言是面向对象语言,而使用的数据库则是关系型数据库,那么面向对象语言和面向关系的数据库之间建立的一种映射关系,这就是对象关系映射。

即可以使用面向对象的思维操作数据库

书中直接建立的一个Book类,并将整个类在litepal.xml代码中添加的信息。

在Activity中添加如下创建数据库代码:

LitePal.getDatabase();

这条代码就可以创建一个数据库。

而在Android提供的数据库方法中,按照上面的方法去更新时则会将表中的数据删除,因而维护成本很高,而在LitePal开源库中只要将版本号加1即可,数据库会得到更新,并且数据不会丢失。

增删改查

添加数据

书中代码:

Book book = new Book();book.setName("The Da Vinci Code");...//设置数据book.save();//添加数据

如上所示,只需创建对象,设置好对象的数据,调用sava()方法即可。

更新数据

更新数据与Android提供的方法类似,需要对修改的数据进行限制。
代码:

Book book = new Book();...//设置需要更新的数据book.updateAll("name = ? and author", "The lost Symbol", "Dan Brown");

若想要将对象数据设置成Java中任何数据类型的默认值时,代码不能为.setPages(0),因为创建对象时,pages字段的值就为0,LitePal不会对这个列进行更新,对于想要设置默认值,LitePal提供了setToDefault()方法,然后传入相应的列名既可以。

例:

Book book = new Book();book.setToDefault("pages");book.updataAll();

这段代码将所有书的页数均更新为0,由于updataAll()方法没有指定约束条件。

删除数据

DataSupport.deleteAll(Book.class, "price < ?", "15");

同样的限制条件进行数据删除。

查询数据

代码例:

List<Book> books = DataSupport.findAll(Book.class);

以上代码可以直接获取数据库中的Book表中的数据。

若想要查询特定的数据,LitePal中提供了一下API:

  • select()—用于指定查询哪几列数据。
  • where()—方法用于指定查询数据的约束条件。
  • order()—方法用于指定结果的排序方法。
  • limit()—方法用于指定查询结果的数量
  • offset()—方法拥有指定查询结果的偏移量,即向后几位。

代码例:

 List<Book> books = DataSupport.select("name", "author", "pages")                               .where("pages > ?", "400")                               .order("pages")                               .limit(10)                               .offset(10)                               .find(Book.class);

使用方法连缀。

并且支持原生SQL查询

Cursor c = DataSupport.findBySQL("select * from Book where pages > ? and price < ?", "400", "20");
0 0