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。