1. 程式人生 > >AndroidSqlite增刪改查的基本使用帶工具類

AndroidSqlite增刪改查的基本使用帶工具類

一.SQLite的介紹

1.SQLite簡介

SQLite是一款輕型的資料庫,是遵守ACID的關聯式資料庫管理系統,它的設計目標是嵌入  式的,而且目前已經在很多嵌入式產品中使用了它,它佔用資源非常的低,在嵌入式裝置中,可能只需要幾百K的記憶體就夠了。它能夠支援 Windows/Linux/Unix等等主流的作業系統,同時能夠跟很多程式語言相結合,比如Tcl、PHP、Java、C++、.Net等,還有ODBC介面,同樣比起 Mysql、PostgreSQL這兩款開源世界著名的資料庫管理系統來講,它的處理速度比他們都快。

2.SQLite的特點:

  • 輕量級


SQLite和C/S模式的資料庫軟體不同,它是程序內的資料庫引擎,因此不存在資料庫的客戶端和伺服器。使用SQLite一般只需要帶上它的一個動態  庫,就可以享受它的全部功能。而且那個動態庫的尺寸也挺小,以版本3.6.11為例,Windows下487KB、Linux下347KB。

  • 不需要"安裝"


SQLite的核心引擎本身不依賴第三方的軟體,使用它也不需要"安裝"。有點類似那種綠色軟體。

  • 單一檔案  


資料庫中所有的資訊(比如表、檢視等)都包含在一個檔案內。這個檔案可以自由複製到其它目錄或其它機器上。

  • 跨平臺/可移植性


除了主流作業系統 windows,linux之後,SQLite還支援其它一些不常用的作業系統。

  • 弱型別的欄位


同一列中的資料可以是不同型別

  • 開源


這個相信大家都懂的!!!!!!!!!!!!

3.SQLite資料型別

一般資料採用的固定的靜態資料型別,而SQLite採用的是動態資料型別,會根據存入值自動判斷。SQLite具有以下五種常用的資料型別:

NULL: 這個值為空值

VARCHAR(n):長度不固定且其最大長度為 n 的字串,n不能超過 4000。

CHAR(n):長度固定為n的字串,n不能超過 254。

INTEGER: 值被標識為整數,依據值的大小可以依次被儲存為1,2,3,4,5,6,7,8.

REAL: 所有值都是浮動的數值,被儲存為8位元組的IEEE浮動標記序號.

TEXT: 值為文字字串,使用資料庫編碼儲存(TUTF-8, UTF-16BE or UTF-16-LE).

BLOB: 值是BLOB資料塊,以輸入的資料格式進行儲存。如何輸入就如何儲存,不改  變格式。

DATA :包含了 年份、月份、日期。

TIME: 包含了 小時、分鐘、秒。

相信學過資料庫的童鞋對這些資料型別都不陌生的!!!!!!!!!!

二.SQLiteDatabase的介紹


Android提供了建立和是用SQLite資料庫的API。SQLiteDatabase代表一個數據庫物件,提供了操作資料庫的一些方法。在Android的SDK目錄下有sqlite3工具,我們可以利用它建立資料庫、建立表和執行一些SQL語句。下面是SQLiteDatabase的常用方法。 

SQLiteDatabase的常用方法 
方法名稱 方法表示含義
openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory  factory) 開啟或建立資料庫
insert(String table,String nullColumnHack,ContentValues  values)
插入一條記錄
delete(String table,String whereClause,String[]  whereArgs) 刪除一條記錄
query(String table,String[] columns,String selection,String[]  selectionArgs,String groupBy,String having,String  orderBy) 查詢一條記錄
update(String table,ContentValues values,String whereClause,String[]  whereArgs) 修改記錄
execSQL(String sql) 執行一條SQL語句
close() 關閉資料庫

Google公司命名這些方法的名稱都是非常形象的。例如openOrCreateDatabase,我們從字面英文含義就能看出這是個開啟或建立資料庫的方法。


三.SQLiteDatabase事務處理的介紹

為什麼需要引入事務處理?

應用程式初始化時需要批量的向sqlite中插入大量資料,單獨的使用for迴圈和Insert方法插入資料導致應用響應緩慢,因為 sqlite插入資料的時候預設一條語句就是一個事務,有多少條資料就有多少次磁碟操作。我的應用初始1000條記錄也就是要1000次讀寫磁碟操作。
而且不能保證所有資料都能同時插入。(有可能部分插入成功,另外一部分失敗)
解決辦法:
新增事務處理,把1000條插入作為一個事務

 db.beginTransaction();  //手動設定開始事務
        try{
            //批量處理操作
            for(int i=0;i<1001;i++){
                insert(...);
            }
            db.setTransactionSuccessful(); //設定事務處理成功,不設定會自動回滾不提交
           }catch(Exception e){
           }finally{
               db.endTransaction(); //處理完成
           }

四.SQLiteDatabase報異常的介紹

SQLiteException: database is locked異常的解決辦法


SQLite實質上是將資料寫入一個檔案,通常情況下,在應用的包名下面都能找到xxx.db的檔案,擁有root許可權的手機,可以通過adb shell,看到data/data/packagename/databases/xxx.db這樣的檔案。我們可以得知SQLite是檔案級別的鎖:多個執行緒可以同時讀,但是同時只能有一個執行緒寫。Android提供了SqliteOpenHelper類,加入Java的鎖機制以便呼叫。如果多執行緒同時讀寫(這裡的指不同的執行緒用使用的是不同的Helper例項),後面的就會遇到android.database.sqlite.SQLiteException: database is locked這樣的異常。對於這樣的問題,解決的辦法就是keep single sqlite connection,保持單個SqliteOpenHelper例項,同時對所有資料庫操作的方法新增synchronized關鍵字。完美解決sqlite的 database locked 或者是 error 5: database locked 問題

五.程式碼展示
工具類使用:

package com.example.android.datebase;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
import android.widget.Toast;

public class DatabaseUtil {

	/*
	 * 我們可以得知SQLite是檔案級別的鎖:多個執行緒可以同時讀,但是同時只能有一個執行緒寫。Android提供了SqliteOpenHelper類,
	 * 加入Java的鎖機制以便呼叫。如果多執行緒同時讀寫(這裡的指不同的執行緒用使用的是不同的Helper例項),後面的就會遇到android.
	 * database.sqlite.SQLiteException: database is
	 * locked這樣的異常。對於這樣的問題,解決的辦法就是keep single sqlite
	 * connection,保持單個SqliteOpenHelper例項,同時對所有資料庫操作的方法新增synchronized關鍵字。
	 * 完美解決sqlite的 database locked 或者是 error 5: database locked 問題
	 */
	public SQLiteDatabase db;

//	public DatabaseUtil(Context context) {
//		SqliteDataBaseClass dataBase = new SqliteDataBaseClass(context);
//		db = dataBase.getReadableDatabase();
//	}
	public DatabaseUtil(Context context, String name, CursorFactory factory, int version) {
		SqliteDataBaseClass dataBase = new SqliteDataBaseClass(context, name,factory, version);
		db = dataBase.getReadableDatabase();
	}
	// 插入一條資料
	public synchronized void insert(String table, String nullColumnHack, ContentValues values) {
		db.insert(table, nullColumnHack, values);
	}

	// 刪除一條資料
	public synchronized void delete(String table, String whereClause, String[] whereArgs) {
		db.delete(table, whereClause, whereArgs);
	}

	// 更新一條資料
	public synchronized void update(String table, ContentValues values, String whereClause, String[] whereArgs) {
		db.update(table, values, whereClause, whereArgs);
	}

	// 查詢資料
	public synchronized List<People> queryAll(String tableName) {
		List<People> list = new ArrayList<People>();
		Cursor cursor = db.query(tableName, null, null, null, null, null, null);

		while (cursor.moveToNext()) {
			People person = new People();
			person.setUsername(cursor.getString(cursor.getColumnIndex("username")));
			person.setDevice_name(cursor.getString(cursor.getColumnIndex("device_name")));
			person.setDevice_id(cursor.getInt(cursor.getColumnIndex("device_id")));
			person.setDate(cursor.getString(cursor.getColumnIndex("auto_data")));
			person.setTime(cursor.getString(cursor.getColumnIndex("auto_time")));
			list.add(person);
		}
		return list;
	}

	public synchronized void close() {
		if (db != null) {
			db.close();
		}
	};
}

基本的增刪改查:

package com.example.androidconnectmysql;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.android.datebase.DatabaseUtil;
import com.example.android.datebase.People;

import android.app.Activity;
import android.content.ContentValues;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

	private Button btn_add, btn_delete, btn_update, btn_quest,btn4;
	private EditText et_add_user, et_add_device, et_add_id, et_add_date, et_add_time;
	private TextView tv1, tv2, tv3, tv4, tv5;
	private ListView lv;
	private SimpleAdapter adapter;
	private List<Map<String, Object>> list1;
	private int version=1;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		btn_add = (Button) findViewById(R.id.btn_add);
		btn_delete = (Button) findViewById(R.id.button1);
		btn_update = (Button) findViewById(R.id.button2);
		btn_quest = (Button) findViewById(R.id.button3);
		btn4=(Button) findViewById(R.id.button4);
		tv1 = (TextView) findViewById(R.id.textView1);
		tv2 = (TextView) findViewById(R.id.textView2);
		tv3 = (TextView) findViewById(R.id.textView3);
		tv4 = (TextView) findViewById(R.id.textView4);
		tv5 = (TextView) findViewById(R.id.textView5);
		lv = (ListView) findViewById(R.id.listview);
		list1 = new ArrayList<Map<String, Object>>();

		et_add_user = (EditText) findViewById(R.id.edit_add_username);
		et_add_device = (EditText) findViewById(R.id.edit_add_devicename);
		et_add_id = (EditText) findViewById(R.id.edit_add_deviceid);
		et_add_date = (EditText) findViewById(R.id.edit_add_date);
		et_add_time = (EditText) findViewById(R.id.edit_add_time);
		btn_add.setOnClickListener(this);
		btn_delete.setOnClickListener(this);
		btn_update.setOnClickListener(this);
		btn_quest.setOnClickListener(this);
//		btn4.setOnClickListener(new OnClickListener() {
//			
//			@Override
//			public void onClick(View v) {
//				//升級資料庫
//				DatabaseUtil util =new DatabaseUtil(MainActivity.this, "Data", null, version);
//				util.close();
//			}
//		});
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_add:
			DatabaseUtil data = new DatabaseUtil(MainActivity.this, "Data", null, version);
			ContentValues values = new ContentValues();
			// 開啟事務
			data.db.beginTransaction();
			try {

//				for (int i = 0; i < 1000; i++) {
					values.put("username", et_add_user.getText().toString());
					values.put("device_name", et_add_device.getText().toString());
					values.put("device_id", et_add_id.getText().toString());
					values.put("auto_data", et_add_date.getText().toString());
					values.put("auto_time", et_add_time.getText().toString());
					data.insert("device_managent", null, values);

//				}
				// 設定事務標誌為成功,當結束事務時就會提交事務
				data.db.setTransactionSuccessful();
			} catch (Exception e) {
				// TODO: handle exception
			} finally {
				// 結束事務
				data.db.endTransaction();
				data.close();
			}
			Toast.makeText(MainActivity.this, "插入成功", Toast.LENGTH_SHORT).show();
			break;
		case R.id.button1:
			DatabaseUtil data1 = new DatabaseUtil(MainActivity.this, "Data", null, version);
			String user = "username=?";
			String[] shuzu = new String[] { "username" };
			data1.delete("device_managent", user, shuzu);
			data1.close();
			Toast.makeText(MainActivity.this, "刪除成功", Toast.LENGTH_SHORT).show();
			break;
		case R.id.button2:
			DatabaseUtil data2 = new DatabaseUtil(MainActivity.this, "Data", null, version);
			ContentValues values1 = new ContentValues();
			values1.put("username", "121315456");
			values1.put("device_name", "121eqweqw315456");
			values1.put("device_id", 2222222);
			values1.put("auto_data", "2000-11-22");
			values1.put("auto_time", "12:00");
			String user1 = "username=?";
			String[] shuzu1 = new String[] { "username" };
			data2.update("device_managent", values1, user1, shuzu1);
			data2.close();
			Toast.makeText(MainActivity.this, "修改成功", Toast.LENGTH_SHORT).show();
			break;
		case R.id.button3:
			list1.clear();
			DatabaseUtil data3 = new DatabaseUtil(MainActivity.this, "Data", null, version);
			List<People> list = data3.queryAll("device_managent");

			for (int i = 0; i < list.size(); i++) {
				String name = list.get(i).getUsername();
				String device_name = list.get(i).getDevice_name();
				int id = list.get(i).getDevice_id();
				String date = list.get(i).getDate();
				String time = list.get(i).getTime();
				Map<String, Object> item = new HashMap<String, Object>();
				item.put("username", "username:" + name);
				item.put("device_name", "device_name:" + device_name);
				item.put("device_id", "device_id:" + id);
				item.put("date", "date:" + date);
				item.put("time", "time:" + time);
				list1.add(item);

			}
			adapter = new SimpleAdapter(MainActivity.this, list1, R.layout.listitem,
					new String[] { "username", "device_name", "device_id", "date", "time" },
					new int[] { R.id.textView1, R.id.textView2, R.id.textView3, R.id.textView4, R.id.textView5 });
			lv.setAdapter(adapter);
			data3.close();
			Toast.makeText(MainActivity.this, "查詢成功", Toast.LENGTH_SHORT).show();
			break;
		default:
			break;
		}
	}

}


六.程式碼下載地址: