Android數據持久化篇

一.文件操做篇

主要經過流來完成java

  獲得輸出流對象FileOutputStream:經過Context的openFileOuput("文件名",模式)方法獲取android

    文件路徑:/data/data/<包名>/files/  存放在這個目錄下
    模式有二:Activity.MODE_PRIVATE覆蓋;Activity.MODE_APPEND——追加程序員

  獲得輸入流對象FileInputStream:經過Context的openFileInput("文件名")返回一個輸入流對象sql

    會自動在路徑:/data/data/<包名>/files/  下找到要讀取的文件名shell

 

  接下來的操做即爲java的IO操做技術!數據庫

貼入一段小代碼app

  1 package com.example.filepersistencetest;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.BufferedWriter;
  5 import java.io.FileInputStream;
  6 import java.io.FileOutputStream;
  7 import java.io.InputStreamReader;
  8 import java.io.OutputStreamWriter;
  9 
 10 import android.app.Activity;
 11 import android.os.Bundle;
 12 import android.util.Log;
 13 import android.view.View;
 14 import android.view.View.OnClickListener;
 15 import android.widget.Button;
 16 import android.widget.EditText;
 17 
 18 public class MainActivity extends Activity implements OnClickListener {
 19     private EditText editText;
 20     private Button sava_button;
 21     private Button read_button;
 22 
 23     @Override
 24     protected void onCreate(Bundle savedInstanceState) {
 25         super.onCreate(savedInstanceState);
 26         setContentView(R.layout.activity_main);
 27         editText = (EditText) findViewById(R.id.edit);
 28         sava_button = (Button) findViewById(R.id.save);
 29         read_button = (Button) findViewById(R.id.read);
 30 
 31         // 綁定單擊事件
 32         sava_button.setOnClickListener(this);
 33         read_button.setOnClickListener(this);
 34 
 35     }
 36 
 37     @Override
 38     public void onClick(View v) {
 39         // 監聽
 40         switch (v.getId()) {
 41         case R.id.save:
 42             save();
 43             break;
 44         case R.id.read:
 45             read();
 46             break;
 47 
 48         default:
 49             break;
 50         }
 51 
 52     }
 53 
 54     public void save() {
 55         String inputText = editText.getText().toString();
 56         BufferedWriter bufw = null;
 57         FileOutputStream out = null;
 58         // 獲得輸出流 Context->openFileOutput("文件名",寫出模式——覆蓋Private或者追加append)
 59         // 返回FileOutputStream對象
 60         try {
 61 
 62             out = openFileOutput("my_data.txt", Activity.MODE_PRIVATE);
 63             bufw = new BufferedWriter(new OutputStreamWriter(out));
 64             bufw.write(inputText);
 65             Log.d("test", inputText);
 66             bufw.flush();
 67             editText.setText("");
 68         } catch (Exception e) {
 69             throw new RuntimeException("打開文件異常!!");
 70         } finally {
 71             try {
 72                 if (null != bufw)
 73                     bufw.close();
 74             } catch (Exception e2) {
 75                 throw new RuntimeException("關閉流失敗");
 76             }
 77         }
 78     }
 79 
 80     public void read() {
 81         editText.setText("");
 82         FileInputStream in = null;
 83         BufferedReader bur = null;
 84         try {
 85             in = openFileInput("my_data.txt");
 86             bur = new BufferedReader(new InputStreamReader(in));
 87             String line = null;
 88             boolean flag = false;
 89             while ((line = bur.readLine()) != null) {
 90                 if (flag)
 91                     editText.append("\n" + line);//
 92                 else {
 93                     editText.append(line);
 94                     flag=true;
 95                 }
 96             }
 97         } catch (Exception e) {
 98             // TODO: handle exception
 99         } finally {
100             try {
101                 bur.close();
102             } catch (Exception e2) {
103                 // TODO: handle exception
104             }
105         }
106 
107     }
108 
109 }
filepersistence

 另外補充兩點編輯器

  a.TextUtils.isEmpty(inputText)——文本工具類,雙重判空
  b.edit.setSelection(inputText.length())——設置光標到末尾ide

二.xml存儲篇——SharedPreferences

  文件操做方式有點相似於無腦讀,無腦寫工具

  而SharedPreferences則將數據分類的比較好,能夠作到存什麼類型就讀什麼類型,以鍵值對的方式存儲

  一般映射關係簡單的時候,用SharedPreferences是比較合適的

 

  存儲路徑:/data/data/<packagename>/shared_prefs/目錄下
  A.獲取SharedPreferences,三種方法
  a.Context 的 getSharedPreferences("文件名",模式)——若是指定的文件不存在,則會自動建立
    MODE_PRIVATE(=0,默認,只有當前應用程序能夠訪問)
    MODE_MULTI_PROCESS,用於多個進程多同一個SharedPreferences進行訪問
  b.Activity 的 getPreferences(模式) 會自動將當前活動的類名做爲SharedPreferences文件名
  c.PreferenceManager 的 靜態getDefaultSharedPreferences(Context)——自動使用當前應用程序名稱做爲文件名的前綴
  B.寫
  a.得到編輯器 經過SharedPreferences對象的edit()方法獲取一個SharedPreferences.Editor對象
  b.經過編輯器寫數據 putBoolean putString ==
  c.提交 commit()

代碼示例:

 1         saveButton.setOnClickListener(new OnClickListener() {
 2             
 3             @Override
 4             public void onClick(View v) {
 5                 // Context獲取SharedPreferences對象,建立編輯器
 6                 SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
 7                 // put內容
 8                 editor.putString("name", "二哥");
 9                 editor.putInt("age", 22);
10                 editor.putBoolean("married", false);
11                 // 提交
12                 editor.commit();
13             }
14         });
 1         getButton.setOnClickListener(new OnClickListener() {
 2             
 3             @Override
 4             public void onClick(View v) {
 5                 SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);
 6                 String name = pref.getString("name", "null");
 7                 int age = pref.getInt("age", 0);
 8                 boolean married = pref.getBoolean("married", false);
 9                 
10                 Toast.makeText(MainActivity.this, name+"::"+age+"::"+married, Toast.LENGTH_LONG).show();
11             }
12         });

 

記住密碼功能實現——參看BroadcastBestPractice

a.定義一個控制器ActivityController管理全部的活動:包括增長,移除活動和銷燬全部活動,經過一個List承載

 1 package com.example.broadcastbestpractic;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import android.app.Activity;
 7 
 8 /**
 9  * 活動控制器
10  * 1.添加活動
11  * 2.刪除活動
12  * 3.銷燬全部活動
13  */
14 public class ActivityController {
15     public static List<Activity> activities = new ArrayList<Activity>();
16     public static void addActivity(Activity activity ){
17         activities.add(activity);
18     }
19     public static void removeActivity(Activity activity ){
20         
21         activities.remove(activity);
22     }
23     public static void finishAll(){
24         for(Activity activity:activities){
25             activity.finish();
26         }
27     }
28 }
ActivityController

 

b.定義一個基類繼承Activity,改類的onCreate和onDestory方法分別實現增長和移除活動

 1 package com.example.broadcastbestpractic;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 
 6 public class BaseActivity extends Activity {
 7 
 8     @Override
 9     protected void onCreate(Bundle savedInstanceState) {
10         // TODO Auto-generated method stub
11         super.onCreate(savedInstanceState);
12         ActivityController.addActivity(this);
13     }
14 
15     @Override
16     protected void onDestroy() {
17         // TODO Auto-generated method stub
18         super.onDestroy();
19         ActivityController.removeActivity(this);
20     }
21     
22 }
BaseActivity

c.主界面MainActivity,具備Button,用於發送強制下線廣播

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context="com.example.broadcastbestpractic.MainActivity" >
10 
11     <Button 
12         android:id="@+id/force_offline"
13         android:layout_width="match_parent"
14         android:layout_height="wrap_content"
15         android:text="Send a force offline broadcast"
16         android:gravity="center"
17         />
18 
19 </RelativeLayout>
activity_main.xml
 1 package com.example.broadcastbestpractic;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Button;
 9 
10 
11 public class MainActivity extends Activity {
12 
13     @Override
14     protected void onCreate(Bundle savedInstanceState) {
15         super.onCreate(savedInstanceState);
16         setContentView(R.layout.activity_main);
17         
18         Button offLine_btn = (Button) findViewById(R.id.force_offline);
19         offLine_btn.setOnClickListener(new OnClickListener() {
20             
21             @Override
22             public void onClick(View v) {
23                 // 發送輕質下線廣播                
24                 Intent intent = new Intent("com.example.broadcastbestpractic.FORCE_OFFLINE");
25                 
26                 sendBroadcast(intent);
27                 
28             }
29         });
30     }
31 
32 }
MainActivity

d.登陸界面LoginActivity,登陸成功則跳轉至主界面

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:stretchColumns="1"
 6      >
 7     
 8     <TableRow >
 9         <TextView
10             android:layout_height="wrap_content"
11             android:text="Account:"
12              />
13         <EditText
14             android:id="@+id/account"
15             android:layout_height="wrap_content"
16             android:hint="admin 123456"
17              />
18     </TableRow>
19     
20     <TableRow >
21         <TextView
22             android:layout_height="wrap_content"
23             android:text="Password:"
24              />
25         <EditText
26             android:id="@+id/password"
27             android:layout_height="wrap_content"
28             android:inputType="textPassword"
29              />
30     </TableRow>
31     <TableRow >
32         <CheckBox 
33             android:id="@+id/remember_pass"
34             android:layout_height="wrap_content"
35             android:layout_gravity="right"
36             android:layout_marginRight="10dp"
37             />
38         <TextView
39             android:layout_height="wrap_content"
40             android:layout_gravity="center_vertical"
41             android:text="Remenbered password"
42              />
43     </TableRow>
44     <TableRow >
45         <Button 
46             android:id="@+id/login"
47             android:text="login"
48             android:layout_span="2"
49             />
50         
51     </TableRow>
52 
53 </TableLayout>
login.xml
 1 package com.example.broadcastbestpractic;
 2 
 3 import android.content.Intent;
 4 import android.content.SharedPreferences;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Button;
 9 import android.widget.CheckBox;
10 import android.widget.EditText;
11 import android.widget.Toast;
12 
13 public class LoginActivity extends BaseActivity {
14     private EditText accoutnEdit;
15     private EditText passwordEdit;
16     private Button loginButton;
17     private CheckBox rememberBox;
18 
19 
20     private SharedPreferences pref;
21     private SharedPreferences.Editor editor;
22     @Override
23     protected void onCreate(Bundle savedInstanceState) {
24         super.onCreate(savedInstanceState);
25         
26         setContentView(R.layout.login);
27         
28         loginButton = (Button) findViewById(R.id.login);
29         accoutnEdit = (EditText) findViewById(R.id.account);
30         passwordEdit = (EditText) findViewById(R.id.password);
31         rememberBox = (CheckBox) findViewById(R.id.remember_pass);
32         
33         /* 在登陸界面建立的時候,先讀取xml文件,看複選框的值是否爲true
34          * 若是爲true,複選框狀態改成true,帳號密碼的內容設置爲xml文件的帳號密碼
35          * 不爲true,則無論
36          */
37         // 獲取checkbox的值
38         pref = getSharedPreferences("data", MODE_PRIVATE);
39         Boolean isRemember = pref.getBoolean("isRemember", false);
40         
41         if(isRemember){
42             accoutnEdit.setText(pref.getString("account", ""));
43             passwordEdit.setText(pref.getString("password", ""));
44             
45             // 注意設置選中的語句爲 setChecked(true)
46             rememberBox.setChecked(true);
47         }
48         
49         loginButton.setOnClickListener(new OnClickListener() {
50             
51             @Override
52             public void onClick(View v) {
53                 // 驗證成功則跳轉至主界面,失敗者提示帳號密碼不正確
54                 if("admin".equals(accoutnEdit.getText().toString())&&"123456".equals(passwordEdit.getText().toString())){
55                     // 記錄帳號
56                     editor = getSharedPreferences("data", MODE_PRIVATE).edit();
57                     // 若是選中,則上傳
58                     if(rememberBox.isChecked()){ 
59                         editor.putBoolean("isRemember", true);
60                         editor.putString("account", "admin");
61                         editor.putString("password", "123456");
62                         
63                     }else {
64                         // 若是未選中,則清除,若是不清除,依然會記住密碼
65                         // 可用的方案二是,若是不清除,能夠吧isRemember這個值設置爲false,就不用大範圍清空數據
66                         editor.clear();
67                     }
68                     editor.commit();
69                     
70                     Intent intent = new Intent(LoginActivity.this,MainActivity.class);
71                     
72                     startActivity(intent);
73                 }else {
74                     Toast.makeText(LoginActivity.this, "account or password is not corret", Toast.LENGTH_SHORT).show();
75                 }
76                 
77             }
78         });
79     }
80 }
LoginActivity

e.靜態廣播接收器,用於接收強制下線廣播,收到後銷燬全部活動,彈出AlertDialog,提示從新登陸

 1 package com.example.broadcastbestpractic;
 2 
 3 import android.app.AlertDialog;
 4 import android.content.BroadcastReceiver;
 5 import android.content.Context;
 6 import android.content.DialogInterface;
 7 import android.content.DialogInterface.OnClickListener;
 8 import android.content.Intent;
 9 import android.view.WindowManager;
10 /**
11  * 
12  * 靜態註冊一個廣播接收器,用於銷燬活動和開啓活動
13  */
14 public class OfflineReceiver extends BroadcastReceiver {
15 
16     @Override
17     public void onReceive(final Context context, Intent intent) {
18         // 銷燬活動
19         ActivityController.finishAll();
20         // 彈出對話框
21         AlertDialog.Builder alerBuilder = new AlertDialog.Builder(context);
22         alerBuilder.setTitle("Warnning!");
23         alerBuilder.setMessage("You are forced line , plese try to login agin.");
24         alerBuilder.setCancelable(false);
25         alerBuilder.setPositiveButton("OK", new OnClickListener() {
26             
27             @Override
28             public void onClick(DialogInterface dialog, int which) {
29                 // 銷燬全部活動
30                 ActivityController.finishAll();
31                 // 重啓登陸
32                 Intent intent = new Intent(context, LoginActivity.class);
33                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
34                 context.startActivity(intent);
35             }
36         });
37         
38         AlertDialog dialog = alerBuilder.create();
39         
40         // dialog 建立好了,必需要讓其顯示,而且屏蔽home鍵
41         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
42         dialog.show();
43         
44 
45     }
46 
47 }
OfflineReceiver

f.Manifest註冊,LoginActivity(入口),MainActivity(主界面),靜態廣播

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.example.broadcastbestpractic"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6 
 7     <uses-sdk
 8         android:minSdkVersion="14"
 9         android:targetSdkVersion="19" />
10 
11     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
12 
13     <application
14         android:allowBackup="true"
15         android:icon="@drawable/ic_launcher"
16         android:label="@string/app_name"
17         android:theme="@style/AppTheme" >
18         <activity
19             android:name=".LoginActivity"
20             android:label="@string/app_name" >
21             <intent-filter>
22                 <action android:name="android.intent.action.MAIN" />
23 
24                 <category android:name="android.intent.category.LAUNCHER" />
25             </intent-filter>
26         </activity>
27         <activity android:name=".MainActivity" >
28         </activity>
29         <receiver android:name="com.example.broadcastbestpractic.OfflineReceiver">
30             <intent-filter >
31                 <action android:name="com.example.broadcastbestpractic.FORCE_OFFLINE"/>
32             </intent-filter>
33         </receiver>
34     </application>
35 
36 </manifest>
AndroidManifest.xml

 

 

注意:

  a.Receiver中彈出對話框的步驟以及須要的權限
  b.Manifest中要聲明權限 android.permission.SYSTEM_ALERT_WINDOW,由於須要對話框一直存活直到點擊從新ok從新登陸

三.sqlite數據庫篇

首先得知道的事情:

1.當數據映射覆雜的時候,必然會用到數據庫

2.Android內置輕量級數據庫sqlite,路徑在/system/xbin/sqlite3

3.程序中建立的數據庫地址:/data/data/<包名>/databases/目錄下

4.用實現抽象類SQLiteOpenHelper的子類對象XXX來建立和升級數據庫

5.用XXX.getReadableDatabase()或XXX.getWritableDatabase()獲取SQLiteDatabase對象YYY

6.經過YYY進行數據的增刪改查

補充下cmd下sqlite測試操做

C:\Users\joho>adb shell

 $ su

 # cd /data/data/com.example.databasetest/databases

 # sqlite3 BookStore.db

 sqlite>.table

 sqlite>.schema

 sqlite>select * from Book;

 sqlite>.quit

 ... 

1.建立數據庫

23.sqLiteOpenHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
38.sqLiteOpenHelper.getWritableDatabase();

 

2.增

 1         addDataButton.setOnClickListener(new OnClickListener() {
 2             
 3             @Override
 4             public void onClick(View v) {
 5                 // SQLiteOpenHelper的getWritableDatabase和getReadableDatab會返回一個SQLiteDatabase對象
 6                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
 7 //                public long insert(String table, String nullColumnHack, ContentValues values)
 8                 ContentValues values = new ContentValues();
 9                 values.put("author", "erge");
10                 values.put("price", "88.8");
11                 values.put("pages", "1");
12                 values.put("name", "程序員的自我修養");
13                 db.insert("Book", null, values);// 插入一條數據
14                 
15                 values.clear();  // 準備插入第二條
16                 values.put("author", "erge");
17                 values.put("price", "888.8");
18                 values.put("pages", "2");
19                 values.put("name", "程序員的將來");
20                 db.insert("Book", null, values); //插入第二條
21                 
22             }
23         });

 

3.改

 1         updateButton.setOnClickListener(new OnClickListener() {
 2             
 3             @Override
 4             public void onClick(View v) {
 5                 // TODO Auto-generated method stub
 6                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
 7 //                 public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
 8 //                (表名,值,where,where的值)
 9                 ContentValues values = new ContentValues();
10                 values.put("name", "the self_improvement of developer");
11                 db.update("Book", values, "name = ?", new String[]{"程序員的自我修養"});
12                 
13                 values.clear();
14                 values.put("name", "the future of developer");
15                 db.update("Book", values, "name = ?", new String[]{"程序員的將來"});
16                 Toast.makeText(MainActivity.this, "update sucess", Toast.LENGTH_SHORT).show();
17             }
18         });

 

4.刪

 1         deleteButton.setOnClickListener(new OnClickListener() {
 2             
 3             @Override
 4             public void onClick(View v) {
 5                 // 
 6                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
 7 //                public int delete(String table, String whereClause, String[] whereArgs)
 8                 db.delete("Book", "pages > ?", new String[]{"1"});
 9             }
10         });

 

5.查

 1         // 查詢最爲複雜,參數較多,獲得的結果保存在遊標——Cursor對象中
 2         queryButton.setOnClickListener(new OnClickListener() {
 3             
 4             @Override
 5             public void onClick(View v) {
 6                 // TODO Auto-generated method stub
 7                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
 8 //                public Cursor query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy) 
 9                 //columns用於約束查詢哪幾列,不指定則查所有
10                 //selection,selectionArgs用來約束查詢哪些行,不指定則所有;
11                 //groupBy指定須要group by的列,不指定則對結果進行group by處理;
12                 //having用於對以前group by的數據進一步過濾,不指定則不過濾;orderBy對結果進行排序,不指定則默認排序
13                 
14                 // 遍歷得結果會存儲到一個Course對象中,經過遍歷這個對象,來輸出數據
15                 Cursor cursor = db.query("Book",null,null,null,null,null,null);
16                 if(cursor.moveToFirst()){
17                     do {
18                         String author = cursor.getString(cursor.getColumnIndex("author"));
19                         Double price = cursor.getDouble(cursor.getColumnIndex("price"));
20                         int pages = cursor.getInt(cursor.getColumnIndex("pages"));
21                         String name = cursor.getString(cursor.getColumnIndex("name"));
22                         Log.d("test", "name::"+name);
23                         Log.d("test", "pages::"+pages);
24                         Log.d("test", "price::"+price);
25                         Log.d("test", "author::"+author);
26                     } while (cursor.moveToNext());
27                 }
28                 cursor.close();
29             }
30         });

 

 

DatabaseTest代碼

主佈局

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6 
 7     <Button 
 8         android:id="@+id/create"
 9         android:layout_height="wrap_content"
10         android:layout_width="match_parent"
11         android:text="create database BookStore.db"
12         />
13 
14     <Button 
15         android:id="@+id/add_data"
16         android:layout_height="wrap_content"
17         android:layout_width="match_parent"
18         android:text="Add data"
19         />
20     <Button 
21         android:id="@+id/update_data"
22         android:layout_height="wrap_content"
23         android:layout_width="match_parent"
24         android:text="Update data"
25         />
26     <Button 
27         android:id="@+id/delete_data"
28         android:layout_height="wrap_content"
29         android:layout_width="match_parent"
30         android:text="Delete data"
31         />
32     <Button 
33         android:id="@+id/query_data"
34         android:layout_height="wrap_content"
35         android:layout_width="match_parent"
36         android:text="Query data"
37         />
38     <Button 
39         android:id="@+id/replace_data"
40         android:layout_height="wrap_content"
41         android:layout_width="match_parent"
42         android:text="use transaction to replace Book"
43         />
44     
45     <Button 
46         android:id="@+id/upgrade_one"
47         android:layout_height="wrap_content"
48         android:layout_width="match_parent"
49         android:text="upgrade database one"
50         />
51     <Button 
52         android:id="@+id/upgrade_two"
53         android:layout_height="wrap_content"
54         android:layout_width="match_parent"
55         android:text="upgrade database two"
56         />
57 </LinearLayout>
activity_main.xml

 

定義MyDatabaseHelper繼承SQLiteOpenHelper

特別注意升級數據庫的寫法!!

 1 package com.example.databasetest;
 2 
 3 import android.content.Context;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 6 import android.database.sqlite.SQLiteOpenHelper;
 7 import android.widget.Toast;
 8 /**
 9  * 
10  * 注意 id 設爲主鍵時 primary key 兩個詞,分開的
11  */
12 public class MyDatabaseHelper extends SQLiteOpenHelper {
13     public static final String CREATE_BOOK =
14             "create table Book(" +
15             "id integer primary key autoincrement," +
16             "author text, " +
17             "price real," +
18             "pages integer," +
19             "name text)";
20     public static final String CREATE_CATEGORY="create table Category(" +
21             "id integer primary key autoincrement," +
22             "category_name text," +
23             "category_code integer)";
24     private Context mContext;//爲何須要?獲取SQLiteOpenHelper實例的時候,會傳入context,爲了在這個context中進行操做
25 //  構造方法(contex , 數據庫名 , 光標? , 版本號)
26     public MyDatabaseHelper(Context context, String name,
27             CursorFactory factory, int version) {
28         super(context, name, factory, version);
29         mContext = context;
30     }
31 
32     @Override
33     public void onCreate(SQLiteDatabase db) {
34         // 建立數據庫的時候建立一張表
35         db.execSQL(CREATE_BOOK);
36         //db.execSQL(CREATE_CATEGORY);
37         Toast.makeText(mContext, "create table sussessed", Toast.LENGTH_SHORT).show();
38     }
39 
40     @Override
41     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
42         // 更新數據庫——感受這種方法很糟糕,若是存在則刪除,數據不要了??
43         /*
44         db.execSQL("drop table if exists Category");
45         db.execSQL("drop table if exists Book");
46         onCreate(db);
47         */
48         
49         // 最佳寫法——固然第二版建立時就會建立category表,第三版建立時就會增長id
50         // 只有低版本升級是纔會執行到下面的語句,另外特別注意:
51         // 這裏並無寫break語句,是爲了保證誇版本升級能夠執行到全部語句——感受還能改造,事務之類的
52         switch (oldVersion) {
53         //升級至第二版時,會多建立一個category表
54         case 1:
55             db.execSQL(CREATE_CATEGORY);
56         //升級至第三版時,Book表會新建一列 category_id
57         case 2:
58             db.execSQL("alter table Book add column category_id integer");
59         default:
60         }
61         
62     }
63 
64 }
MyDatabaseHelper

 

主入口

  1 package com.example.databasetest;
  2 
  3 import android.app.Activity;
  4 import android.content.ContentValues;
  5 import android.database.Cursor;
  6 import android.database.sqlite.SQLiteDatabase;
  7 import android.database.sqlite.SQLiteOpenHelper;
  8 import android.os.Bundle;
  9 import android.util.Log;
 10 import android.view.View;
 11 import android.view.View.OnClickListener;
 12 import android.widget.Button;
 13 import android.widget.Toast;
 14 
 15 
 16 public class MainActivity extends Activity {
 17     private SQLiteOpenHelper sqLiteOpenHelper;
 18     @Override
 19     protected void onCreate(Bundle savedInstanceState) {
 20         super.onCreate(savedInstanceState);
 21         setContentView(R.layout.activity_main);
 22         // 獲得SQLiteOpentHelper的實例
 23         sqLiteOpenHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
 24         Button createDatabaseButton = (Button) findViewById(R.id.create);
 25         Button addDataButton = (Button) findViewById(R.id.add_data);
 26         Button updateButton = (Button) findViewById(R.id.update_data);
 27         Button deleteButton = (Button) findViewById(R.id.delete_data);
 28         Button queryButton = (Button) findViewById(R.id.query_data);
 29         Button replaceButton = (Button) findViewById(R.id.replace_data);
 30         Button upgrade_One_Button = (Button) findViewById(R.id.upgrade_one);
 31         Button upgrade_Two_Button = (Button) findViewById(R.id.upgrade_two);
 32         
 33         createDatabaseButton.setOnClickListener(new OnClickListener() {
 34             
 35             @Override
 36             public void onClick(View v) {
 37                 // 沒有則會建立數據庫,有則不建立
 38                 sqLiteOpenHelper.getWritableDatabase();
 39             }
 40         });
 41         
 42 
 43         addDataButton.setOnClickListener(new OnClickListener() {
 44             
 45             @Override
 46             public void onClick(View v) {
 47                 // SQLiteOpenHelper的getWritableDatabase和getReadableDatab會返回一個SQLiteDatabase對象
 48                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
 49 //                public long insert(String table, String nullColumnHack, ContentValues values)
 50                 ContentValues values = new ContentValues();
 51                 values.put("author", "erge");
 52                 values.put("price", "88.8");
 53                 values.put("pages", "1");
 54                 values.put("name", "程序員的自我修養");
 55                 db.insert("Book", null, values);// 插入一條數據
 56                 
 57                 values.clear();  // 準備插入第二條
 58                 values.put("author", "erge");
 59                 values.put("price", "888.8");
 60                 values.put("pages", "2");
 61                 values.put("name", "程序員的將來");
 62                 db.insert("Book", null, values); //插入第二條
 63                 
 64             }
 65         });
 66         
 67         updateButton.setOnClickListener(new OnClickListener() {
 68             
 69             @Override
 70             public void onClick(View v) {
 71                 // TODO Auto-generated method stub
 72                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
 73 //                 public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
 74 //                (表名,值,where,where的值)
 75                 ContentValues values = new ContentValues();
 76                 values.put("name", "the self_improvement of developer");
 77                 db.update("Book", values, "name = ?", new String[]{"程序員的自我修養"});
 78                 
 79                 values.clear();
 80                 values.put("name", "the future of developer");
 81                 db.update("Book", values, "name = ?", new String[]{"程序員的將來"});
 82                 Toast.makeText(MainActivity.this, "update sucess", Toast.LENGTH_SHORT).show();
 83             }
 84         });
 85         
 86         deleteButton.setOnClickListener(new OnClickListener() {
 87             
 88             @Override
 89             public void onClick(View v) {
 90                 // 
 91                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
 92 //                public int delete(String table, String whereClause, String[] whereArgs)
 93                 db.delete("Book", "pages > ?", new String[]{"1"});
 94             }
 95         });
 96         
 97         // 查詢最爲複雜,參數較多
 98         queryButton.setOnClickListener(new OnClickListener() {
 99             
100             @Override
101             public void onClick(View v) {
102                 // TODO Auto-generated method stub
103                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
104 //                public Cursor query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy) 
105                 //columns用於約束查詢哪幾列,不指定則查所有
106                 //selection,selectionArgs用來約束查詢哪些行,不指定則所有;
107                 //groupBy指定須要group by的列,不指定則對結果進行group by處理;
108                 //having用於對以前group by的數據進一步過濾,不指定則不過濾;orderBy對結果進行排序,不指定則默認排序
109                 
110                 // 遍歷得結果會存儲到一個Course對象中,經過遍歷這個對象,來輸出數據
111                 Cursor cursor = db.query("Book",null,null,null,null,null,null);
112                 if(cursor.moveToFirst()){
113                     do {
114                         String author = cursor.getString(cursor.getColumnIndex("author"));
115                         Double price = cursor.getDouble(cursor.getColumnIndex("price"));
116                         int pages = cursor.getInt(cursor.getColumnIndex("pages"));
117                         String name = cursor.getString(cursor.getColumnIndex("name"));
118                         Log.d("test", "name::"+name);
119                         Log.d("test", "pages::"+pages);
120                         Log.d("test", "price::"+price);
121                         Log.d("test", "author::"+author);
122                     } while (cursor.moveToNext());
123                 }
124                 cursor.close();
125             }
126         });
127         
128         replaceButton.setOnClickListener(new OnClickListener() {
129             
130             @Override
131             public void onClick(View v) {
132                 // TODO Auto-generated method stub
133                 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
134                 db.beginTransaction();
135                 try {
136                     // 刪除原來的表
137                     db.delete("Book", null, null);
138                     
139                     // 中斷測試
140                     if(true){
141                         throw new RuntimeException("...");
142                     }
143                     // 從新添加數據
144                     ContentValues values = new ContentValues();
145                     values.put("author", "nima");
146                     values.put("price", 25.5);
147                     values.put("pages", 88);
148                     values.put("name", "zhiqinchun");
149                     
150                     db.insert("Book", null, values);
151                     db.setTransactionSuccessful();
152                 } catch (Exception e) {
153                     // TODO: handle exception
154                 }finally{
155                     db.endTransaction();
156                 }
157             }
158         });
159         
160         upgrade_One_Button.setOnClickListener(new OnClickListener() {
161             
162             @Override
163             public void onClick(View v) {
164                 // 這裏數據庫版本應該搞個變量控制一下,否則升級就只能升級一次  ,後面指定的版本號比以前的大的話,就會調用onUpgrade方法
165                 sqLiteOpenHelper = new MyDatabaseHelper(MainActivity.this, "BookStore.db", null, 2);
166                 sqLiteOpenHelper.getWritableDatabase();
167                 
168             }
169         });
170         upgrade_Two_Button.setOnClickListener(new OnClickListener() {
171             
172             @Override
173             public void onClick(View v) {
174                 // 這裏數據庫版本應該搞個變量控制一下,否則升級就只能升級一次  ,後面指定的版本號比以前的大的話,就會調用onUpgrade方法
175                 sqLiteOpenHelper = new MyDatabaseHelper(MainActivity.this, "BookStore.db", null, 3);
176                 sqLiteOpenHelper.getWritableDatabase();
177                 
178             }
179         });
180         
181     }
182 
183 }
MainActivity
相關文章
相關標籤/搜索