十分钟安卓:实现对SQLite的增删查改

简单了解SQLite

百度说:SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。

SQLiteOpenHelper

SQLiteOpenHelper是Google写好的API,是一个抽象的用于管理数据库创建版本管理的帮助程序类。

我们要写一个它的子类,这个子类要重写实现onCreate(SQLiteDatabase)onUpgrade(SQLiteDatabase, int, int)并且可选地onOpen(SQLiteDatabase),如果数据库存在,则该类负责打开数据库,如果不存在则创建它,并根据需要进行升级。事务用于确保数据库始终处于合理状态。

public class MyOpenHelper extends SQLiteOpenHelper {
    //利用SQLiteOpenHelper来创建和获取数据库
    public MyOpenHelper(Context context) {
        //构造器,若数据库不存在,创建数据库
        super(context, "test.db", null, 1);
        //第一个参数:上下文
        //第二个参数:数据库名称
        //第三个参数:游标工厂,一般使用默认的游标,默认值为null
        //第四个参数:数据库版本
    }

    @Override
    //在创建数据库的的时候调用onCreate方法,创建新表
    public void onCreate(SQLiteDatabase db) {
        //创建一张新表
        db.execSQL("create table Person(name varchar(20) primary key, sex char(2), age integer); ");
    }
    
    @Override
    //当更新数据库版本的时候调用onUpgrade方法
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	
    }
}

获取数据库

获取数据库有两个方法:getReadableDatabase() getWritableDatabase(),我们可以看一下Google的介绍
在这里插入图片描述
在这里插入图片描述

正常情况下,getReadableDatabase() 和 getWritableDatabase() 返回的都是一个SQLiteDatabase类型的数据库,但如果出现了一些问题,如磁盘满了,那么getReadableDatabase()返回的就是一个只读的数据库,而getWritableDatabase()就可能会出现调用错误。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
    //new一个db小帮手
    MyOpenHelper mOpenHelper = new MyOpenHelper(this);
    SQLiteDatabase database = mOpenHelper.getReadableDatabase();
    ...//要执行的操作
    //用完数据库记得要关闭
    database.close();
    mOpenHelper.close();
}

实现增删改查

获取到数据库database之后就可以直接操作了,一般是调用SQLiteDatabase中的execSQL()的方法。
execSQL(String sql)里的sql是一个完整的sql语句,要注意(“双引号”)和(‘单引号’)的区别,和不要在sql语句最后漏打;分号结束。

(一)插入

插入操作没有返回值

database.execSQL("insert into Person values('张三','男',35);");
database.execSQL("insert into Person values('李四','女',22);");

也可以用Google封装好的API,insert()方法

//为了避免出现"insert into Person(null) values(null)"这种 要插入数据的列为空 而导致程序崩溃的情况
//若将nullColumnHack定为"name"
//这个方法就会将Person(null)中的null改为nullColumnHack的值
String nullColumnHack = "name";
//用ContentValues,通过"列名-列值"的方式来存储要插入的数据
//一个ContentValues对象存储一行的值
ContentValues values = new ContentValues();
//put()方法,第一个参数key,要插入数据的列名,第二个参数value,要插入数据的值
values.put("name","小小");
values.put("sex","女");
values.put("age",10);
//insert()方法返回一个long类型的值,值为插入表中的第几行
long index = database.insert("Person", nullColumnHack, values);
//如果index等于-1,则插入错误,打个提醒
if (index != -1) {
    Toast.makeText(this,"完成插入第"+index+"行数据",Toast.LENGTH_SHORT);
}else {
    Toast.makeText(this,"插入数据失败",Toast.LENGTH_SHORT);
}
(二)删除

删除操作没有返回值

database.execSQL("delete from Person where name = '李四';");

Google也有封装好的API,delete()方法

//第一个参数:表名
String table = "Person";
//第二个参数:where语句
//注意:=后面的条件要用?代替
String whereClause = "name = ?";
//第三个参数:满足条件的值 用于代替whereClause中的?
String[] whereArgs = {"李四"};
//delete方法会将上面的内容拼成sql语句"delete from Person where name = '李四';" 再执行sql语句
//该方法返回一个整数 删除操作后影响表的行数
int lines = database.delete(table, whereClause, whereArgs);
(三)修改

修改操作没有返回值

database.execSQL("update Person set name = '张三三牛掰' where name = '张三';");

Google的update()方法

//第一个参数:表名
String table = "Person";
//第二个参数:要更新的数据 即放在set后面的内容
ContentValues values = new ContentValues();
values.put("name", "张三三牛掰");
//第三个参数:where语句
//注意:=后面的条件要用?代替
String whereClause = "name = ?";
//第四个参数:一个装着满足条件的值的数组 用于代替whereClause中的?
String[] whereArgs = {"张三"};
//update方法会将上面的内容拼成sql语句"update Person set name = '张三三牛掰' where name = '张三';"
//update方法返回的是修改表后影响的行数
int lines = database.update(table, values, whereClause, whereArgs);
(四)查询

查询操作调用的是rawQuery()方法,并在结果集返回一个游标Cursor,调用Cursor的moveToNext()方法,若有下一行,就返回true值。

Cursor cursor = database.rawQuery("select * from Person;");
while(cursor.moveToNext()){
	//当结果集中有下一条,cursor就移到下一条,获取这一行每一列的信息
    //每一列的索引从0开始
    String name = cursor.getString(0);
    //不想数第几列的话也可以通过列名来获取第几列
    String sex = cursor.getString(cursor.getColumnIndex("sex"));
    int age = cursor.getString(cursor.getColumnIndex("age"));
    String info = name+", 性别:"+sex+", 今年"+age+"岁";
    Log.d(info, "query: ");
}

Google的query()方法

String table = "Person";
//你要查询的列名 注意:该参数是个字符串数组
String[] columns = {"name","sex"};
//用selectionArgs来代替selection中的?可以防止sql注入攻击
String selection = "sex = ?";
String[] selectionArgs = {"男"};
String groupBy = null;
String having = null;
String orderBy = null;
String limit = null;
//以上条件拼成的sql语句是"select name,sex from Person where sex = '男';"
database.query(table,columns,selection,selectionArgs,groupBy,having,orderBy,limit);
//如果想要查询的语句是"select * from Person;"的话
//表名写好,后面的参数全部写null就可以了

总结

方式有无返回值处理大量数据效率灵活性sql出错概率
execSQL()、rawQuery()只有rawQuery()有
封装好的API都有

总体来看呢,自己打出来的sql总体效率会更高,自己想写什么就写什么,可以省去很多步骤,自己写起来也很方便。但自己写的出错率也会高,有时候sql语句不小心写错或者执行出错,程序就会崩溃,用户体验感会下降。

用封装好的API用起来虽然繁琐,但效果会保险很多。

建议是按照自己的需求来选择两种方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值