安卓案例:利用SQLiteOpenHelper操作数据库及表
一、运行效果
二、涉及知识点
1、利用SQLiteOpenHelper类创建与升级数据库
这个类是一个抽象类,我们必须继承该类创建一个子类,实现里面的两个抽象方法:
(1)public void onCreate(SQLiteDatabase db);
(2)public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
这两个方法什么时候会调用呢?
如果数据库不存在,那么就会调用onCreate方法来创建数据库、表以及视图。
如果数据库存在但是没有升级,什么事情也不做。
如果数据库存在并且进行了升级,那么就会调用onUpgrade方法来完成升级服务。
2、游标与列表的绑定
数据表查询的结果放在游标集里,这作为数据源,如何把数据源和展示控件(ListView)绑定到一起呢?这就需要一个适配器——SimpleCursorAdapter(简单游标适配器)。
3、列表控件
4、上下文菜单
5、对话框
三、实现步骤
1、创建安卓应用SQLiteOpenHelperDemo
2、主布局资源文件activity_main.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp"
tools:context="net.hw.sqlite_open_helper_demo.MainActivity">
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
3、继承SQLiteOpenHelper,创建自定义数据库打开助手DBHelper
package net.hw.sqlite_open_helper_demo;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
/**
* Created by Administrator on 2017/12/27.
*/
public class DBHelper extends SQLiteOpenHelper {
/**
* 数据库名
*/
private static final String DB_NAME = "student.db";
/**
* 数据库版本号
*/
private static final int DB_VERSION = 1;
/**
* 表名
*/
private static final String TABLE_NAME = "student";
/**
* 上下文
*/
private Context context;
/**
* 构造方法
*
* @param context
*/
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
}
/**
* 创建方法:当数据库不存在时才调用
*
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
// 创建表
createTable(db, TABLE_NAME);
// 插入记录
insertRecords(db);
}
/**
* 创建表
*
* @param tableName
*/
private void createTable(SQLiteDatabase db, String tableName) {
// 定义SQL字符串
String strSQL = "CREATE TABLE " + tableName + "(_id text, name text, gender text, age integer, major text)";
try {
// 执行SQL,创建表
db.execSQL(strSQL);
// 提示用户建表成功
Toast.makeText(context, "恭喜,表【" + tableName + "】创建成功!", Toast.LENGTH_SHORT).show();
} catch (SQLException e) {
// 提示用户建表失败
Toast.makeText(context, "遗憾,表【" + tableName + "】创建失败!", Toast.LENGTH_SHORT).show();
}
}
/**
* 插入表记录
*
* @param db
*/
private void insertRecords(SQLiteDatabase db) {
// 创建内容值对象
ContentValues values = new ContentValues();
// 通过键值对方式存放记录信息
values.put("_id", "1600001");
values.put("name", "李云龙");
values.put("gender", "男");
values.put("age", 19);
values.put("major", "软件技术专业");
// 调用db的插入方法,插入第1条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600002");
values.put("name", "张云红");
values.put("gender", "女");
values.put("age", 18);
values.put("major", "市场营销专业");
// 调用db的插入方法,插入第2条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600003");
values.put("name", "肖文燕");
values.put("gender", "女");
values.put("age", 20);
values.put("major", "数字媒体专业");
// 调用db的插入方法,插入第3条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600004");
values.put("name", "郑小刚");
values.put("gender", "男");
values.put("age", 18);
values.put("major", "软件技术专业");
// 调用db的插入方法,插入第4条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600005");
values.put("name", "唐雨涵");
values.put("gender", "女");
values.put("age", 20);
values.put("major", "机械制造专业");
// 调用db的插入方法,插入第5条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600006");
values.put("name", "王小丫");
values.put("gender", "女");
values.put("age", 20);
values.put("major", "数字媒体专业");
// 调用db的插入方法,插入第6条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600007");
values.put("name", "张廷玉");
values.put("gender", "男");
values.put("age", 18);
values.put("major", "市场营销专业");
// 调用db的插入方法,插入第7条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600008");
values.put("name", "吴文霞");
values.put("gender", "女");
values.put("age", 20);
values.put("major", "机械制造专业");
// 调用db的插入方法,插入第8条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600009");
values.put("name", "王晓燕");
values.put("gender", "女");
values.put("age", 18);
values.put("major", "数字媒体专业");
// 调用db的插入方法,插入第9条记录
db.insert(TABLE_NAME, null, values);
// 通过键值对方式存放记录信息
values.put("_id", "1600010");
values.put("name", "董翔宇");
values.put("gender", "男");
values.put("age", 20);
values.put("major", "市场营销专业");
// 调用db的插入方法,插入第10条记录
db.insert(TABLE_NAME, null, values);
}
/**
* 查询方法
*
* @param columns
* @param selection
* @param selectionArgs
* @return
*/
public Cursor query(String[] columns, String selection, String[] selectionArgs) {
// 获取一个只读数据库
SQLiteDatabase db = getReadableDatabase();
// 执行查询方法,返回游标
return db.query(TABLE_NAME, columns, selection, selectionArgs, null, null, null);
}
public int delete(String whereClause, String[] whereArgs) {
// 获取一个可写数据库
SQLiteDatabase db = getWritableDatabase();
// 执行删除方法,返回删除记录数
return db.delete(TABLE_NAME, whereClause, whereArgs);
}
/**
* 更新方法(课堂练习)
*
* @param values
* @param whereClause
* @param whereArgs
* @return
*/
public int update(ContentValues values, String whereClause, String[] whereArgs) {
return 0;
}
/**
* 插入方法(课堂练习)
*
* @param values
* @return
*/
public int insert(ContentValues values) {
return 0;
}
/**
* 升级方法:当数据库升级时被调用
*
* @param sqLiteDatabase
* @param i
* @param i1
*/
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
// 暂时不升级数据库
}
}
4、主界面类MainActivity
package net.hw.sqlite_open_helper_demo;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends Activity {
/**
* 编辑菜单项标识
*/
private static final int EDIT_MENU_ITEM = 1;
/**
* 删除菜单项标识
*/
private static final int DELETE_MENU_ITEM = 2;
/**
* 学生列表控件
*/
private ListView lvStudent;
/**
* 简单游标适配器
*/
private SimpleCursorAdapter adapter;
/**
* 游标(数据源)
*/
private Cursor cursor;
/**
* 当前列表项位置
*/
private int position;
/**
* 数据库助手
*/
private DBHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 利用布局资源文件设置用户界面
setContentView(R.layout.activity_main);
// 通过资源标识获得控件实例
lvStudent = (ListView) findViewById(R.id.lv_student);
// 实例化数据库助手
dbHelper = new DBHelper(this);
// 查询全部表记录
cursor = dbHelper.query(null, null, null);
// 实例化简单游标适配器
adapter = new SimpleCursorAdapter(
this, // 参数1:上下文
android.R.layout.simple_expandable_list_item_2, // 参数2:列表项模板
cursor, // 参数3:游标(数据源)
new String[] {"name", "gender"}, // 参数4:字段列表
new int[] {android.R.id.text1, android.R.id.text2}, // 参数5:控件标识列表
SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER // 参数6:标志(注册内容观察者)
);
// 给列表控件设置适配器
lvStudent.setAdapter(adapter);
}
}
运行程序,结果如下:
5、单击列表项,弹出吐司,显示该学生详情
// 给列表控件注册监听器
lvStudent.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
// 游标定位到指定记录
cursor.moveToPosition(position);
// 获取当前记录各个字段值
String _id = cursor.getString(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String gender = cursor.getString(cursor.getColumnIndex("gender"));
int age = cursor.getInt(cursor.getColumnIndex("age"));
String major = cursor.getString(cursor.getColumnIndex("major"));
// 将各个字段值拼接成一个学生记录信息
StringBuilder builder = new StringBuilder();
builder.append("学生详细信息\n\n");
builder.append("学号:" + _id + "\n");
builder.append("姓名:" + name + "\n");
builder.append("性别:" + gender + "\n");
builder.append("年龄:" + age + "\n");
builder.append("专业:" + major + "\n");
String studentInfo = builder.toString();
// 通过吐司显示学生信息
Toast.makeText(MainActivity.this, studentInfo, Toast.LENGTH_SHORT).show();
}
});
此时,运行程序,单击某一项:
6、创建上下文菜单
/**
* 创建上下文菜单
*
* @param menu
* @param v
* @param menuInfo
*/
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// 获取适配器上下文菜单信息对象
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
// 获取列表项当前位置
position = acmi.position;
// 游标定位到指定记录
cursor.moveToPosition(position);
// 获取当前记录的姓名信息
String name = cursor.getString(cursor.getColumnIndex("name"));
// 添加上下文菜单项
menu.add(1, EDIT_MENU_ITEM, 1, "编辑【" + name + "】记录");
menu.add(1, DELETE_MENU_ITEM, 2, "删除【" + name + "】记录");
// 设置上下文菜单标题行图标
menu.setHeaderIcon(R.mipmap.ic_launcher);
// 设置上下文菜单标题行
menu.setHeaderTitle("表记录操作");
}
7、在onCreate方法里给列表控件lvStudent注册上下文菜单
此时,运行程序,长按某一项:
8、完成删除记录功能
/**
* 上下文菜单项选择事件处理
*
* @param item
* @return
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case EDIT_MENU_ITEM:
// TODO 课堂练习
break;
case DELETE_MENU_ITEM:
// 定义警告对话框生成器
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// 通过生成器设置,创建警告对话框
builder.setIcon(R.mipmap.ic_launcher) // 设置图标
.setTitle("删除表记录") // 设置标题
.setMessage("您是否要删除当前记录?") // 设置正文
.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 游标定位到当前记录
cursor.moveToPosition(position);
// 获取当前记录的_id
String _id = cursor.getString(cursor.getColumnIndex("_id"));
// 删除当前记录
int count = dbHelper.delete("_id = ?", new String[] {_id});
// 判断是否删除成功
if (count > 0) {
// 游标执行重查询方法
cursor.requery();
// 刷新列表控件
lvStudent.deferNotifyDataSetChanged();
} else {
Toast.makeText(MainActivity.this, "遗憾,记录删除失败!", Toast.LENGTH_SHORT).show();
}
}
}) // 设置肯定按钮
.setNegativeButton("否", null) // 设置否定按钮
.create() // 创建警告对话框
.show(); // 显示警告对话框
break;
}
return true;
}
运行程序,测试删除功能:
单击“删除【李云龙】记录”菜单项:
单击【是】按钮,看看“李云龙”还在不在?
9、完成编辑记录功能(课堂练习)
四、课后作业
对教学案例,完成添加记录和查询记录功能。
系统主界面
编辑菜单:
查询菜单:
排序菜单:
统计菜单:
关于菜单:
原文:https://blog.csdn.net/howard2005/article/details/79457374