精华内容
下载资源
问答
  • Android系统中主要提供了三种方式用于简单的实现数据持久化功能: 文件存储(手机自带的内存)、SharedPreferences存储以及数据库存储, 当然还可以用sd卡存储 1,文件存储 特点:手机自带的内存,只能供当前...

    Android系统中主要提供了三种方式用于简单的实现数据持久化功能:

    文件存储(手机自带的内存)SharedPreferences存储以及数据库存储, 当然还可以用sd卡存储

    1,文件存储

    特点:手机自带的内存,只能供当前应用程序访问,其他应用程序访问不了,程序卸载这些数据也会随着消失

    原理:
    基本是先获取一个文件的输出流,然后把信息write进去,最后关闭流
    a,通过上下文类context的openFileOutput()方法获得一个FileOutputStream输出流
    b,要写入的内容通过write()写到FileOutputStream对象
    c,关闭流
    openFileOutput()可以将数据存储到指定的文件中,方法有两个参数,第一个参数是文件名,不需要带上完整的路径,因为这里都是默认存储到data/data/file下面的

    第二个参数是文件的操作模式,两种:MODE_PRIVATE和MODE_APPEND.前者是覆盖,后者是追加
    (MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE,前者是允许只读,后者是只写,但是都被抛弃,因为不安全)
    [java] view plain copy
    1. private void save(String inputText ) {  
    2.            FileOutputStream fos = null;  
    3.            BufferedWriter writer = null;  
    4.             try {  
    5.                fos = openFileOutput( "data", Context.MODE_PRIVATE);  
    6.                writer = new BufferedWriter( new OutputStreamWriter(fos));  
    7.                 writer.write( inputText);  
    8.            } catch (IOException e) {  
    9.                  // TODO Auto-generated catch block  
    10.                  e.printStackTrace();  
    11.            } finally {  
    12.                  try {  
    13.                       if( writer != null)  
    14.                             writer.close();  
    15.                 }catch (IOException e) {  
    16.                       // TODO Auto-generated catch block  
    17.                       e.printStackTrace();  
    18.                 }  

    主要的就是上面的三句话
    openFileOutput打开一个输出流,然后构建一个字节缓冲流对象然后写数据,

    此外还有几个方法需要特别注意一下 ,这几个方法对于文件关系提供了更好的支持,配合上面介绍的方式, 就可以对文件的数据进行常规的CRUD操作 (增删改查),方法如下:
    File getFIlesDir ():获取文件系统的绝对路径。
    boolean deleteFile(String name):删除一个指定文件名为name的文件。
    String[] fileList() :当前应用内部存储路径下的所有文件名。

    [java] view plain copy
    1.  //帮助我们返回一个目录  
    2.   //context.getCacheDir ()的话就是保存到cache缓存文件夹下面       
    3. File file=new File(context.getFilesDir(), "userinfo.txt");             
    4.        FileOutputStream fos= new FileOutputStream( file);            
    5.             //zhangsan 123  
    6.             fos.write(( username+ "##"+ password).getBytes());  
    7.             fos.close();  



    2、sharedpreference 存储(一般用于保存用户设置偏好);

    特点如下:

    @1以键值对的形式保存到data/data/应用程序包名/shared_prefs目录的XXX.xml文件中

    @2目前支持的数据类型有String int float boolean long

    @3不支持自定义的Object

    @4通常用来存储App上的用户配置信息.如:是否震动,是否打开背景音乐 小游戏积分 用户账号密码信息

    @5 在一些需要缓存的页面数据的情况在,比如一个首页的列表数据,在不需要对列表数据进行增删改的情况下(一般app的页面数据缓存仅需要查询功能),可以取巧使用sp来保存json数据,再利用fastjson,gson等格式化工具来恢复数据。


    要使用该方法来存储数据就要先获得一个SharedPreferences对象,有三种获取方法
    a,Context上下文类中的getSharedPreferences
    两个参数,第一个是指定文件的名称,不在就创建。目录也是在data/data/包名/shared_prefs目录下
    第二个参数是操作模式。MODE_PRIVATE是默认的,只允许当前的应用程序对其进行操作,MODE_MULTI_PROCESS是一般用于有多个进程中对同一个SharedPreferences文件进行读写的情况,同样有MODE_WORLD_WRITEABLE MODE_WORLD_READABLE两个被废弃的模式
    b,Activity类中的getPreferences
    只有一个参数,也是操作模式,文件的名称是默认的当前活动的类名
    c,PreferenceManager管理类中的getDefaultSharedPreferences()
    管理类中的一个静态方法,接收一个context参数,自动把当前的包名作为文件命名的前缀

    得到一个对象之后,有三步来进行数据的存储
    1,调用对象的edit方法获得一个SharedPreferences.Editor对象
    2,向.Editor对象添加数据,putBoolean()或者是putString(),,等等putXXX()方法
    3,调用commit方法将添加的数据提交,完成数据的存储操作

    例子:
    [java] view plain copy
    1. @Override  
    2. public void onClick(View v) {  
    3.       // TODO Auto-generated method stub  
    4.  SharedPreferences.Editor editor=getSharedPreferences( "data", MODE_PRIVATE).edit();  
    5.              editor.putString( "name""HuaAn");  
    6.              editor.putInt( "id"9527);  
    7.              editor.putBoolean( "婚否"false );  
    8.              editor.commit();          
    9.            }  
    10.      });  

    最后的结果是以xml的方式存在内存中的


    从SharedPreferences中读取数据 SharedPreferences提供了许多的get方法来进行获取数据,都和相应的put方法对应
    get方法也是有两个参数,第一个“键”,第二个是键找不到值时候的默认值,自己设定把
    还是继续取出上面存储的xml数据文件的数据 
    [java] view plain copy
    1. restore_button .setOnClickListener(new OnClickListener() {             
    2.             @Override  
    3.             public void onClick(View v) {  
    4.                  // TODO Auto-generated method stub  
    5.    SharedPreferences  pref=getSharedPreferences( "data", MODE_PRIVATE);  
    6.              
    7.            String name= pref.getString( "name""HuaAn");  
    8.             int id= pref.getInt( "id"9527);  
    9.             boolean married= pref.getBoolean( "婚否"false ); 
    10.            }  
    11.      });  
    12.      }  


    3 ,SQLite数据库存储

    为方便管理数据库有一个专门的抽象类SQLiteOpenHelper,它有两个抽象的方法onCreate()和onUpdate()
    此外还有两个实例方法,getReadableDatabase()和getWritableDatabase(),都可以创建或者是打开一个现有的数据库(存在就打开,不在就创建),返回一个可对数据库进行操作的对象
    当数据库不可写入的时候,前者返回的是一个只能读的方式打开数据库,后者则会出现异常

    数据库文件同样还是会放在data/data/包名/databases下面

    实现步骤如下:

    1,构建SQLiteOpenHelper的实例,也就是完成其构造函数(参数一是context,第二个是要创建的数据库的名字,第三个是cursor,一般是null,第四个是数据库的版本号)
    2,再调用getReadableDatabase()或者getWritableDatabase()方法创建数据库
    同时重写onCreate()方法,该方法也会得到执行
    例子:

    [java] view plain copy
    1. public class MyDatabaseHelper extends SQLiteOpenHelper {  
    2. /* 
    3. 补充一下建表的一些类型 
    4. integer ---整型 
    5. real-----浮点类型 
    6. text---文本类型 
    7. blob---二进制类型 
    8.  
    9. */  
    10. public static final String CREATE_BOOK= "create table book(id integer primary key autoincrement,"  
    11.            + "author text"  
    12.            + "price real"  
    13.            + "pages integer"  
    14.            + "name text)";   
    15.      private Context mContext ;  
    16.   
    17.      public MyDatabaseHelper(Context context, String name,  
    18.                 CursorFactory factory, int version) {  
    19.             super( context, name, factory, version);  
    20.             // TODO Auto-generated constructor stub  
    21.             mContext= context;  
    22.      }  
    23.   
    24.      @Override  
    25.      public void onCreate(SQLiteDatabase db) {  
    26.             // TODO Auto-generated method stub  
    27. //执行建表语句  
    28.     db.execSQL(CREATE_BOOK);  
    29.     Toast.makeText(mContext , "数据库创建成功" , Toast.LENGTH_SHORT).show();  
    30.      }  
    31.   
    32.      @Override  
    33.      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
    34.             // TODO Auto-generated method stub  
    35.      }  
    36. }  

    1. dbHelper= new MyDatabaseHelper( this"BookStore.db"null1);  
    2.      Button createDatabase=(Button) findViewById(R.id.create_database );  
    3.      createDatabase.setOnClickListener( new OnClickListener() {  
    4.              
    5.             @Override  
    6.             public void onClick(View v) {  
    7.                  // TODO Auto-generated method stub  
    8.                  dbHelper. getWritableDatabase();  
    9.            }  
    10.      });  

    public long insert (String table, String nullColumnHack, ContentValues values)

    Added in API level 1

    Convenience method for inserting a row into the database.

    Parameters
    table the table to insert the row into
    nullColumnHack optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided values is empty, no column names are known and an empty row can't be inserted. If not set to null, thenullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your values is empty.
    values this map contains the initial column values for the row. The keys should be the column names and the values the column values
    Returns
    • the row ID of the newly inserted row, or -1 if an error occurred
    [java] view plain copy
    1. Button addData =(Button) findViewById(R.id. add_data);  
    2.       addData.setOnClickListener( new OnClickListener() {           
    3.             @Override  
    4.             public void onClick(View v) {  
    5.                  // TODO Auto-generated method stub  
    6.                 SQLiteDatabase dbOperate= dbHelper.getWritableDatabase();  
    7.                 ContentValues values= new ContentValues();  
    8.             //下面没有给表中的id赋值,因为在建表的时候,id是默认自动增长的  
    9.                  //添加第一条记录到Book  
    10.                  values.put( "name""安卓入门之路" );  
    11.                  values.put( "author""hl174");  
    12.                  values.put( "pages"800);  
    13.                  values.put( "price"50);                 
    14.                  dbOperate.insert( "book"null, values);  
    15.                   
    16.                  values.clear();  
    17.                   
    18.                  //插入第二条记录到book  
    19.                  values.put( "name""安卓精通" );  
    20.                  values.put( "author""hl174");  
    21.                  values.put( "pages"700);  
    22.                  values.put( "price"45);       
    23.               dbOperate.insert( "book"null, values);  
    24.            }  
    25.      });  

    更新数据:
    update():四个参数

    public int update (String table, ContentValues values, String whereClause, String[]whereArgs)

    Added in API level 1

    Convenience method for updating rows in the database.

    Parameters
    table the table to update in
    values a map from column names to new column values. null is a valid value that will be translated to NULL.
    whereClause the optional WHERE clause to apply when updating. Passing null will update all rows.
    whereArgs You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings.
    Retu rns
    • the number of rows affected
    第一个参数:表名  第二个参数:ContentValues对象,
    最后两个参数是用来约束更新某一行或几行中的数据,不指定的话就是更新所有行
    [java] view plain copy
    1. //更新数据  
    2.      Button updateData=(Button) findViewById(R.id. update_data);  
    3.       updateData.setOnClickListener( new OnClickListener() {  
    4.             @Override  
    5.             public void onClick(View v) {  
    6.                  // TODO Auto-generated method stub  
    7.                 SQLiteDatabase db= dbHelper.getWritableDatabase();  
    8.                 ContentValues values= new ContentValues();  
    9.                  values.put( "price"10000);  
    10.                   
    11.         db.update( "book", values, "name=?"new String[]{"安卓入门之路" });  
    12.            }  
    13.      });  
    上面第三个参数对应的是类似sql中的where语句,?是一个占位符,第四个参数的内容可以替换掉该占位符



    删除数据
    很明显,删除数据就是delete()方法了

    public int delete (String table, String whereClause, String[] whereArgs)

    Added in API level 1

    Convenience method for deleting rows in the database.

    Parameters
    table the table to delete from
    whereClause the optional WHERE clause to apply when deleting. Passing null will delete all rows.
    whereArgs You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings.
    Returns
    • the number of rows affected if a whereClause is passed in, 0 otherwise. To remove all rows and get a count pass "1" as the whereClause.
    三个参数:第一个是表名
    第二个第三个同样是进行约束的条件行
    [java] view plain copy
    1. //删除数据  
    2.      Button deleteData=(Button) findViewById(R.id. delete_data);  
    3.       deleteData.setOnClickListener( new OnClickListener() {        
    4.             @Override  
    5.             public void onClick(View v) {  
    6.                  // TODO Auto-generated method stub  
    7.                 SQLiteDatabase db= dbHelper.getWritableDatabase();  
    8.                  //删除页数大于500的记录  
    9.                  db.delete( "book""pages>?"new String[]{"500" });  
    10.            }  
    11.      });  



    查询语句
    CRUD中其实用的最多的还是查询语句
    同样SQLiteDatabase也提供了query()方法,但是这个方法有好多个参数的类型,看最少的参数为7个

    public Cursor query (String table, String[] columns, String selection, String[]selectionArgs, String groupBy, String having, String orderBy)

    Added in API level 1

    Query the given table, returning a Cursor over the result set.

    Parameters
    table The table name to compile the query against.
    columns A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
    selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
    selectionArgs You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
    groupBy A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
    having A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
    orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
    Returns
    • Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
    See Also
    1:表名
    2:要查询的是哪几列,不指定的话就是默认查询所有列
    3、4:约束某一行或者是某几行的数据,不指定则默认是查询所有的数据
    5,groupby指定的列,不指定这项参数就相当于跳过
    6,having是对group之后的数据进行过滤
    7可以指定查询结果的排序方式

    当然调用query之后会返回一个Cursor对象,查询到的数据都将从这个对象中取出
    [java] view plain copy
    1. public void onClick(View v ) {  
    2.           // TODO Auto-generated method stub  
    3.        SQLiteDatabase db= dbHelper.getWritableDatabase();  
    4.         //查询book表中的所有数据  
    5.  Cursor cursor=  db.query( "book"nullnullnullnullnullnull);  
    6.    if( cursor.moveToFirst()){  
    7.           do{  
    8.              //遍历cursor对象,取出数据并打印  
    9.          String name= cursor.getString( cursor.getColumnIndex( "name"));  
    10.        String author= cursor.getString( cursor.getColumnIndex( "author"));  
    11.      int pages= cursor.getInt( cursor.getColumnIndex( "pages"));  
    12.      double price= cursor.getDouble( cursor.getColumnIndex( "price"));  
    13.                              
    14.          Log. d("MainActivity" , "书名是:" +name );  
    15.          Log. d("MainActivity" , "书的作者是:" +author );  
    16.          Log. d("MainActivity" ,"书的页数是:" +pages );  
    17.          Log. d("MainActivity" , "书的价钱是:" +price );  
    18.           } while( cursor.moveToNext());  
    19.          }  
    20.      cursor.close();  
    21.     }  
    22.   });  
    首先是通过db.query得到cursor对象,在cursor类中我们发现了下面的一些方法,getString,getDouble,getInt等但是都需要传一个参数进去,也就是所在列的下标,从0开始计数
    要得到相应列所在的下标同样有方法getColumnIndex(String columnName),这样的话先得到列所在的下标,然后通过该下标得到相应的记录值



    public abstract int getColumnIndex (String columnName)

    Added in API level 1

    Returns the zero-based index for the given column name, or -1 if the column doesn't exist. If you expect the column to exist use getColumnIndexOrThrow(String) instead, which will make the error more clear.

    Parameters
    columnName the name of the target column.
    Returns
    • the zero-based column index for the given column name, or -1 if the column name does not exist.
    展开全文
  • Android数据持久化实现方式分为内部存储、外部存储、及网络数据,本章节根据数据持久化的方式对数据的存和取进行一一讲解。 二:数据持久化方式 1:内部存储 内部存储方式创建的所有文件都在和应用包名相同的...

    一:数据持久化

    何为数据持久化?就是在退出应用程序或重启设备后数据不会丢失,例如每次打开淘宝都可以查看购物车中添加的商品信息和订单情况。

    在Android中数据持久化实现方式分为内部存储、外部存储、及网络数据,本章节根据数据持久化的方式对数据的存和取进行一一讲解。

    二:数据持久化方式

    1:内部存储

    内部存储方式创建的所有文件都在和应用包名相同的目录下,默认只有当前应用可以访问这些数据,当前应用程序卸载之后,这些数据也会被删除。在正常设备中无权限查看此目录中的内容,root之后是可以的。

    • File文件存储

    根据Android系统提供的方法openFileOutPut()默认存储文件的路径是/data/data/packageName/files/目录下,当然也可以自定义存储路径,通过new File()方法。这里只针对默认的创建方式举例说明:

    文件的保存:

    openFileOutPut()方法的第一参数为文件名称,第二个参数为保存文件的模式,操作模式分很多种。

    MODE_PRIVATE是默认的操作模式,表示当文件存在的时候将覆盖原有的数据 ;

    MODE_APPEND表示当文件不存在时则创建,存在时则追加数据 。

    文件的读取:

    • SharedPreferences存储

    SharedPreferences是使用键值对的方式来存储数据的,根据键读取相应的值,生成的xml文件存储目录为/data/data/packageName/shared_prefs/目录下 。

     1 >  存储方式

    存数据时需要先得到SharedPreferences对象,然后再得到SharedPreferences.Edit对象edit , 以edit.putxxx(key,value)方法添加数据,最后用apply()提交数据;获取数据时用SharedPreferences对象的getxx(key,default)方法,default代表根据数据类型自定义的默认值,如果根据key得到的值是空那就返回default定义的值 。

    2 >   获取SharedPreferences的方式分为:

    context.getSharedPreferences() :

    第一个参数为文件名,当前文件不存在则会先创建文件;第二个参数为操作模式,当前默认操作模式为Context.MODE_PRIVATE,表示只有当前应用程序可以对此文件进行读写,与直接传0意思一样 。

    ((Activity)context).getPreferences():

    以默认操作模式做为参数,生成当前Activity名的xml文件 。

    PreferenceManager.getDefaultSharedPreferences() :

    Context作为参数,生成以当前包名为前缀的xml文件,packageName_preferences.xml

    3 >  存储例子:

    4> 读取例子:

    • SQLite数据库存储

    SQLite是Android内置轻量级数据库,运算速度快,占用资源少,用标准的SQL语法实现相关功能 。数据库存放位置/data/data/packageName/databases/xx.db。

    每一个SQLite数据库都有一个叫sqlite_master的系统表,表内存储当前数据库中所有表的相关信息,表名、索引、用于创建此表的sql语句等,sqlite_master只能读取,不能做其他操作;另一个表sqlite_temp_master存储的是所有的临时表,表的结构与sqliter_master一致。

    创建数据库及数据表成功后就可以对数据进行操作,分为C=添加/insert;R=查询/select;U=更新/update;D=删除/delete,使用对应的SQL语句实现。借助生成的SQLiteDatabase对象完成CRUD的操作。

    1 > 创建数据库

    通过实现SQLiteOpenHelper抽象类完成数据库的创建与升级,SQLiteOpenHelper抽象类中的两个抽象方法onCreate() 和onUpgrade(),一般在重写onCreate()方法时实现创建表的逻辑 。

    2 > 查看数据库文件(设备需要root)

    adb命令查看:

    工具查看:

    3 > 查看数据表是否存在

    4 > 插入表数据

    代码插入:

    命令行插入:

    5 > 查看表数据

    代码查看:

    命令查看:

    6 > 删除表/表数据

    删除单条数据:

    删除所有数据:

    删除表:

    7 > 更新数据库

    更新数据库最初方式,直接在onUpgrade()方法中添加如下语句,如果表存在则将原表删除重新调用onCreate()方法进行创建

    初始化时更改下数据库版本号:

    但这样会有一个问题,添加新表会删除之前表及表数据,导致原有数据清空,升级数据库一般都会保留原数据。如果直接从v1版升级到v2版,就从当前数据库版本为DEFAULT_VERSION=1,更新至NEW_VERSION=2,那就直接调用onUpgrade()方法,在方法内部判断版本号,如果新版本号>旧版本号,并且旧版本号与DEFAULT_VERSION相等那就在原数据库中再添加一个Book表;

    如果直接安装v2版本,那直接调用onCreate() -->onUpgrade()方法,onUpgrade()实现同上,如果多次升级数据库那就可以根据对应版本号做相应更改的操作。

    这时查看下user.db数据库中的表,可以看到包含Book与User:

    查看Book表中也成功添加了一条数据

    8 > 更新表数据

    代码更新:

    更新结果:

    命令更新:

    也可以用SQLiteDatabase的execSQL(sql)执行Sql语句来完成CRUD的操作,这里就不详细说了。

    2:外部存储

    外部存储一般是存储在sdcard上,任何有sdcard访问权限的应用均可以对数据进行访问,外部存储需要申请读写权限 ,否则访问时会抛异常。

    • SdCard存储

    3:网络数据

    有些数据需要实时更新,那用内部或外部存储工作量会很大,所占空间也大,这时通过网络请求向服务端请求所需要的数据会方便很多,需要指定<uses-permission android:name="android.permission.INTERNET"/>网络权限 ,具体网络请求实现可以用原生的也可以使用相应类库。

     

    展开全文
  • Android数据持久化存储

    千次阅读 2016-05-05 14:51:19
    Android数据持久化存储共有四种方式,分别是文件存储、SharedPreferences、Sqlite数据库和ContentProvider。在本篇幅中只介绍前面三种存储方式,因为ContentProvider属于android四大组件之一,所以它的数据存储方式...

    Android数据持久化存储共有四种方式,分别是文件存储、SharedPreferencesSqlite数据库和ContentProvider。在本篇幅中只介绍前面三种存储方式,因为ContentProvider属于android四大组件之一,所以它的数据存储方式在介绍四大组件的时候说明。

    1、文件存储

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

    文件存储有两种方式,一是存储到手机内存中(memory,一是存储到sd卡中。

    1.1、存储到手机内存中

    1)将数据存储到文件中

    Context类中提供了一个 openFileOutput()方法,可以用于将数据存储到指定的文件中。

    方法介绍: 

    openFileOutput(name, mode):

    name:是文件名,注意这里指定的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data/<package name>/files/(等价于 getFilesDir())目 录下 的 

    mode:是文件的操作模式 ,

    MODE_PRIVATE:默认的操作模式,同名文件内容会被覆盖。

    MODE_APPEND则表示 如果该文件已存在就往文件里面追加内容,不存在就创建新文件。

    还有另外两种(android 4.2被废弃)MODE_WORLD_READABLEMODE_WORLD_WRITEABLE,这两种模式表示允许其他的应用程序对我们程序中的文件进行读写操作。

    openFileOutput()方法返回的是一个 FileOutputStream对象,得到了这个对象之后就可以 使用 Java流的方式将数据写入到文件中了

    public void save() {

    String data = "Data to save";

    FileOutputStream out = null;

    BufferedWriter writer = null;

    try {

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

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

    writer.write(data);

    catch (IOException e) {

    e.printStackTrace();

    finally {

    try {

    if (writer != null) {

    writer.close();

    }

    catch (IOException e) {}

    }

          }

        }

    以上代码就是将将一 段文本内容保存到文件中。

    完成将数据存储到文件中,接下来如何从文件中读取数据呢?

    2)从文件中读取数据

    Context类中还提供了一个 openFileInput()方法,用于从文件中读取数据。

    这个方法只接收一个参数,即要读取的文件名,使用openFileInput("filename")读取存放在/data/data/<package name>/files目录应用私有的文件。该方法返回一个 FileInputStream对象,得到了这个对象之后再通过 Java流的方式就可以将数据读取出来了。 

    public String load() {

    FileInputStream in = null;

    BufferedReader reader = null;

    StringBuilder content = new StringBuilder();

    try {

    in = openFileInput("data");

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

    String line = "";

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

    content.append(line);

    }

    catch (IOException e) {

    e.printStackTrace();

    finally {

    if (reader != null) {

    try {

    reader.close();

    catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    return content.toString();

    }

    1.2、存储到sd卡中

    前面说了file储存,数据是存储在应用程序内的,文件大小受到限制;当要存储大的文件时,就要使用sd卡方式存储了。使用sd卡存储主要是使用Environment这个类的功能。

    1)将数据存储到sd卡中

    Environment类介绍:

    ①常用常量:

    String MEDIA_MOUNTED:外部存储器可读可写

    MEDIA_MOUNTED_READ_ONLY:外部存储器只读

    ②常用方法:

    getExternalStorageDirectory ():获取SDCard的目录/mnt/sdcard

    getExternalStorageState ():获取外部存储器的当前状态

    通过简单价绍Environment类的使用,接下来就是sd卡读写数据了。以下是sd卡读写数据的步骤:

    1)判断sd卡的状态

    2)获取存储器的目录,即sd卡的目录

    3)使用IO流对sd卡进行文件的读写操作

    4)在清单文件中添加权限

    写入数据到sd卡中代码如下:

    public void write2Sd(){

    if (Environment.getExternalStorageState().equals(  

                Environment.MEDIA_MOUNTED)) {  

     

            String content = edtContent.getText().toString();  

     

            try {  

     

                // 获取SDcard路径  

                File sdCardDir = Environment  

                        .getExternalStorageDirectory();  

     

                // SDCard目录:/mnt/sdcard  

                String sdcardPath = sdCardDir.getAbsolutePath();  

     

                File file = new File(sdCardDir, FILE_NAME);  

                // File file = new File(sdcardPath  

                // + File.separator + FILE_NAME);  

                // 以指定文件创建RandomAccessFile对象  

                RandomAccessFile raf = new RandomAccessFile(file, "rw");  

                // 将文件记录指针移动最后  

                raf.seek(file.length());  

                // 输出文件内容  

                raf.write(content.getBytes());  

                raf.close();  

     

            } catch (Exception e) {  

                // TODO: handle exception  

            }  

        }  

    }

     

    以上代码可知,往sd卡中写数据先调用getExternalStorageState()判断sd卡状态,接着获取sd卡的存储路径,以路径很文件名创建文件,最后使用RandomAccessFile 类存储数据,使用该类的好处是可以定位的指定位置进行读写数据。

    2)从sd卡中读取数据

    public void readFromSd(){

    if (Environment.getExternalStorageState().equals(  

                Environment.MEDIA_MOUNTED)) {  

            // 获取SDcard路径  

     

            StringBuilder sb = new StringBuilder();  

            try {  

                File sdCardDir = Environment  

                        .getExternalStorageDirectory();  

                File file = new File(sdCardDir, FILE_NAME);  

     

                InputStream inputStream = new FileInputStream(file);  

                int len = 0;  

                byte[] buffer = new byte[1024];  

                while ((len = inputStream.read(buffer)) != -1) {  

     

                    sb.append(new String(buffer, 0, len));  

                }  

                tvResult.setText(sb.toString());  

                // 关闭流  

                inputStream.close();  

     

            } catch (Exception e) {  

                // TODO Auto-generated catch block  

                e.printStackTrace();  

            }  

        } 

    }

    2、SharedPreferences存储

    2.1将数据存储到 sp

    SharedPreferences类,它是一个轻量级的存储类,适合用于保存软件配置参数。SharedPreferences是使用键值对的方式来存储数据的,存储数据是以xml文件形式存储,文件存放在/data/data/<package name>/shared_prefs目录下。

    步骤:

    1)获取SharedPreferences对象。

    要想使用sp来存储数据,首先需要获取到sp对象。Android 中主要提供了三种方法用于得到 sp对象。 

    1Context类中的 getSharedPreferences(name, mode)方法

    Name:用于指定 SharedPreferences文件的名称

    mode指定操作模式,和文件存储模式一样。

    2Activity类中的 getPreferences(mode)方法 

    使用这个方法时会自动将当前活动的类名作为 SharedPreferences的文件名。 

    3. PreferenceManager类中的 getDefaultSharedPreferences(context)方法  这是一个静态方法,使用当前应用程序的包名作为前缀名来命名文件。 

    2)调用sp对象的edit()方法来获取一个SharedPreferences.Editor对象。 

    3)向 SharedPreferences.Editor 对象中添加数据。比如添加一个布尔型数据就使用 putBoolean方法,添加一个字符串则使用 putString()方法,以此类推。

    4)调用 commit()方法将添加的数据提交,从而完成数据存储操作

    2.2、从sp中读取数据

    步骤:

    1)获取SharedPreferences对象。

    2然后分别调用它的 geXxx()方法获取存储的值。如getString()getInt()和 getBoolean(),没有找到相应的值就会使用方法中传入的默认值来代替

    3、Sqlite数据库存储

    SQLite是一款轻量级的关系型数据库,它的运算速度非常快, 占用资源很少,通常只需要几百 K的内存就足够了。SQLite 不仅支持标准的SQL语法,还遵循了数据库的 ACID事务

    Android提供了一个 SQLiteOpenHelper帮助类,借助这个类就可以非常简单地对数据库进行创建和升级。

     SQLiteOpenHelper是一个抽象类,有两个抽象方法,分别是 onCreate()和 onUpgrade(),分别在这两个方法中去实现创建、升级数据库的逻辑。 SQLiteOpenHelper中还有两个实例方法,getReadableDatabase() 和 getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在 则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。

    3.1、创建数据库

    因为SQLiteOpenHelper是一个抽象类,创建数据库的时候可以创建一个类继承SQLiteOpenHelper,并重写其两个抽象方法。新建MyDatabaseHelper 类继承自 SQLiteOpenHelper,代码如下所示: 

    public class MyDatabaseHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = "create table book ("

    "id integer primary key autoincrement, "

                + "author text, "

    "price real, " 

                + "pages integer, name text)";

    private Context mContext;

     

    public MyDatabaseHelper(Context context, String name,

    CursorFactory factory, int version) {

    super(context, name, factory, version);

    mContext = context;

    }

     

    @Override

    public void onCreate(SQLiteDatabase db) {

    db.execSQL(CREATE_BOOK);

    Toast.makeText(mContext"Create succeeded", Toast.LENGTH_SHORT).show();

    }

     

    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)    {

    }

    }

    如上所示,先把建表语句写成字符串常量, 在onCreate()方法中调用  SQLiteDatabase的 execSQL()方法去执行这条建表语句,以保证数据库创建的同时也成功的创建Book表。

    然后再布局文件加入了一个id.create_databaseButton按钮,用于创建数据库。最后修改 MainActivity中的代码,如下所示: 

    public class MainActivity extends Activity {

    private MyDatabaseHelper dbHelper;

     

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

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

    Button createDatabase = (Button) findViewById(R.id.create_database);

    createDatabase.setOnClickListener(new OnClickListener() {

    @Override

    public void onClick(View v) {

    dbHelper.getWritableDatabase();

    }

    });

    }

    }

    如上所示,在 onCreate()方法中构建了一个 MyDatabaseHelper对象,并且通过构造函数的参数将数据库名指定为 BookStore.db,版本号指定为 1,然后在 Create database按钮的点击事件里调用了getWritableDatabase()方法。这样当第一次点击按钮时,就会检测 到当前程序中并没有BookStore.db这个数据库,于是会创建该数据库并调用MyDatabaseHelper中的 onCreate()方法同时也创建Book表。

    3.2、升级数据库

    MyDatabaseHelper中的onUpgrade() 方法是用于对数据库进行升级的。

    接着我们再添加一张 Category表用于记录书籍的分类,修改MyDatabaseHelper 代码如下:

    public class MyDatabaseHelper extends SQLiteOpenHelper {

    public static final String CREATE_CATEGORY = "create table Category ("

    "id integer primary key autoincrement, " 

                + "category_name text, "

    "category_code integer)";

    .....

       @Override

    public void onCreate(SQLiteDatabase db) {

    db.execSQL(CREATE_BOOK);

    db.execSQL(CREATE_CATEGORY);

    }

     

        @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    switch (oldVersion) {

    case 1:

    db.execSQL(CREATE_CATEGORY);

    case 2:

    db.execSQL("alter table Book add column category_id integer");

    default:

    }

    }

    }

     

     

    可以看到,这里在onUpgrade()方法中加入了一个switch判断,如果oldVersion等于1,就再创建一个CATEGORY表。接着只需要在创建MyDatabaseHelper 时构造函数第四个参数改成大于1的整数即可。

    紧接着,发现CATEGORY表少添加了category_id列,为了保留原有数据库的数据,只需在添加一个case语句,使用alter..add添加该列就行,注意case之间没有break使用这种方式升级数据库就不会导致表中的数据丢失问题。

    3.3、数据库的CRUD操作

    数据库的crud其中 代表添加 (Create),R代表查询(Retrieve),U代表更新(Update) ,D代表删除(Delete)。每一种操 作又各自对应了一种 SQL命令。

    调用SQLiteOpenHelpergetReadableDatabase()getWritableDatabase()

    方法是可以用于创建和升级数据库的,这两个方法还都会返回一个SQLiteDatabase 对象,借助这个对象就可以对数据进行 CRUD操作。 

    1数据库的add操作

    SQLiteDatabase中的 insert(table, nullColumnHack, values)方法

    Table:表名

    nullColumnHack:通常用不到,直接传null

    Value:ContentValue,map集合,表示待添加的数据。

    public void add() {

    SQLiteDatabase db = dbHelper.getWritableDatabase();

    ContentValues values = new ContentValues(); // 开始组装第一条数据

    values.put("name""The Da Vinci Code");

    values.put("author""Dan Brown");

    values.put("pages", 454);

    values.put("price", 16.96);

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

    }

     

    2)R数据库的query操作

    SQLiteDatabase中的query(table, columns, selection, selectionArgs, groupBy, having, orderBy)方法:

    table, 表名

    columns, 指定去查询哪几列

    selection, selectionArgs, 指定约束条件和占位符,表示查询哪几行

    groupBy, 查询结果进行group by操作

    having, 对groupBy后的数据进行进一步过滤

    orderBy对查询的结果进行排序

     

    public void query() {

    SQLiteDatabase db = dbHelper.getWritableDatabase();

     

    // 查询Book表中所有的数据

    Cursor cursor = db.query("Book"nullnullnullnullnullnull);

    if (cursor.moveToFirst()) {

    do {

    // 遍历Cursor对象

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

    String author = cursor.getString(cursor

    .getColumnIndex("author"));

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

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

     

    while (cursor.moveToNext());

    }

    cursor.close();

    }

     

    3U数据库的update操作

    SQLiteDatabase中的 update(table, values, whereClause, whereArgs)方法

    Table:表名

    Value:ContentValue,map集合。

    whereClausewhereArgs:指定第三和第四个参数用于指定修改哪些行

    public void update() {

    SQLiteDatabase db = dbHelper.getWritableDatabase();

    ContentValues values = new ContentValues(); 

    values.put("price", 10.99); 

    db.update("Book", values, "name = ?"

    new String[] { "xiao ming" }); 

    }

     

    4)D数据库的delete操作

    SQLiteDatabase中的 delete(table, whereClause, whereArgs)

    table,表名

    whereClause, whereArgs:指定要删除哪些行,对应sql语句的where部分。

    public void delete() {

    SQLiteDatabase db = dbHelper.getWritableDatabase();

     

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

    }

    3.4、使用SQL操作数据库

    Android中支持使用原生的sql语句执行数据库的增删改查操作。具体如下:

    添加数据的方法如下:

     db.execSQL("insertintoBook(name,author,pages,price)values(?,?,?,?)", new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" }); 

     更新数据的方法如下: 

    db.execSQL("updateBooksetprice=? wherename=?",new String[]{"10.99", "The Da Vinci Code" }); 

    删除数据的方法如下: 

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

    查询数据的方法如下: 

    db.rawQuery("select * from Book", null); 

    3.5、使用LitePal框架完成Android数据库的存储

    使用SQLiteOpenHelper有一个弊端,就是如果数据库中某一列已经没有用了,我想把这一列删除,使用SQLite是无法实现删除某一列的(开发中多是忽视它,反正以后也用不到,留着也占用不了多少空间),另外就是如果表之间存在关联关系,建表语句就会变得很复杂,因此使用LitePal来自动建立表关联又是一个非常不错的选择,我们不需要关心什么外键、中间表等实现的细节,只需要在对象中声明好它们相互之间的引用关系,LitePal就会自动在数据库表之间建立好相应的关联关系了。

    注:虽然使用Litepal框架可以轻松实习表的关联,但表的关联知识了解下还是有必要的。多表设计数据库口诀:

    一对一关联的实现方式是用外键,多对一关联的实现方式也是用外键(外键必须加载多方),多对多关联的实现方式是用中间表。

    关于使用LitePal的教程可以参考这篇博客:

    http://blog.csdn.net/guolin_blog/article/details/38461239

    LitePal开源项目地址:https://github.com/LitePalFramework/LitePal

     

     

    展开全文
  • Android数据持久化存储共有四种方式,分别是文件存储、SharedPreferences、Sqlite数据库和ContentProvider。在本篇幅中只介绍前面三种存储方式,因为ContentProvider属于android四大组件之一,所以它的数据存储方式...


    Android数据持久化存储共有四种方式,分别是文件存储、SharedPreferences、Sqlite数据库和ContentProvider。在本篇幅中只介绍前面三种存储方式,因为ContentProvider属于android四大组件之一,所以它的数据存储方式在介绍四大组件的时候说明。

    1、文件存储

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

    文件存储有两种方式,一是存储到手机内存中(memory),一是存储到sd卡中。

    1.1、存储到手机内存中

    1)将数据存储到文件中

    Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中。

    方法介绍:

    openFileOutput(name,mode):

    name:是文件名,注意这里指定的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data//files/(等价于getFilesDir())目录下的

    mode:是文件的操作模式,

    MODE_PRIVATE:默认的操作模式,同名文件内容会被覆盖。

    MODE_APPEND则表示如果该文件已存在就往文件里面追加内容,不存在就创建新文件。

    还有另外两种(android4.2被废弃),MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE,这两种模式表示允许其他的应用程序对我们程序中的文件进行读写操作。

    openFileOutput()方法返回的是一个FileOutputStream对象,得到了这个对象之后就可以使用Java流的方式将数据写入到文件中了。

    publicvoidsave(){

    Stringdata="Datatosave";

    FileOutputStreamout=null;

    BufferedWriterwriter=null;

    try{

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

    writer=newBufferedWriter(newOutputStreamWriter(out));

    writer.write(data);

    }catch(IOExceptione){

    e.printStackTrace();

    }finally{

    try{

    if(writer!=null){

    writer.close();

    }

    }catch(IOExceptione){}

    }

    }

    }

    以上代码就是将将一段文本内容保存到文件中。

    完成将数据存储到文件中,接下来如何从文件中读取数据呢?

    2)从文件中读取数据

    Context类中还提供了一个openFileInput()方法,用于从文件中读取数据。

    这个方法只接收一个参数,即要读取的文件名,使用openFileInput("filename")读取存放在/data/data//files目录应用私有的文件。该方法返回一个FileInputStream对象,得到了这个对象之后再通过Java流的方式就可以将数据读取出来了。

    publicStringload(){

    FileInputStreamin=null;

    BufferedReaderreader=null;

    StringBuildercontent=newStringBuilder();

    try{

    in=openFileInput("data");

    reader=newBufferedReader(newInputStreamReader(in));

    Stringline="";

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

    content.append(line);

    }

    }catch(IOExceptione){

    e.printStackTrace();

    }finally{

    if(reader!=null){

    try{

    reader.close();

    }catch(IOExceptione){

    e.printStackTrace();

    }

    }

    }

    returncontent.toString();

    }

    1.2、存储到sd卡中

    前面说了file储存,数据是存储在应用程序内的,文件大小受到限制;当要存储大的文件时,就要使用sd卡方式存储了。使用sd卡存储主要是使用Environment这个类的功能。

    1)将数据存储到sd卡中

    Environment类介绍:

    ①常用常量:

    StringMEDIA_MOUNTED:外部存储器可读可写

    MEDIA_MOUNTED_READ_ONLY:外部存储器只读

    ②常用方法:

    getExternalStorageDirectory():获取SDCard的目录,/mnt/sdcard

    getExternalStorageState():获取外部存储器的当前状态

    通过简单价绍Environment类的使用,接下来就是sd卡读写数据了。以下是往sd卡读写数据的步骤:

    1)判断sd卡的状态

    2)获取存储器的目录,即sd卡的目录

    3)使用IO流对sd卡进行文件的读写操作

    4)在清单文件中添加权限

    写入数据到sd卡中代码如下:

    publicvoidwrite2Sd(){

    if(Environment.getExternalStorageState().equals(

    Environment.MEDIA_MOUNTED)){

     

    Stringcontent=edtContent.getText().toString();

     

    try{

     

    //获取SDcard路径

    FilesdCardDir=Environment

    .getExternalStorageDirectory();

     

    //SDCard目录:/mnt/sdcard

    StringsdcardPath=sdCardDir.getAbsolutePath();

     

    Filefile=newFile(sdCardDir,FILE_NAME);

    //Filefile=newFile(sdcardPath

    //+File.separator+FILE_NAME);

    //以指定文件创建RandomAccessFile对象

    RandomAccessFileraf=newRandomAccessFile(file,"rw");

    //将文件记录指针移动最后

    raf.seek(file.length());

    //输出文件内容

    raf.write(content.getBytes());

    raf.close();

     

    }catch(Exceptione){

    //TODO:handleexception

    }

    }

    }

     

    以上代码可知,往sd卡中写数据先调用getExternalStorageState()判断sd卡状态,接着获取sd卡的存储路径,以路径很文件名创建文件,最后使用RandomAccessFile类存储数据,使用该类的好处是可以定位的指定位置进行读写数据。

    2)从sd卡中读取数据

    publicvoidreadFromSd(){

    if(Environment.getExternalStorageState().equals(

    Environment.MEDIA_MOUNTED)){

    //获取SDcard路径

     

    StringBuildersb=newStringBuilder();

    try{

    FilesdCardDir=Environment

    .getExternalStorageDirectory();

    Filefile=newFile(sdCardDir,FILE_NAME);

     

    InputStreaminputStream=newFileInputStream(file);

    intlen=0;

    byte[]buffer=newbyte[1024];

    while((len=inputStream.read(buffer))!=-1){

     

    sb.append(newString(buffer,0,len));

    }

    tvResult.setText(sb.toString());

    //关闭流

    inputStream.close();

     

    }catch(Exceptione){

    //TODOAuto-generatedcatchblock

    e.printStackTrace();

    }

    }

    }

    2、SharedPreferences存储

    2.1、将数据存储到sp中

    SharedPreferences类,它是一个轻量级的存储类,适合用于保存软件配置参数。SharedPreferences是使用键值对的方式来存储数据的,存储数据是以xml文件形式存储,文件存放在/data/data//shared_prefs目录下。

    步骤:

    1)获取SharedPreferences对象。

    要想使用sp来存储数据,首先需要获取到sp对象。Android中主要提供了三种方法用于得到sp对象。

    1、Context类中的getSharedPreferences(name,mode)方法

    Name:用于指定SharedPreferences文件的名称

    mode指定操作模式,和文件存储模式一样。

    2、Activity类中的getPreferences(mode)方法

    使用这个方法时会自动将当前活动的类名作为SharedPreferences的文件名。

    3.PreferenceManager类中的getDefaultSharedPreferences(context)方法 这是一个静态方法,使用当前应用程序的包名作为前缀名来命名文件。

    2)调用sp对象的edit()方法来获取一个SharedPreferences.Editor对象。

    3)向SharedPreferences.Editor对象中添加数据。比如添加一个布尔型数据就使用putBoolean方法,添加一个字符串则使用putString()方法,以此类推。

    4)调用commit()方法将添加的数据提交,从而完成数据存储操作

    2.2、从sp中读取数据

    步骤:

    1)获取SharedPreferences对象。

    2)然后分别调用它的geXxx()方法获取存储的值。如getString()、getInt()和getBoolean(),没有找到相应的值就会使用方法中传入的默认值来代替

    3、Sqlite数据库存储

    SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百K的内存就足够了。SQLite不仅支持标准的SQL语法,还遵循了数据库的ACID事务。

    Android提供了一个SQLiteOpenHelper帮助类,借助这个类就可以非常简单地对数据库进行创建和升级。

    SQLiteOpenHelper是一个抽象类,有两个抽象方法,分别是onCreate()和onUpgrade(),分别在这两个方法中去实现创建、升级数据库的逻辑。SQLiteOpenHelper中还有两个实例方法,getReadableDatabase()和getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。

    3.1、创建数据库

    因为SQLiteOpenHelper是一个抽象类,创建数据库的时候可以创建一个类继承SQLiteOpenHelper,并重写其两个抽象方法。新建MyDatabaseHelper类继承自SQLiteOpenHelper,代码如下所示:

    publicclassMyDatabaseHelperextendsSQLiteOpenHelper{

    publicstaticfinalStringCREATE_BOOK="createtablebook("

    +"idintegerprimarykeyautoincrement,"

    +"authortext,"

    +"pricereal,"

    +"pagesinteger,nametext)";

    privateContextmContext;

     

    publicMyDatabaseHelper(Contextcontext,Stringname,

    CursorFactoryfactory,intversion){

    super(context,name,factory,version);

    mContext=context;

    }

     

    @Override

    publicvoidonCreate(SQLiteDatabasedb){

    db.execSQL(CREATE_BOOK);

    Toast.makeText(mContext,"Createsucceeded",Toast.LENGTH_SHORT).show();

    }

     

    @Override

    publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){

    }

    }

    如上所示,先把建表语句写成字符串常量,在onCreate()方法中调用SQLiteDatabase的execSQL()方法去执行这条建表语句,以保证数据库创建的同时也成功的创建Book表。

    然后再布局文件加入了一个id是.create_database的Button按钮,用于创建数据库。最后修改MainActivity中的代码,如下所示:

    publicclassMainActivityextendsActivity{

    privateMyDatabaseHelperdbHelper;

     

    @Override

    protectedvoidonCreate(BundlesavedInstanceState){

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

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

    ButtoncreateDatabase=(Button)findViewById(R.id.create_database);

    createDatabase.setOnClickListener(newOnClickListener(){

    @Override

    publicvoidonClick(Viewv){

    dbHelper.getWritableDatabase();

    }

    });

    }

    }

    如上所示,在onCreate()方法中构建了一个MyDatabaseHelper对象,并且通过构造函数的参数将数据库名指定为BookStore.db,版本号指定为1,然后在Createdatabase按钮的点击事件里调用了getWritableDatabase()方法。这样当第一次点击按钮时,就会检测到当前程序中并没有BookStore.db这个数据库,于是会创建该数据库并调用MyDatabaseHelper中的onCreate()方法同时也创建Book表。

    3.2、升级数据库

    MyDatabaseHelper中的onUpgrade()方法是用于对数据库进行升级的。

    接着我们再添加一张Category表用于记录书籍的分类,修改MyDatabaseHelper代码如下:

    publicclassMyDatabaseHelperextendsSQLiteOpenHelper{

    publicstaticfinalStringCREATE_CATEGORY="createtableCategory("

    +"idintegerprimarykeyautoincrement,"

    +"category_nametext,"

    +"category_codeinteger)";

    .....

     

    @Override

    publicvoidonCreate(SQLiteDatabasedb){

    db.execSQL(CREATE_BOOK);

    db.execSQL(CREATE_CATEGORY);

    }

     

    @Override

    publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){

    switch(oldVersion){

    case1:

    db.execSQL(CREATE_CATEGORY);

    case2:

    db.execSQL("altertableBookaddcolumncategory_idinteger");

    default:

    }

    }

    }

     

     

    可以看到,这里在onUpgrade()方法中加入了一个switch判断,如果oldVersion等于1,就再创建一个CATEGORY表。接着只需要在创建MyDatabaseHelper时构造函数第四个参数改成大于1的整数即可。

    紧接着,发现CATEGORY表少添加了category_id列,为了保留原有数据库的数据,只需在添加一个case语句,使用alter..add添加该列就行,注意case之间没有break。使用这种方式升级数据库就不会导致表中的数据丢失问题。

    3.3、数据库的CRUD操作

    数据库的crud其中C代表添加(Create),R代表查询(Retrieve),U代表更新(Update),D代表删除(Delete)。每一种操作又各自对应了一种SQL命令。

    调用SQLiteOpenHelper的getReadableDatabase()或getWritableDatabase()

    方法是可以用于创建和升级数据库的,这两个方法还都会返回一个SQLiteDatabase对象,借助这个对象就可以对数据进行CRUD操作。

    1)C数据库的add操作

    SQLiteDatabase中的insert(table,nullColumnHack,values)方法

    Table:表名

    nullColumnHack:通常用不到,直接传null。

    Value:ContentValue,是map集合,表示待添加的数据。

    publicvoidadd(){

    SQLiteDatabasedb=dbHelper.getWritableDatabase();

    ContentValuesvalues=newContentValues();//开始组装第一条数据

    values.put("name","TheDaVinciCode");

    values.put("author","DanBrown");

    values.put("pages",454);

    values.put("price",16.96);

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

    }

     

    2)R数据库的query操作

    SQLiteDatabase中的query(table,columns,selection,selectionArgs,groupBy,having,orderBy)方法:

    table,表名

    columns,指定去查询哪几列

    selection,selectionArgs,指定约束条件和占位符,表示查询哪几行

    groupBy,对查询结果进行groupby操作

    having,对groupBy后的数据进行进一步过滤

    orderBy,对查询的结果进行排序

     

    publicvoidquery(){

    SQLiteDatabasedb=dbHelper.getWritableDatabase();

     

    //查询Book表中所有的数据

    Cursorcursor=db.query("Book",null,null,null,null,null,null);

    if(cursor.moveToFirst()){

    do{

    //遍历Cursor对象

    Stringname=cursor.getString(cursor.getColumnIndex("name"));

    Stringauthor=cursor.getString(cursor

    .getColumnIndex("author"));

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

    doubleprice=cursor.getDouble(cursor.getColumnIndex("price"));

     

    }while(cursor.moveToNext());

    }

    cursor.close();

    }

     

    3)U数据库的update操作

    SQLiteDatabase中的update(table,values,whereClause,whereArgs)方法

    Table:表名

    Value:ContentValue,是map集合。

    whereClause、whereArgs:指定第三和第四个参数用于指定修改哪些行

    publicvoidupdate(){

    SQLiteDatabasedb=dbHelper.getWritableDatabase();

     

    ContentValuesvalues=newContentValues();

    values.put("price",10.99);

    db.update("Book",values,"name=?",

    newString[]{"xiaoming"});

    }

     

    4)D数据库的delete操作

    SQLiteDatabase中的delete(table,whereClause,whereArgs)

    table,表名

    whereClause,whereArgs:指定要删除哪些行,对应sql语句的where部分。

    publicvoiddelete(){

    SQLiteDatabasedb=dbHelper.getWritableDatabase();

     

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

    }

    3.4、使用SQL操作数据库

    Android中支持使用原生的sql语句执行数据库的增删改查操作。具体如下:

    添加数据的方法如下:

    db.execSQL("insertintoBook(name,author,pages,price)values(?,?,?,?)",newString[]{"TheDaVinciCode","DanBrown","454","16.96"});

    更新数据的方法如下:

    db.execSQL("updateBooksetprice=?wherename=?",newString[]{"10.99","TheDaVinciCode"});

    删除数据的方法如下:

    db.execSQL("deletefromBookwherepages>?",newString[]{"500"});

    查询数据的方法如下:

    db.rawQuery("select*fromBook",null);

    3.5、使用LitePal框架完成Android数据库的存储

    使用SQLiteOpenHelper有一个弊端,就是如果数据库中某一列已经没有用了,我想把这一列删除,使用SQLite是无法实现删除某一列的(开发中多是忽视它,反正以后也用不到,留着也占用不了多少空间),另外就是如果表之间存在关联关系,建表语句就会变得很复杂,因此使用LitePal来自动建立表关联又是一个非常不错的选择,我们不需要关心什么外键、中间表等实现的细节,只需要在对象中声明好它们相互之间的引用关系,LitePal就会自动在数据库表之间建立好相应的关联关系了。

    注:虽然使用Litepal框架可以轻松实习表的关联,但表的关联知识了解下还是有必要的。多表设计数据库口诀:

    一对一关联的实现方式是用外键,多对一关联的实现方式也是用外键(外键必须加载多方),多对多关联的实现方式是用中间表。

    LitePal开源项目地址:https://github.com/LitePalFramework/LitePal


    展开全文
  • Android数据存储方式有五种 一、SharedPreferences 是一种轻型的数据存储方式 本质是基于XML文件存储key-value键值对数据 通常用来存储一些简单的配置信息 SharedPreference对象本身只能获取数据而不支持存储...
  • 在讨论数据持久化技术之前我们先了解几个概念? 什么是瞬时数据:存储在内存当中,有可能会因为程序的关闭或其他原因导致内存被收回而丢失的数据...安卓提供了三种方式用于简单的数据持久化功能:文件储存,SharedP...
  • 不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的。也就是说当保存一条数据的时候,需要给这条数据提供一个对应的健,这样再读取数据的时候就可以通过这个健把相应的值去出来,而...
  • 所谓的文件存储,就是将数据存储在文件中,不对数据有任何的格式转换处理,所有的数据都将数原封不动的保存到文件当中去,这种方式比较适合存储一些简单的文本数据或者二进制数据,比如评论的时候,中途退出,这...
  • 本文主要探究前三种存储方式。 一. 文件存储 将所有数据原封不动的保存到文件当中 适用于: 存储一些简单的文本数据或二进制数据 如何做: 通过 Context类的 openFileOutput() 方法 两个参数: 1.文件名 不可以...
  • 占用资源很少,通常只需要几百k的内存就足够了,之前多介绍的两种方式只适合去存储一些简单的数据和键值对,当蓄呀存储大量的复杂的关系型数据的时候,就会发现以上两种存储方式很难应付。下面开始介绍在android中...
  • 1、Files对象保存数据的分类 (1)、使用IO流进行存储,保存在/data/data/... 使用IO流方式存取数据,即使用FileOutputStream类提供的openFileOutput()方法获取输出流,输出文件到磁盘;使用FileInputStream类提供的o
  • Android数据存储的持久化技术有:文件存储,SharePreference存储,数据库存储,或者将数据存储在SD卡中,存储在SD卡上有一定的不安全因素。 1。文件存储 文件存储是Android中最基本的存储方式,它在存储的过程...
  • 原文: ...Android系统为我们提供了五种数据持久化存储方式,以满足不同的需求。 他们分别是: Shared Preferences Store private primitive data in key-valu
  • 1.数据持久化存储 android提供了4种文件存储方式:文件(/data/data/<包名>/files/),SharePreference(/data/data/<包名>/shared prefs/) , SQLite数据库(/data/data/<包名>/database/)和...
  • SharedPreferences是一种轻量级的存储方式,通过存为键值对保存为xml文件来存放读取数据,文件路径在data/data/程序包名/share_prefs目录下,只适合存储一些简单参数配置; 2.文件存储(三级缓存中的磁盘缓存) ...
  • Android数据持久化存储共有四种方式,分别是文件存储、SharedPreferences、Sqlite数据库和ContentProvider。在本篇幅中只介绍前面三种存储方式,因为ContentProvider属于android四大组件之一,所以它的数据存储方式...
  • 前言之前一直在讲AndroidUI的内容,但是还没有完结,之后会慢慢补充。今天讲讲其他的,关于数据持久化...在Android中,可以使用几种方式实现数据持久化:Shared Preferences:共享参数形式,一种以Key-Value的键值对...
  • Android 系统中主要提供了三种方式用于实现数据持久化功能,分别是: 1、文件存储 2、SharedPreference 存储 3、数据库存储。SharedPreferences 是使用键值对的方式存储数据的,使用 SharedPreferences来进行数据...
  • 持久化技术提供了一种机制可以让数据在瞬时状态和持久状态之间进行转换Android 系统提供了 3 种方式用于简单地实现数据持久化功能,即 文件存储,SharePreference存储 和 数据库存储。1.文件存储最基本的存储方式,...
  • SharedPreferences使用键值对的方式存储数据 存储一个数据的时候,需要给这个数据提供一个键,取这个数据的时候也需要使用这个键来取. * SharedPreferences对象的获取方式 * 1.Context类中的...
  • Android 数据持久化(SQLite数据存储

    千次阅读 2016-02-16 14:33:41
    数据分为两种:瞬时数据与永久数据。...说了这么多,然并卵,它跟本文的主题有什么关系呢,Android 系统提供了三种方式来实现数据持久化,即文件存储、SharedPreference 存储、数据库存储。本文主要介绍数据
  • Android 系统中主要提供了三种方式用于实现数据持久化功能,分别是: 1、文件存储 2、SharedPreference 存储 3、数据库存储。 今天我们学习第一种存储方式:文件存储。 使用范围:文件储存适合用于存储一些...
  • SharedPreferences使用键值对的方式存储数据,支持多种不同类型数据存储。 如果想要使用SharedPreferences来存储数据,首先需要获取到SharedPreferences对象,有三种方法: 1. Context类中的...
  • Android 数据持久化

    2017-04-05 15:56:42
    Android 数据持久化就是指讲存储在内存中的瞬时数据保存在存储设备...Android 中主要提供了3种方式用于简单地实现数据持久化功能,文件存储,SharedPreference存储和数据库存储。相比另一个存储在SD卡上相对简单安全。
  • Android数据持久化

    2017-04-28 11:09:12
    Android中经常会遇到操作数据的功能,所以Android数据持久化是一个挺重要的知识点 Android 数据持久化有四种方式 1.文件存储(内部存储,外部存储)。 2.SharedPreferences。 3.Sqlite数据库。 4.网络存储(服务器)。 ...
  • 1、sharedpreference 共享参数(一般用于保存用户设置偏好); ** * 特点: ...* (1)以键值对的形式保存到data/data/应用程序包名/shared_prefs目录的XXX.xml文件中 ...* (2)目前支持的数据类型...* (4)通常用来存储App

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 479
精华内容 191
关键字:

android数据持久化存储方式