前段時間寫了個安卓平台下SQLite數據庫操作的實例 ,一直沒得時間總結 ,今天把它弄出來了。
在Android 運行時環境包含了完整的 SQLite。
首先介紹一下SQLite這個數據庫:
SQLite,是一款輕型的數據庫,是遵守ACID的關聯式數據庫管理系統,它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統,同時能夠跟很多程序語言相結合,比如 Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起Mysql、PostgreSQL這兩款開源世界著名的數據庫管理系統來講,它的處理速度比他們都快。
有一點相對其他數據庫來說比較特殊的是:SQLite是無類型的. 這意味着你可以保存任何類型的數據到你所想要保存的任何表的任何列中,意思就是說話你可以在創建數據庫表的時候任意定義數據類型,卻不影響實際使用時的數據存儲。
舉個例子說就是你可以在創建表時定義username字段為varchar類型,但是實時使用時你可以向這個字段存入1、2.5、2012-6-6.。。這樣的整型,單精,以及時間等其他類型,在SQLite里沒有這種限制。
但是有一種情況例外:當字段類型為 ”Integer Primary Key” 時,就是定義表主鍵,這個就只能是integer類型。和普通數據庫相同 。
SQLite 不支持一些標准的 SQL 功能,特別是外鍵約束(FOREIGN KEY constrains),嵌套 transcaction 和 RIGHT OUTER JOIN 和 FULL OUTER JOIN, 還有一些 ALTER TABLE 功能。
需要注意一點: SQLite不支持存儲過程!
我這里就簡單介紹,如需要可自行去了解關於SQLite的更多知識,
然后是我的Demo(一個簡單的完成數據庫增刪查改操作):
首先是項目目錄結構:
在本項目中我們使用JUnit測試,就要在AndroidManifest.xml配置JUnit
AndroidManifest.xml
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.yzsoft.sqlitedemo.test"
- android:versionCode="1"
- android:versionName="1.0" >
- <!-- 為了方便測試,我直接把上面包位置改成我項目的測試包下 -->
- <uses-sdk
- android:minSdkVersion="8"
- android:targetSdkVersion="15" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <!--
- 因為我們開發項目的時候,包會比較多,所以最好在下面這個activity的配置( android:name="org.yzsoft.sqlitedemo.activity.MainActivity" )這句這里打上完整的 包名.類名
- ,雖然可以直接用 .類名,但是這個.類名是建立在
- <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.yzsoft.sqlitedemo.test"
- 之上的,用package+.類名也剛好可以組合成完整路徑。但是我們保險一點寫完整去。
- -->
- <activity
- android:name="org.yzsoft.sqlitedemo.activity.MainActivity"
- android:label="@string/title_activity_main" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <!-- JUnit要加這句 -->
- <uses-library android:name="android.test.runner" />
- </application>
- <!-- JUnit還要加這段 (android:targetPackage測試類所在包名 ) -->
- <instrumentation
- android:name="android.test.InstrumentationTestRunner"
- android:label="Test Unit Tests"
- android:targetPackage="org.yzsoft.sqlitedemo.test" >
- </instrumentation>
- </manifest>
1、MainActivity.java(因為本項目中使用JUnit進行測試,就不需要Activity了,留着不用寫它)
- package org.yzsoft.sqlitedemo.activity;
- import org.yzsoft.sqlitedemo.util.R;
- import org.yzsoft.sqlitedemo.util.R.layout;
- import org.yzsoft.sqlitedemo.util.R.menu;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- public class MainActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.activity_main, menu);
- return true;
- }
- }
2、DBOpenHandler.java
- package org.yzsoft.sqlitedemo.util;
- import android.content.Context;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteDatabase.CursorFactory;
- import android.database.sqlite.SQLiteOpenHelper;
- public class DBOpenHandler extends SQLiteOpenHelper {
- /**
- *
- * @param context
- * 上下文
- * @param name
- * 數據庫名
- * @param factory
- * 可選的數據庫游標工廠類,當查詢(query)被提交時,該對象會被調用來實例化一個游標。默認為null。
- * @param version
- * 數據庫版本號
- */
- public DBOpenHandler(Context context, String name, CursorFactory factory, int version) {
- super(context, name, factory, version);
- }
- @Override
- public void onCreate(SQLiteDatabase db) {// 覆寫onCreate方法,當數據庫創建時就用SQL命令創建一個表
- // 創建一個t_users表,id主鍵,自動增長,字符類型的username和pass;
- db.execSQL("create table t_users(id integer primary key autoincrement,username varchar(200),pass varchar(200) )");
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // TODO Auto-generated method stub
- }
- }
3、TUsers.java(實體類,習慣了WEB開發,總會加個實體類,方便)
- package org.yzsoft.sqlitedemo.vo;
- public class TUsers {
- private int id ;
- private String username;
- private String pass;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getPass() {
- return pass;
- }
- public void setPass(String pass) {
- this.pass = pass;
- }
- }
4、SQLiteDAOImpl.java(數據庫操作實現類)
- package org.yzsoft.sqlitedemo.util;
- import java.util.ArrayList;
- import java.util.List;
- import org.yzsoft.sqlitedemo.vo.TUsers;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- public class SQLiteDAOImpl {
- private DBOpenHandler dbOpenHandler;
- public SQLiteDAOImpl(Context context) {
- this.dbOpenHandler = new DBOpenHandler(context, "dbtest.db", null, 1);
- }
- public void save(TUsers tusers) {// 插入記錄
- SQLiteDatabase db = dbOpenHandler.getWritableDatabase();// 取得數據庫操作
- db.execSQL("insert into t_users (username,pass) values(?,?)", new Object[] { tusers.getUsername(), tusers.getPass() });
- db.close();// 記得關閉數據庫操作
- }
- public void delete(Integer id) {// 刪除紀錄
- SQLiteDatabase db = dbOpenHandler.getWritableDatabase();
- db.execSQL("delete from t_users where id=?", new Object[] { id.toString() });
- db.close();
- }
- public void update(TUsers tusers) {// 修改紀錄
- SQLiteDatabase db = dbOpenHandler.getWritableDatabase();
- db.execSQL("update t_users set username=?,pass=? where" + " id=?", new Object[] { tusers.getUsername(), tusers.getPass(), tusers.getId() });
- db.close();
- }
- public TUsers find(Integer id) {// 根據ID查找紀錄
- TUsers tusers = null;
- SQLiteDatabase db = dbOpenHandler.getReadableDatabase();
- // 用游標Cursor接收從數據庫檢索到的數據
- Cursor cursor = db.rawQuery("select * from t_users where id=?", new String[] { id.toString() });
- if (cursor.moveToFirst()) {// 依次取出數據
- tusers = new TUsers();
- tusers.setId(cursor.getInt(cursor.getColumnIndex("id")));
- tusers.setUsername(cursor.getString(cursor.getColumnIndex("username")));
- tusers.setPass(cursor.getString(cursor.getColumnIndex("pass")));
- }
- db.close();
- return tusers;
- }
- public List<TUsers> findAll() {// 查詢所有記錄
- List<TUsers> lists = new ArrayList<TUsers>();
- TUsers tusers = null;
- SQLiteDatabase db = dbOpenHandler.getReadableDatabase();
- // Cursor cursor=db.rawQuery("select * from t_users limit ?,?", new
- // String[]{offset.toString(),maxLength.toString()});
- // //這里支持類型MYSQL的limit分頁操作
- Cursor cursor = db.rawQuery("select * from t_users ", null);
- while (cursor.moveToNext()) {
- tusers = new TUsers();
- tusers.setId(cursor.getInt(cursor.getColumnIndex("id")));
- tusers.setUsername(cursor.getString(cursor.getColumnIndex("username")));
- tusers.setPass(cursor.getString(cursor.getColumnIndex("pass")));
- lists.add(tusers);
- }
- db.close();
- return lists;
- }
- public long getCount() {//統計所有記錄數
- SQLiteDatabase db = dbOpenHandler.getReadableDatabase();
- Cursor cursor = db.rawQuery("select count(*) from t_users ", null);
- cursor.moveToFirst();
- db.close();
- return cursor.getLong(0);
- }
- }
5、TUsersTest.java(JUnit測試類)
- package org.yzsoft.sqlitedemo.test;
- import java.util.List;
- import org.yzsoft.sqlitedemo.util.DBOpenHandler;
- import org.yzsoft.sqlitedemo.util.SQLiteDAOImpl;
- import org.yzsoft.sqlitedemo.vo.TUsers;
- import android.test.AndroidTestCase;
- import android.util.Log;
- public class TUsersTest extends AndroidTestCase {
- private static final String TAG = "這個是測試類";// 准備好TAG標識用於LOG輸出,方便我們用LogCat進行調試
- public void testCreate() {
- DBOpenHandler dbHandler = new DBOpenHandler(this.getContext(), "dbtest.db", null, 1);// 創建數據庫文件
- dbHandler.getWritableDatabase();
- }
- public void testSave() throws Throwable {
- SQLiteDAOImpl p = new SQLiteDAOImpl(this.getContext());
- TUsers tuser = new TUsers();
- tuser.setUsername("用戶");
- tuser.setPass("密碼");
- p.save(tuser);
- Log.i(TAG, "插入成功");// 用日志記錄一個我們自定義的輸出。可以在LogCat窗口中查看,方便調試
- }
- public void testUpate() throws Throwable {
- SQLiteDAOImpl p = new SQLiteDAOImpl(this.getContext());
- TUsers tuser = p.find(1);
- tuser.setUsername("張三");
- p.update(tuser);
- Log.i(TAG, "修改成功");
- }
- public void testDelete() throws Throwable {
- SQLiteDAOImpl p = new SQLiteDAOImpl(this.getContext());
- p.delete(2);
- Log.i(TAG, "刪除成功");
- }
- public void testFind() throws Throwable {
- SQLiteDAOImpl p = new SQLiteDAOImpl(this.getContext());
- TUsers tuser = p.find(1);
- Log.i(TAG, tuser.getUsername() + " 用戶名");
- }
- public void testGetCount() throws Throwable {
- SQLiteDAOImpl p = new SQLiteDAOImpl(this.getContext());
- Log.i(TAG, p.getCount() + " 總記錄數");
- }
- public void testFindAll() throws Throwable {
- SQLiteDAOImpl p = new SQLiteDAOImpl(this.getContext());
- List<TUsers> tusers = p.findAll();
- for (TUsers tuser : tusers) {
- Log.i(TAG, tuser.getUsername() + " 用戶名");
- }
- }
- }
然后是測試中的一些截圖:
最后我們把File Exploer中data/data/項目包名/databases/dbtest.db 導出來,用Navicat Premium等數據庫管理工具查看里面的數據:
導出來看看:
雖然安卓平台中SQLite是個小型的本地數據庫,但是有些地方使用起來會比文件存儲更方便,本文只是對它作一個簡單的操作實例 ,有這方面興趣的童鞋可以自己去深入研究。也希望大家能多交流交流~~~~
最最后~附上項目源碼: