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的常用方法
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;
}
}
}
六.程式碼下載地址: