android 关于Sqlite的使用
2018-04-10 本文已影响0人
成旭辕
关于Sqite的使用,以及需要注意的地方,下面简单介绍一下
首先需要一个自定义的类继承SQLiteOpenHelper,并且实现构造方法,和onCreate()方法和onUpgrade
onCreate() 方法中创建数据库
onUpgrade() 方法中根据版本号来更新表
创建表的时候注意:
primary key: 主键
autoincrement: 自增型变量 (这个变量一般都要设置,主要根据你的需求来吧)
if not exists : 如果表已经创建过了就不再创建了
这里DatabaseHelper 用了一个单例,建议最好使用单例,一般情况使用数据库是都会使用到多线程,
多线程操作数据库是经常会遇到各种各样的坑
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = DatabaseHelper.class.getSimpleName();
private static final String DB_NAME = "db_test";//数据库名称
private static DatabaseHelper mInstance;
public synchronized static DatabaseHelper getInstance() {
if (mInstance == null) {
mInstance = new DatabaseHelper(Application.getInstance(), DB_NAME, null, 1);
}
return mInstance;
}
public synchronized static void destoryInstance() {
if (mInstance != null) {
mInstance.close();
}
}
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
super(context, name, factory, version, errorHandler);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table if not exists user(id integer primary key autoincrement, name, age, sex )");
Log.i(TAG, "----create table user ----");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// switch(newVersion){
// case 1: db.execSQL(第一个版本的建表语句);
// case 2: db.execSQL(第二个版本的建表语句);
// case 3: db.execSQL(第三个版本的建表语句);
// }
}
}
获取读写数据库SQLiteDatabase 管理类
public class DBManager {
private static class DBManagerHolder {
private final static DBManager mDBManager = new DBManager();
}
public static DBManager getInstance() {
return DBManagerHolder.mDBManager;
}
/**
* 获取可写数据库
*/
public SQLiteDatabase getWritableDatabase() {
return DatabaseHelper.getInstance().getWritableDatabase();
}
/**
* 获取可读数据库
*
* @return SQLiteDatabase
*/
public SQLiteDatabase getReadableDatabase() {
return DatabaseHelper.getInstance().getReadableDatabase();
}
}
针对具体的User的一个增删改查管理类
下面是一个具体的案例,插入,更新,删除,查询的操作也可以直接使用SQL语句,不过Google官方建立使用下面的方式
sql 语句方式:
插入sql语句: "insert into 表名(列名1,列名2,列名3) values(?,?,?)", new Object[]{列名1的值, 列名2的值, 列名3的值}
更新sql语句: "update user set 修改的列名 = ? where 修改的列名 = ?", new String[]{原来的值, 修改的值}
删除sql语句: "delete from person where 列名 = ?",new String[]{删除条件}
查询sql语句: "select * from person where 查询的列名 like ?",new String[]{查询条件} eg: "select * from user where id like ?",new String[]{"1"}
删除表sql语句: drop table if exists 表名 //这种方式把表直接干掉
清空表sql语句: delete from if exists 表名 //这种方式把表里面的数据全部清空
清空表将自增id恢复到从0开始,需要在执行一条语句 : "update sqlite_sequence set seq=0 where name='use'"
例如: sqLiteDatabase.execSQL("delete from if exists user")
sqLiteDatabase.execSQL("update sqlite_sequence set seq=0 where name='user'")
清空user表,并将自增id从
class DbUserManager{
/**
*插入数据
* @param name
* @param age
* @param sex 一般:1男2女
*/
public void insertUser(String name, Integer age, Int sex) {
SQLiteDatabase sqLiteDatabase = DBManager.getInstance().getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("name", name);
cv.put("age", age);
cv.put("sex", sex);
sqLiteDatabase.insert(TABLE_USE, null, cv);
sqLiteDatabase.close();
}
/**
* 删除数据
*/
public void delete(int id) {
//得到一个可写的数据库
SQLiteDatabase sqLiteDatabase = DBManager.getInstance().getWritableDatabase();
String whereClauses = "id=?";
String[] whereArgs = {String.valueOf(id)};
sqLiteDatabase.delete(TABLE_MEMBER, whereClauses, whereArgs);
sqLiteDatabase.close();
}
/**
*
*更新年纪
*@param whoId 目标人的id
*@param age 修改之后的年纪
*/
public void update(whoId int,int age) {
SQLiteDatabase sqLiteDatabase = DBManager.getInstance().getWritableDatabase();
ContentValues cv = new ContentValues();
//往ContentValues对象存放数据,键-值对模式
cv.put("age", age);
//where 子句 "?"是占位符号
String whereClause = "id=?";
String[] whereArgs = {String.valueOf(whoId)};
sqLiteDatabase.update(TABLE_MEMBER, cv, whereClause, whereArgs);
sqLiteDatabase.close();
}
/**
*查询单独的一条数据
*需要查询数据的id
*/
public void read(int id) {
SQLiteDatabase sqLiteDatabase = DBManager.getInstance().getReadableDatabase();
Cursor cursor = sqLiteDatabase.query("user", new String[]{"id", "name", "age", "sex"}, "id=?", new String[]{String.valueOf(id)}, null, null, null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String age = cursor.getString(cursor.getColumnIndex("age"));
String sex = cursor.getString(cursor.getColumnIndex("sex"));
Log.i("query", "姓名:" + name + " " + "年龄:" + age + " " + "性别:" + sex);
}
cursor.close();
//关闭数据库
sqLiteDatabase.close();
}
/**
**
*查询某张表中所有数据
*/
public void getAllUer() {
List<Map<String, Object>> mapList = new ArrayList<>();
SQLiteDatabase sqLiteDatabase = DBManager.getInstance().getReadableDatabase();
Cursor cursor = sqLiteDatabase.query(true, TABLE_MEMBER, new String[]{"id", "name", "age","sex"}, "", null, null, null, "id DESC", null);
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String age = cursor.getString(cursor.getColumnIndex("age"));
String sex = cursor.getString(cursor.getColumnIndex("sex"));
Map<String, Object> map = new HashMap<>();
map.put("name", name);
map.put("age", age);
map.put("sex", sex);
mapList.add(map);
}
cursor.close();
//关闭数据库
sqLiteDatabase.close();
//测试查询结果,需要时请删去下面这几行代码
if(mapList ==null || mapList.size() ==0) return
for (int i = 0; i < mapList.size(); i++) {
Map<String, Object> map = mapList.get(i);
LogUtils.i("query all", "姓名:" + map.get("name") + " " + "年龄:" + map.get("age") + " " + "性别:" + map.get("sex"));
}
}
}
测试调用
class TestActivity extends AppCompatActivity{
private DbUserManager mDbUserManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDbUserManager = new DbUserManager();
test()
}
private void test(){
//插入数据
mDbUserManager.insertUser("程序员1",26,1);
mDbUserManager.insertUser("程序员2",26,2);
//读取数据
mDbUserManager.getAllUer();
//更新数据
mDbUserManager.update(1,25);
}
}
数据库事务问题
有时候遇到某些需求,需要添加事务
SQLiteDatabase db = DBManager.getInstance().getWritableDatabase();
db.beginTransaction(); // 开启事务
try {
db.execSQL("你的SQL语句1");
db.execSQL("你的SQL语句2");
db.setTransactionSuccessful(); // 标记事务完成
} finally {
db.endTransaction(); // 结束事务
db.close();
}
注释:
调用SQLiteDatabase的beginTransaction()方法可以开启一个事务,
调用 endTransaction() 结束事务 当程序执行到endTransaction() 方法时,会检查事务的标志是否为成功,
如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,
如果没有调用setTransactionSuccessful() 方法则回滚事务
这么说不一定能懂,那么啥叫事务呢?
你可以看作是一组操作,只有一组动作全部完成,才算完成,中间任何一个地方出现问题,就回滚,
比如说你去ATM机取钱,第一步插入看,第二步输入密码,第三步输取款金额,第四步把钱取出来,第五步取卡。
好,假如你现在进行到第三步输入了取款金额,突然断电了,你还没来得及把钱取出来,假如没有用事务的话,你卡里的钱就会被扣掉,
这个时候你是不是会疯掉,😄 ,如果用事务的话,就会把你整个取钱的五个步骤看成是一个整体,任何有个步骤出现问题都会回滚(就会回到原来没有执行任何SQL之前的样子)
突然断电了也不要紧,事务一回滚,你的钱就会回到你取钱之前的数额,这就是事务,现在你能理解了吧。