Android提供了4种数据存储技术,分别是SharedPreferences、Files、SQLite数据库和网络存储数据。(有的开发者认为使用ContentProvider也可以算是一种,但我觉得ContentProvider本质上还是用的sqlite,所以未将其纳入其中)

其中最常用的有这三种:SharedPreferences、Files、SQLite数据库。

下面我们分别来认识一下:

1、SharedPreferences

它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。

其存储位置在/data/data/<包名>/shared_prefs目录下。

SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。

它主要是通过键值对的方式来存储数据的,获取它的方式有两种:

  1、getSharedPreferences():如果需要多个使用名称来区分的共享文件,则可以使用该方法,其第一个参数就是共享文件的名称。对于使用同一个名称获得的多个SharedPreferences引用,其指向同一个对象。

  2、getPreferences();如果Activity仅需要一个共享文件,则可以使用该方法。因为只有一个文件,它并不需要提供名称。

完成SharedPreferences类中增加值的步骤如下:

  1. 调用SharedPreferences类的edit()方法获得SharedPreferences.Editor对象。
  2. 调用如putBoolean()、putString()等方法附加值
  3. 使用commit()方法提交新值。

SharedPreferences使用时,分两种:

一种是在一个项目中使用,另一个是在两个不同的项目中使用。

下面我们用实例来演示一下,首先是第一种情况(即在一个项目中使用):

首先是布局文件main.xml:

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     android:orientation="vertical" > 6     <LinearLayout  7         android:layout_width="match_parent" 8         android:layout_height="wrap_content"> 9         <TextView 10             android:id="@+id/name_tv"11             android:layout_width="wrap_content"12             android:layout_height="wrap_content"13             android:text="姓名:"14             android:textSize="30sp"/>15         <EditText 16             android:id="@+id/ET_name"17             android:layout_width="0dip"18             android:layout_height="wrap_content"19             android:layout_weight="1"20             android:inputType="text"21             android:textSize="20sp">22             <requestFocus></requestFocus>23         </EditText>24     </LinearLayout>25     <LinearLayout 26         android:layout_width="match_parent"27         android:layout_height="wrap_content">28         <TextView 29             android:id="@+id/tv_psd"30             android:layout_height="wrap_content"31             android:layout_width="wrap_content"32             android:text="密码:"33             android:textSize="30sp"/>34         <EditText 35             android:id="@+id/et_psd"36             android:layout_weight="1"37             android:layout_height="wrap_content"38             android:layout_width="0dip"39             android:textSize="20sp"40             android:inputType="textPassword"/>41     </LinearLayout>42     <Button 43         android:id="@+id/bt_login"44         android:layout_height="wrap_content"45         android:layout_width="wrap_content"46         android:text="登陆"47         android:textSize="20sp"/>48 </LinearLayout>

read_data.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <TextView         android:id="@+id/tv_rname"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="30sp"/>    <TextView         android:id="@+id/tv_rpsd"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="30sp"/></LinearLayout>

然后新建两个Activity,分别为ReadActivity和WriteActivity:

 1 public class ReadActivity extends Activity { 2  3     @Override 4     protected void onCreate(Bundle savedInstanceState) { 5         // TODO Auto-generated method stub 6         super.onCreate(savedInstanceState); 7         setContentView(R.layout.read_data); 8         TextView tv_name=(TextView) findViewById(R.id.tv_rname); 9         TextView tv_psd=(TextView) findViewById(R.id.tv_rpsd);10         SharedPreferences sp=getSharedPreferences("test", MODE_PRIVATE);11         tv_name.setText(sp.getString("name", "error_name"));12         tv_psd.setText(sp.getString("psd", "error_psd"));13     }14 15 }
 1 public class WriteActivity extends Activity { 2  3     @Override 4     protected void onCreate(Bundle savedInstanceState) { 5         // TODO Auto-generated method stub 6         super.onCreate(savedInstanceState); 7         setContentView(R.layout.main); 8         final EditText et_name=(EditText) findViewById(R.id.ET_name); 9         final EditText et_psd=(EditText) findViewById(R.id.et_psd);10         Button bt_login=(Button) findViewById(R.id.bt_login);11         bt_login.setOnClickListener(new OnClickListener() {12             13             @Override14             public void onClick(View v) {15                 String name=et_name.getText().toString();16                 String psd=et_psd.getText().toString();17                 SharedPreferences sp_login=getSharedPreferences("test", MODE_PRIVATE);18                 Editor editor=sp_login.edit();19                 editor.putString("name", name);20                 editor.putString("psd", psd);21                 editor.commit();22                 Intent intent=new Intent();23                 intent.setClass(WriteActivity.this, ReadActivity.class);24                 startActivity(intent);25                 26             }27         });28     }29 }

这里记得把配置文件也要修改一下(注册Activity和修改默认启动Activity):

 1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3     package="com.example.demo_base_sharedpreferences" 4     android:versionCode="1" 5     android:versionName="1.0" > 6  7     <uses-sdk 8         android:minSdkVersion="14" 9         android:targetSdkVersion="19" />10 11     <application12         android:allowBackup="true"13         android:icon="@drawable/ic_launcher"14         android:label="@string/app_name"15         android:theme="@style/AppTheme" >16         <activity17             android:name="com.example.demo_base_sharedpreferences.WriteActivity"18             android:label="@string/app_name" >19             <intent-filter>20                 <action android:name="android.intent.action.MAIN" />21 22                 <category android:name="android.intent.category.LAUNCHER" />23             </intent-filter>24         </activity>25         <activity android:name="com.example.demo_base_sharedpreferences.ReadActivity"></activity>26     </application>27 28 </manifest>

代码完毕,运行程序即可体验SharedPreferences在仅在一个项目中的使用情况。

下面来看看第二种(两个不同项目之间的使用),因为很多代码都是相同的,就直接上代码了

创建第一个项目demo_between_SharedPreferences01

main布局文件代码:

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     android:orientation="vertical" > 6     <LinearLayout  7         android:layout_height="wrap_content" 8         android:layout_width="match_parent"> 9         <TextView 10             android:id="@+id/tv_read"11             android:layout_width="wrap_content"12             android:layout_height="wrap_content"13             android:text="全局可读:"14             android:textSize="20sp"/>15         <EditText 16             android:id="@+id/et_read"17             android:layout_width="0dip"18             android:layout_height="wrap_content"19             android:layout_weight="1"20             android:inputType="text"21             android:textSize="20sp"/>22     </LinearLayout>23     <LinearLayout 24         android:layout_height="wrap_content"25         android:layout_width="match_parent">26         <TextView 27             android:id="@+id/tv_write"28             android:layout_width="wrap_content"29             android:layout_height="wrap_content"30             android:text="全局可写:"31             android:textSize="20sp"/>32         <EditText 33             android:id="@+id/et_write"34             android:layout_width="0dip"35             android:layout_height="wrap_content"36             android:layout_weight="1"37             android:inputType="text"38             android:textSize="20sp"/>39     </LinearLayout>40     <LinearLayout 41         android:layout_height="wrap_content"42         android:layout_width="match_parent">43         <TextView 44             android:id="@+id/tv_read_write"45             android:layout_width="wrap_content"46             android:layout_height="wrap_content"47             android:text="全局可读:"48             android:textSize="20sp"/>49         <EditText 50             android:id="@+id/et_read_write"51             android:layout_width="0dip"52             android:layout_height="wrap_content"53             android:layout_weight="1"54             android:inputType="text"55             android:textSize="20sp"/>56     </LinearLayout>57     <Button 58         android:id="@+id/bt_save"59         android:layout_width="wrap_content"60         android:layout_height="wrap_content"61         android:text="保存键值对"62         android:textSize="20sp"/>63 </LinearLayout>
View Code

java文件:

 1     private EditText et_read,et_write,et_read_write; 2     private SharedPreferences sp_read,sp_write,sp_read_write; 3  4     @SuppressLint("WorldReadableFiles") 5     @Override 6     protected void onCreate(Bundle savedInstanceState) { 7         super.onCreate(savedInstanceState); 8         setContentView(R.layout.main); 9         et_read=(EditText) findViewById(R.id.et_read);10         et_write=(EditText) findViewById(R.id.et_write);11         et_read_write=(EditText) findViewById(R.id.et_read_write);12         sp_read=getSharedPreferences("read", MODE_WORLD_READABLE);13         sp_write=getSharedPreferences("write", MODE_WORLD_WRITEABLE);14         sp_read_write=getSharedPreferences("read_write", MODE_WORLD_READABLE+MODE_WORLD_WRITEABLE);15         Button bt_save=(Button) findViewById(R.id.bt_save);16         bt_save.setOnClickListener( save);17     }18     19     public OnClickListener save=new OnClickListener() {20         21         @Override22         public void onClick(View v) {23             Editor ed_read=sp_read.edit();24             Editor ed_write=sp_write.edit();25             Editor ed_read_write=sp_read_write.edit();26             ed_read.putString("test", et_read.getText().toString());27             ed_write.putString("test", et_write.getText().toString());28             ed_read_write.putString("test", et_read_write.getText().toString());29             ed_read.commit();30             ed_write.commit();31             ed_read_write.commit();32             33         }34     };
View Code

创建第二个项目demo_between_SharedPreferences02

main.xml布局文件:

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     android:layout_width="fill_parent" 4     android:layout_height="fill_parent" 5     android:orientation="vertical" > 6     <TextView  7         android:id="@+id/read" 8         android:layout_height="wrap_content" 9         android:layout_width="wrap_content"10         android:textSize="30sp"/>11     <TextView 12         android:id="@+id/write"13         android:layout_height="wrap_content"14         android:layout_width="wrap_content"15         android:textSize="30sp"/>16     <TextView 17         android:id="@+id/read_write"18         android:layout_height="wrap_content"19         android:layout_width="wrap_content"20         android:textSize="30sp"/>21 22 </LinearLayout>
View Code

java文件

 1 private SharedPreferences sp_read,sp_write,sp_read_write; 2     private TextView tv_read,tv_write,tv_read_write; 3  4     @Override 5     protected void onCreate(Bundle savedInstanceState) { 6         super.onCreate(savedInstanceState); 7         setContentView(R.layout.main); 8         tv_read=(TextView) findViewById(R.id.read); 9         tv_write=(TextView) findViewById(R.id.write);10         tv_read_write=(TextView) findViewById(R.id.read_write);11         Context othercontext=null;12         try {13             othercontext=createPackageContext("com.example.demo_between_sharepreferences", MODE_PRIVATE);14         } catch (NameNotFoundException e) {15             // TODO Auto-generated catch block16             e.printStackTrace();17         }18         sp_read=othercontext.getSharedPreferences("read", MODE_WORLD_READABLE);19         sp_write=othercontext.getSharedPreferences("write", MODE_WORLD_WRITEABLE);20         sp_read_write=othercontext.getSharedPreferences("read_write", MODE_WORLD_READABLE+MODE_WORLD_WRITEABLE);21         tv_read.setText("全局可读:"+sp_read.getString("test", "null"));22         tv_write.setText("全局可写:"+sp_write.getString("test", "null"));23         tv_read_write.setText("全局可读可写:"+sp_read_write.getString("test", "null"));24         25     }
View Code

然后运行第一个项目,输入信息,点击保存。

运行第二个项目。则界面上显示了用户刚刚在第一个项目中输入并保存的信息。

2、文件Files对象存储

在Android中,文件对象存储主要有两种方式:

  1. java提供的io流体系。(FileOutputStream类的openFileOutput()方法和FileInputStram类提供的openFileInput()方法)默认情况下,使用IO流保存的文件仅对当前应用程序可见。如果用户卸载了该应用程序,则保存数据的文件也会被一起删除。
  2. 使用Environment类的getExternalStorageDirectory()方法对Android中SD卡的操作。

对文件的操作呢,建议大家可以先看看它的相关文档,如我们会使用到的:

http://developer.android.com/intl/zh-cn/reference/java/io/File.html

接下来我们依然用实例来体验一下吧。

第一种使用java提供的io流体系

本实例的布局文件我们使用讲SharedPreferences的第一种情况时使用的布局文件。(注意:在控件的名称上可能会有改动

然后创建两个Activity:InternalDataWriteActivity和InternalDataReadActivity:

 1 public class InternalDataReadActivity extends Activity { 2  3     protected void onCreate(Bundle savedInstanceState) { 4         super.onCreate(savedInstanceState); // 调用父类方法 5         setContentView(R.layout.result);// 使用布局文件 6         FileInputStream fis = null; 7         byte[] buffer = null; 8         try { 9             fis = openFileInput("login");// 获得文件输入流10             buffer = new byte[fis.available()];// 定义保存数据的数组11             fis.read(buffer);// 从输入流中读取数据12         } catch (FileNotFoundException e) {13             e.printStackTrace();14         } catch (IOException e) {15             e.printStackTrace();16         } finally {17             if (fis != null) {18                 try {19                     fis.close();// 关闭文件输入流20                 } catch (IOException e) {21                     e.printStackTrace();22                 }23             }24         }25 26         TextView usernameTV = (TextView) findViewById(R.id.username);27         TextView passwordTV = (TextView) findViewById(R.id.password);28         String data = new String(buffer);// 获得数组中保存的数据29         String username = data.split(" ")[0];// 获得username30         String password = data.split(" ")[1];// 获得password31         usernameTV.setText("用户名:" + username);// 显示用户名32         passwordTV.setText("密    码:" + password);// 显示密码33     }34 }
View Code
 1 public class InternalDataWriteActivity extends Activity { 2     /** Called when the activity is first created. */ 3     @Override 4     public void onCreate(Bundle savedInstanceState) { 5         super.onCreate(savedInstanceState);// 调用父类方法 6         setContentView(R.layout.main);// 应用布局文件 7         final EditText usernameET = (EditText) findViewById(R.id.username);// 获得用户名控件 8         final EditText passwordET = (EditText) findViewById(R.id.password);// 获得密码控件 9         Button login = (Button) findViewById(R.id.login);// 获得按钮控件10         login.setOnClickListener(new View.OnClickListener() {11 12             @Override13             public void onClick(View v) {14                 String username = usernameET.getText().toString();// 获得用户名15                 String password = passwordET.getText().toString();// 获得密码16                 FileOutputStream fos = null;17                 try {18                     fos = openFileOutput("login", MODE_PRIVATE);// 获得文件输出流19                     fos.write((username + " " + password).getBytes());// 保存用户名和密码20                     fos.flush();// 清除缓存21                 } catch (FileNotFoundException e) {22                     e.printStackTrace();23                 } catch (IOException e) {24                     e.printStackTrace();25                 } finally {26                     if (fos != null) {27                         try {28                             fos.close();// 关闭文件输出流29                         } catch (IOException e) {30                             e.printStackTrace();31                         }32                     }33                 }34                 Intent intent = new Intent();// 创建Intent对象35                 intent.setClass(InternalDataWriteActivity.this, InternalDataReadActivity.class);// 指定跳转到InternalDataReadActivity36                 startActivity(intent);// 实现跳转37             }38         });39     }40 }
View Code

最后注意配置文件的修改:

 1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3     package="com.mingrisoft" 4     android:versionCode="1" 5     android:versionName="1.0" > 6  7     <uses-sdk android:minSdkVersion="15" /> 8  9     <application10         android:icon="@drawable/ic_launcher"11         android:label="@string/app_name" >12         <activity13             android:name="com.mingrisoft.InternalDataWriteActivity"14             android:label="@string/app_name" >15             <intent-filter>16                 <action android:name="android.intent.action.MAIN" />17 18                 <category android:name="android.intent.category.LAUNCHER" />19             </intent-filter>20         </activity>21         <activity android:name="com.mingrisoft.InternalDataReadActivity" />22     </application>23 24 </manifest>
View Code

运行程序,输入数据后,跳转到另一个页面时读取第一个页面的数据。(当然,这种效果也可以使用SharedPreferences)

第二种对安卓的SD卡的操作

修改main.xml布局文件

 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     android:layout_width="fill_parent" 4     android:layout_height="fill_parent" 5     android:background="@drawable/background" 6     android:orientation="vertical" > 7  8     <TextView 9         android:id="@+id/message"10         android:layout_width="wrap_content"11         android:layout_height="wrap_content"12         android:textColor="@android:color/white"13         android:textSize="20dp" />14 15 </LinearLayout>
View Code

然后创建一个Activity类:

 1 public class FileCreateActivity extends Activity { 2     /** Called when the activity is first created. */ 3     @Override 4     public void onCreate(Bundle savedInstanceState) { 5         super.onCreate(savedInstanceState);// 调用父类方法 6         setContentView(R.layout.main);// 应用布局文件 7         TextView tv = (TextView) findViewById(R.id.message); 8         File root = Environment.getExternalStorageDirectory();// 获得SD卡根路径 9         if(root.exists()&&root.canWrite()){10             File file = new File(root, "DemoFile.txt");11             try {12                 if (file.createNewFile()) {13                     tv.setText(file.getName() + "创建成功!");14                 } else {15                     if(file.exists()){16                         file.delete();17                         tv.setText("已删除同名文件,请重新创建。");18                     }19                     else20                     tv.setText(file.getName() + "创建失败!");21                     22                 }23                 24             } catch (IOException e) {25                 e.printStackTrace();26             }27         }else {28             tv.setText("SD卡不存在或者不可写!");29         }30     }31 }
View Code

最后在配置文件中添加权限和修改默认Activity:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<activity
android:name="com.mingrisoft.FileCreateActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>
</activity>

此时,即可运行程序。

3、SQLite的数据库存储

Android系统自带有轻量级的数据库—SQLite。它与我们所接触其他数据库大部分都相同,支持大部分的标准SQL语句,分页查询和mysql相同

select * from person(表名) LIMIT 10,20(第10条索引开始,取20条数据)。

另外,它还有个需要注意的地方,那就是不区分数据类型(主键除外)

光说知识点比较空洞,下面我们用一个例子来认识sqlite,在例子中会用注释来解释一些sqlite的知识

不多说直接上代码:

新建一个DBOpenHelper类,并继承SQLiteOpenHelper:

 1 package cn.itcast.sqlite; 2  3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6  7 public class DBOpenHelper extends SQLiteOpenHelper {    // 定义工具类, 继承SQLiteOpenHelper 8      9     public DBOpenHelper(Context context) {                // 创建对象的时候, 需要传入上下文环境10         super(context, "itcast.db", null, 4);11         /*12          * 由于父类没有无参构造函数, 必须显式调用有参的构造函数13          * 参数1: 上下文环境, 用来确定数据库文件存储的目录14          * 参数2: 数据库文件的名字15          * 参数3: 生成游标的工厂, 填null就是使用默认的16          * 参数4: 数据库的版本, 从1开始17          */18     }19 20     @Override21     public void onCreate(SQLiteDatabase db) {22         System.out.println("onCreate");23         db.execSQL("CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))");        // 执行SQL语句, 创建表24     }25 26     @Override27     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {28         System.out.println("onUpgrade");29         db.execSQL("ALTER TABLE person ADD balance INTEGER");30     }31 32 }
View Code

创建一个实体类person,接下来的例子中会使用到:

在创建时,get,set方法和一些构造函数可以通过选择菜单栏或点击鼠标右键出现的source选项中选择快速生成。

 1 package cn.itcast.sqlite; 2  3 public class Person { 4     private Integer id; 5     private String name; 6     private Integer balance; 7  8     public Person() { 9         super();10     }11 12     public Person(String name, Integer balance) {13         super();14         this.name = name;15         this.balance = balance;16     }17 18     public Person(Integer id, String name, Integer balance) {19         super();20         this.id = id;21         this.name = name;22         this.balance = balance;23     }24 25     public Integer getId() {26         return id;27     }28 29     public void setId(Integer id) {30         this.id = id;31     }32 33     public String getName() {34         return name;35     }36 37     public void setName(String name) {38         this.name = name;39     }40 41     public Integer getBalance() {42         return balance;43     }44 45     public void setBalance(Integer balance) {46         this.balance = balance;47     }48 49     @Override50     public String toString() {51         return "Person [id=" + id + ", name=" + name + ", balance=" + balance + "]";52     }53 54 }
View Code

下面创建一个操作sql语句的PersonDao类:

该类中,包含了最常用的sql语句,其中的注释的地方希望大家理解意思。

 1 package cn.itcast.sqlite; 2  3 import java.util.ArrayList; 4 import java.util.List; 5  6 import android.content.Context; 7 import android.database.Cursor; 8 import android.database.sqlite.SQLiteDatabase; 9 10 public class PersonDao {11     private DBOpenHelper helper;12     13     public PersonDao(Context context) {14         helper = new DBOpenHelper(context);15     }16 17     public void insert(Person p) {18         SQLiteDatabase db = helper.getWritableDatabase();    // 获取数据库连接(可写的)19         db.execSQL("INSERT INTO person(name, balance) VALUES(?, ?)", new Object[] { p.getName(), p.getBalance() });        // 执行SQL语句, 插入20         db.close();21     }22     23     public void delete(int id) {24         SQLiteDatabase db = helper.getWritableDatabase();25         db.execSQL("DELETE FROM person WHERE id=?", new Object[] { id });26         db.close();27     }28 29     public void update(Person p) {30         SQLiteDatabase db = helper.getWritableDatabase();31         db.execSQL("UPDATE person SET name=?, balance=? WHERE id=?", new Object[] { p.getName(), p.getBalance(), p.getId() });32         db.close();33     }34     35     public Person query(int id) {36         SQLiteDatabase db = helper.getReadableDatabase();            // 获取数据库连接(可读的)37         Cursor c = db.rawQuery("SELECT name, balance FROM person WHERE id=?", new String[] { id + "" });    // 执行SQL语句, 查询, 得到游标38         Person p = null;39         if (c.moveToNext()) {                                        // 判断游标是否包含下一条记录, 如果包含将游标向后移动一位40             String name = c.getString(c.getColumnIndex("name"));    // 获取"name"字段的索引, 然后根据索引获取数据41             int balance = c.getInt(1);                                // 获取1号索引上的数据42             p = new Person(id, name, balance);    43         }44         c.close();45         db.close();46         return p;47     }48     49     public List<Person> queryAll() {50         SQLiteDatabase db = helper.getReadableDatabase();                    51         Cursor c = db.rawQuery("SELECT id, name, balance FROM person", null);    52         List<Person> persons = new ArrayList<Person>();53         while (c.moveToNext()) {                                        54             Person p = new Person(c.getInt(0), c.getString(1), c.getInt(2));55             persons.add(p);56         }57         c.close();58         db.close();59         return persons;60     }61     62     public int queryCount() {63         SQLiteDatabase db = helper.getReadableDatabase();                    64         Cursor c = db.rawQuery("SELECT COUNT(*) FROM person", null);    65         c.moveToNext();66         int count = c.getInt(0);67         c.close();68         db.close();69         return count;70     }71     72     public List<Person> queryPage(int pageNum, int capacity) {        73         String offset = (pageNum - 1) * capacity + "";        // 偏移量74         String len = capacity + "";                            // 个数75         SQLiteDatabase db = helper.getReadableDatabase();                    76         Cursor c = db.rawQuery("SELECT id, name, balance FROM person LIMIT ?,?", new String[]{offset , len});    77         List<Person> persons = new ArrayList<Person>();78         while (c.moveToNext()) {                                        79             Person p = new Person(c.getInt(0), c.getString(1), c.getInt(2));80             persons.add(p);81         }82         c.close();83         db.close();84         return persons;85     }86     87 }
View Code

最后,我们将用单元测试类来检验我们做得是否正确(注意,不要忘记在配置文件中注册Junit的使用(详见《Android Junit单元测试》一文)):

 1 package cn.itcast.sqlite; 2  3 import java.util.List; 4 import java.util.Random; 5  6 import android.test.AndroidTestCase; 7  8 public class DBTest extends AndroidTestCase { 9 10     public void testCreateDatabase() {11         DBOpenHelper helper = new DBOpenHelper(getContext());12         helper.getWritableDatabase();    13         /*14          * 获取可写的数据连接15          * 数据库文件不存在时, 会创建数据库文件, 并且执行onCreate()方法16          * 数据库文件存在, 并且版本没有改变时, 不执行任何方法17          * 数据库文件存在, 版本提升, 执行onUpgrade()方法18          */19     }20     21     public void testInsert() {22         PersonDao dao = new PersonDao(getContext());23         for (int i = 1; i <= 100; i++)24             dao.insert(new Person("Test" + i, new Random().nextInt(10000)));25     }26     27     public void testDelete() {28         PersonDao dao = new PersonDao(getContext());29         dao.delete(1);30     }31     32     public void testUpdate() {33         PersonDao dao = new PersonDao(getContext());34         dao.update(new Person(3, "王五", 30000));35     }36     37     public void testQuery() {38         PersonDao dao = new PersonDao(getContext());39         System.out.println(dao.query(3));40     }41     42     public void testQueryAll() {43         PersonDao dao = new PersonDao(getContext());44         List<Person> persons = dao.queryAll();45         for (Person p : persons)46             System.out.println(p);47     }48     49     public void testQueryCount() {50         PersonDao dao = new PersonDao(getContext());51         System.out.println(dao.queryCount());52     }53     54     public void testQueryPage() {55         PersonDao dao = new PersonDao(getContext());56         List<Person> persons = dao.queryPage(3, 20);57         for (Person p : persons)58             System.out.println(p);59     }60     61 }
View Code

运行程序即可。(该例使用的是System.out输出结果,为方便查看建议add a new logcte filter)

上面是sqlite的最常规和最基本的操作。

下面我们来看看sqlite的一些其他操作:

1、数据库事务的操作。不多说,直接上代码:

在PersonDao类中,添加一个新的方法:(前两个参数代表的是数据库中的ID字段)

 1 public void remit(int from, int to, int amount) { 2         SQLiteDatabase db = helper.getWritableDatabase(); 3         try { 4             db.beginTransaction();            // 开始事务 5             db.execSQL("UPDATE person SET balance=balance-? WHERE id=?", new Object[] { amount, from }); 6             db.execSQL("UPDATE person SET balance=balance+? WHERE id=?", new Object[] { amount, to }); 7             db.setTransactionSuccessful();    // 设置成功点, 在事务结束时, 成功点之前的操作会被提交 8             /*若此处再接下面的三行代码 9             db.execSQL("……");                //如果此行的代码出现异常,那么上面的(即前面的)两个execSQL()执行的SQL语句可以正常执行,此行和下面的execSQL()将不会被执行。10             db.execSQL("……");                //如果只有此行代码异常,那么最上面的(即前面的)两个execSQL()执行的SQL语句可以正常执行,此行和上面的execSQL()将不会被执行。11             db.setTransactionSuccessful();12             */13         } finally {14             db.endTransaction();            // 结束事务, 将成功点之前的操作提交15             db.close();16         }17     }
View Code

在DBtest单元测试类中,测试刚刚添加的有关事务的方法:

1 public void testRemit() {2         PersonDao dao = new PersonDao(getContext());3         dao.remit(3, 2, 1000);4     }
View Code

2、另一种数据操作(增删查改)的方式

这种方式呢,不需要写SQL语句。但是,它的实质是转换成sql语句再执行。在某些情况下呢,对数据的操作会更加方便。

下面,我们就将PersonDao类用新的数据操作的方式来实现一下,大家可以对比一下与之前的PersonDao类的区别,其实真正关键的、不同的代码就那么几句,大部分还是相同的。

  1 package cn.itcast.sqlite;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.content.ContentValues;  7 import android.content.Context;  8 import android.database.Cursor;  9 import android.database.sqlite.SQLiteDatabase; 10  11 public class PersonDao { 12     private DBOpenHelper helper; 13      14     public PersonDao(Context context) { 15         helper = new DBOpenHelper(context); 16     } 17  18     public void insert(Person p) { 19         SQLiteDatabase db = helper.getWritableDatabase();    // 获取数据库连接(可写的) 20         ContentValues values = new ContentValues();            // 类似于Map的容器, 键是String, 用来存放列名, 值是Object, 用来存要插入的数据 21         values.put("name", p.getName());                    // 某些情况下, 程序会接收一个ContentValues参数, 这时用这种方式存储比较方便 22         values.put("balance", p.getBalance()); 23         long id = db.insert("person", null, values);        // 第二个参数随便写表中的一个列名即可, 用来在想插入一条除了主键全部为空的记录时使用 24         System.out.println("插入的记录的id是: " + id); 25         db.close(); 26     } 27      28     public void delete(int id) { 29         SQLiteDatabase db = helper.getWritableDatabase(); 30         int rows = db.delete("person", "id=?", new String[] { id + "" }); 31         System.out.println("删除了" + rows + "行"); 32         db.close(); 33     } 34  35     public void update(Person p) { 36         SQLiteDatabase db = helper.getWritableDatabase(); 37         ContentValues values = new ContentValues(); 38         values.put("name", p.getName()); 39         values.put("balance", p.getBalance()); 40         int rows = db.update("person", values, "id=?", new String[] { p.getId() + "" }); 41         System.out.println("更新了" + rows + "行"); 42         db.close(); 43     } 44      45     public Person query(int id) { 46         SQLiteDatabase db = helper.getReadableDatabase();            // 获取数据库连接(可读的) 47         Cursor c = db.query("person", new String[] { "name", "balance" }, "id=?", new String[] { id + "" }, null, null, null); 48         Person p = null; 49         if (c.moveToNext()) {                                        // 判断游标是否包含下一条记录, 如果包含将游标向后移动一位 50             String name = c.getString(c.getColumnIndex("name"));    // 获取"name"字段的索引, 然后根据索引获取数据 51             int balance = c.getInt(1);                                // 获取1号索引上的数据 52             p = new Person(id, name, balance);     53         } 54         c.close(); 55         db.close(); 56         return p; 57     } 58      59     public List<Person> queryAll() { 60         SQLiteDatabase db = helper.getReadableDatabase();                     61         Cursor c = db.query("person", null, null, null, null, null, "id DESC"); 62         List<Person> persons = new ArrayList<Person>(); 63         while (c.moveToNext()) {                                         64             Person p = new Person(c.getInt(0), c.getString(1), c.getInt(2)); 65             persons.add(p); 66         } 67         c.close(); 68         db.close(); 69         return persons; 70     } 71      72     public int queryCount() { 73         SQLiteDatabase db = helper.getReadableDatabase();                     74         Cursor c = db.query("person", new String[]{ "COUNT(*)" }, null, null, null, null, null);     75         c.moveToNext(); 76         int count = c.getInt(0); 77         c.close(); 78         db.close(); 79         return count; 80     } 81      82     public List<Person> queryPage(int pageNum, int capacity) {         83         String offset = (pageNum - 1) * capacity + "";        // 偏移量 84         String len = capacity + "";                            // 个数 85         SQLiteDatabase db = helper.getReadableDatabase();                     86         Cursor c = db.query("person", null, null, null, null, null, null, offset + "," + len);     87         List<Person> persons = new ArrayList<Person>(); 88         while (c.moveToNext()) {                                         89             Person p = new Person(c.getInt(0), c.getString(1), c.getInt(2)); 90             persons.add(p); 91         } 92         c.close(); 93         db.close(); 94         return persons; 95     } 96      97     public void remit(int from, int to, int amount) { 98         SQLiteDatabase db = helper.getWritableDatabase(); 99         try {100             db.beginTransaction();            // 开始事务101             db.execSQL("UPDATE person SET balance=balance-? WHERE id=?", new Object[] { amount, from });102             db.execSQL("UPDATE person SET balance=balance+? WHERE id=?", new Object[] { amount, to });103             db.setTransactionSuccessful();    // 设置成功点, 在事务结束时, 成功点之前的操作会被提交104         } finally {105             db.endTransaction();            // 结束事务, 将成功点之前的操作提交106             db.close();107         }108     }109     110 }
View Code

更多相关文章

  1. Android(安卓)XmlSerializer 换行
  2. Android中的下拉列表-自定义选项界面样式
  3. Mms模块ConversationList流程分析
  4. 实现Android(安卓)获取cache缓存的目录路径的方法
  5. Android中自制通讯录中显示出数据库中的姓名和电话号码进行打电
  6. Android(安卓)获取sdcard音乐文件
  7. Android判断后台服务是否开启的两种方法实例详解
  8. Andorid Dialog万能去黑边去白底方法
  9. 方法数据库android轻量型数据库sqlite的使用方法汇总

随机推荐

  1. 覆盖odoo 8中的JS函数
  2. 八款Js框架介绍及比较,Dojo 、Scriptacul
  3. javascripterror 为空或不是对象.
  4. 使用js更改抛出事件的输入值
  5. 多选列表框功能
  6. Angular 2快速入门 - 我的应用程序组件未
  7. des加解密(JavaScript&Java)
  8. javascript的数据类型,以及javascript中类
  9. 如何在Node中创建可重用的函数而不编写样
  10. 市委组织部考核项目——多条数据的提交