SQLite數據庫DAO標準和CURD操作
(基於WeChat項目,在Fragment中實現對SQLite數據庫的創建、更新、讀取、刪除[CURD]操作)
-> 參考教程
創建助手類DbHelpr
SQLiteOpenHelper:封裝了數據庫創建、打開和更新等方法是抽象類。可用助手類來打開或創建數據庫,見"定義DAO"板塊代碼。
public class DbHelper extends SQLiteOpenHelper {
public static final String TB_NAME = "users";
public DbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) { // 第一次創建數據庫時調用
db.execSQL("create table if not exists " + TB_NAME + "(_id integer primary key autoincrement, name varchar, pwd varchar)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 提升構造方法版本參數值再次安裝或運行時調用
db.execSQL("drop table if exists " + TB_NAME);
onCreate(db);
}
}
定義DAO
DAO(數據訪問對象)是一種API(應用程序編程接口)。
DAO的代碼編寫:
public class usersDAO {
private SQLiteDatabase db;
private DbHelper dbHelper;
public usersDAO(Context context) {
dbHelper = new DbHelper(context, "test.db", null, 1);
}
// 查詢所有記錄
public Cursor allQuery() {
db = dbHelper.getReadableDatabase();
return db.rawQuery("select * from users", null);
}
// 返回數據表記錄數
public int getRecordsNumber() {
db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from users", null);
return cursor.getCount();
}
// 插入表數據
public void insertInfo(String name, String pwd) {
db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("pwd", pwd);
long rowId = db.insert(dbHelper.TB_NAME, null, values);
if (rowId == -1) {
Log.i("myDbDemo", "數據插入失敗!");
} else {
Log.i("myDbDemo", "數據插入成功!" + rowId);
}
}
// 刪除表數據
public void deleteInfo(String selectId) {
String where = "_id = " + selectId;
int i = db.delete(dbHelper.TB_NAME, where, null);
if (i > 0) {
Log.i("myDbDemo", "數據刪除成功!");
} else {
Log.i("myDbDemo", "數據未刪除!");
}
}
// 更新表數據
public void updateInfo(String name, String pwd, String selectId) {
ContentValues values = new ContentValues();
values.put("name", name);
values.put("pwd", pwd);
String where = "_id = " + selectId;
int i = db.update(dbHelper.TB_NAME, values, where, null);
if (i > 0) {
Log.i("myDbDemo","數據更新成功!");
} else {
Log.i("myDbDemo","數據未更新!");
}
}
}
其中,
- ContentValues 以鍵值對形式存放數據。
- Cursor 即遊標,和所學的其他數據庫一樣,適合用來查詢讀取數據,使用後完畢關閉遊標。
- db.update()、db.delete()等操作可用db.execSQL()來替換,前者是非原生用法,後者是原生用法(執行標準SQL語句)。
比如:
db.update(dbHelper.TB_NAME, values, where, null);
可寫作:
db.execSQL("update users set name = ?, pwd = ? where _id = ?", new Object[]{name, pswd, seleteId});
點擊事件
設定三個按鈕,Add Update Delete,實現增刪改操作。
displayRecords()實現讀取數據。
private usersDAO myDAO;
private ListView lvFind;
private List<Map<String, Object>> listData;
private Map<String, Object> listItem;
private SimpleAdapter listAdapter;
private EditText etName;
private EditText etPwd;
private String selectId = null;// 獲取點擊ListView中item對應的user的id
View view;
public void displayRecords(View view) {
lvFind = (ListView) view.findViewById(R.id.lvFind);
listData = new ArrayList<Map<String, Object>>();
Cursor cursor = myDAO.allQuery();
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
// String pwd = cursor.getString(2);
String pwd = cursor.getString(cursor.getColumnIndex("pwd"));
listItem = new HashMap<String, Object>();
listItem.put("_id", id);
listItem.put("name", name);
listItem.put("pwd", pwd);
listData.add(listItem);
}
cursor.close();
listAdapter = new SimpleAdapter(view.getContext(),
listData,
R.layout.list_item_find,
new String[]{"_id", "name", "pwd"},
new int[]{R.id.txtId, R.id.txtName, R.id.txtPwd});
lvFind.setAdapter(listAdapter);
lvFind.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Map<String, Object> rec = (Map<String, Object>) listAdapter.getItem(position);
etName.setText(rec.get("name").toString());
etPwd.setText(rec.get("pwd").toString());
Log.i("", rec.get("_id").toString());
selectId = rec.get("_id").toString();
Toast.makeText(view.getContext(), selectId + "", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onClick(View v) {
if (selectId != null) {// 選擇列表項,以進行操作
String p1 = etName.getText().toString().trim();
String p2 = etPwd.getText().toString().trim();
switch (v.getId()) {
case R.id.btnAdd:
myDAO.insertInfo(p1, p2);
break;
case R.id.btnModify:
myDAO.updateInfo(p1, p2, selectId);
Toast.makeText(v.getContext(), "update succeed", Toast.LENGTH_SHORT).show();
break;
case R.id.btnDelete:
myDAO.deleteInfo(selectId);
Toast.makeText(v.getContext(), "delete succeed", Toast.LENGTH_SHORT).show();
break;
}
} else {//未選擇列表項
if (v.getId() == R.id.btnAdd) {
String p1 = etName.getText().toString();
String p2 = etPwd.getText().toString();
if (p1.equals("") || p2.equals("")) {
Toast.makeText(v.getContext(), "please input name and password", Toast.LENGTH_SHORT).show();
} else {
myDAO.insertInfo(p1, p2);
}
} else {
Toast.makeText(v.getContext(), "please select the record", Toast.LENGTH_SHORT).show();
}
}
displayRecords(view);
在一開始的編寫運行過程中,點擊按鈕發生閃退,Logcat報空指針錯誤。
Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
空指針問題是一類常見的運行出錯問題,一般是當前環境找不到代碼所指的id什麼的、Fragment裏面view的環境指向有誤。
查找原因,修正之後運行成功。
完整代碼已上傳至github。