【达内课程】SQLite(二)中现成的增删改查方法


除了使用 sql 语句,SQLiteDatabase 中提供了一个现成的方法来完成我们上一节所有的操作

新增数据 insert()

【参数】
String table数据表名
String nullColumnHack仅当第 3 个参数无效时,该参数有效,推荐取值为任意一个字段的名称
ContentValues values封装了字段名称与字段值的对象
【返回值】
新增加的记录的ID
如果增加数据出错,返回 -1
【ContentValue的常用方法】
void put(String key,?? value)向 ContentValue 对象中封装数据
void clear()清除 ContentValue 对象中的所有数据

在上一节的例子中增加两条数据:

private void callInsert() {
        String table = "users";
        String nullColumnHack = null;
        ContentValues values = new ContentValues();
        values.put("name", "Pablo");
        values.put("age", 36);
        values.put("phone", "911");
        values.put("email", "pablo@narco.com");
        long id = db.insert(table, nullColumnHack, values);
        Log.d("SQLITE", "新增加的数据id:" + id);

        //如果想要增加多条数据,应该 new ContentValues(),或者调用 values.clear()方法清空数据,再put值
        values = new ContentValues();
        values.put("name", "Steve");
        values.put("age", 28);
        db.insert(table, nullColumnHack, values);
    }

这个方法返回新增的 id,如果不成功,返回 -1

第二个参数,是防止程序崩溃的一个解决方案,因为我们第三个参数是一个完全正常的参数,所以第二个参数我们可以随便写。

insert()方法的本质也是在为我们拼接了一个 sql 语句,如果我们第三个参数为 null,会出现INSERT INTO users () VALUES ();的错误 sql,这种情况下,第二个参数就会起作用,我们建议它的值写成一个字段的值,例如 name,那么程序内部拼接出来的 sql 就是INSERT INTO users (name) VALUES (NULL);虽然没有意义,但是能保证程序不出错,所以第二个参数,仅当第三个参数没有有效值时有效。

运行程序,导出 test.db 查看数据:
在这里插入图片描述
查看 Log 日志:
在这里插入图片描述

删除数据 delete()

【参数】
String table
String whereClauseWHERE子句,不包含“WHERE”关键字,且各字段值推荐使用?表示
String[] whereArgsWHERE子句中各?对应的值,如果第 2 个参数中没有 ?,则该参数为 null 即可。
【返回值】
如果使用了有效的 whereClause 参数,则返回受影响的行数,否则返回 0
在这里插入图片描述

private void callDelete() {
        String table = "users";
        String name = "Lily";
        int age = 50;
        String whereClause = "age>" + age + " OR name='" + name + "'";
        String[] whereArgs = null;
        int affectedRows = db.delete(table, whereClause, whereArgs);
        Log.d("SQLITE", "受影响的行数" + affectedRows);
    }

可以优化为

private void callDelete() {
        String table = "users";
        String name = "Lily";
        int age = 50;
        String whereClause = "age>? OR name=?";
        String[] whereArgs = {age + "", name};
        int affectedRows = db.delete(table, whereClause, whereArgs);
        Log.d("SQL", "受影响的行数" + affectedRows);
    }

不管是什么类型的都可以改为 ?

运行程序,查看Log:
在这里插入图片描述
删除后的数据
在这里插入图片描述

查询

Cursor
【move系列方法】
boolean move(int offset)在现有位置的基础上,移动 offset 个位置
boolean moveToFirst()移动到第一条数据
boolean moveToLast()移动到最后一条数据
boolean moveToNext()移动到下一条数据
boolean moveToPrevious()移动到上一条数据
boolean moveToPosition(int position)移动到位置为 position 的数据

以上方法的返回值均为 boolean 类型,表示移动操作成功与否

每一个 Cursor 对象在初始状态时,游标都是不指向任何一条数据的,所以,每个 Cursor 对象都必须至少成功的调用一次 move 方法以后,才能获取数据

【is系列方法】
boolean isFirst()是否处于第一条数据的位置
boolean isLast()是否处于最后一条数据的位置
boolean isBeforeFirst()是否处于第一条数据之前的位置
boolean isAfterLast()是否处于最后一条数据之后的位置

【get系列方法】
int getCount()获取查询到的数据的数量
int getColumnCount()获取查询的列的数量
String[] getColumnNames()获取查询的所有列的名称
int getColumnIndex(String columnName)根据参数 columnName(列的名称)获取列的索引
??? get???(int columnIndex)根据参数 columnIndex(列的索引)获取数据,例如调用 getString(0) 则表示获取第一列的数据,得到的结果是 String 类型的结果

我们写程序查询第一条数据

private void callQuery() {
        //查询数据
        String table = "users";
        String[] columns = {"name", "age", "phone", "email"};//查询的字段列表
        String selection = null;//查询的where字句
        String[] selectionArgs = null;
        String groupBy = null;
        String having = null;
        String orderBy = null;
        //处理数据
        Cursor c = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
        if (c.moveToFirst()) {
            String name = c.getString(0);
            int age = c.getInt(1);
            String phone = c.getString(2);
            String email = c.getString(3);
            Log.d("SQLITE", "name:" + name + " age:" + age + " phone:" + phone + " email:" + email);
            c.close();
        }
    }

运行程序查看日志
在这里插入图片描述

如果想查询下一条,可以修改刚才的程序

......
//处理数据
Cursor c = db.query(table, columns, selection, selectionArgs, groupBy, having, groupBy);
c.moveToFirst();
c.moveToNext();
String name = c.getString(0);
int age = c.getInt(1);
......

查看日志
在这里插入图片描述

需要注意的是一旦我们指定了列

String[] columns = {"name","age","phone","email"};//查询的字段列表

c.getString(0)中 0、1… 是确定的了,如果再增加列,这些序号是要重新调整的,因此我们可以根据字段名获取 index

String name = c.getString(c.getColumnIndex("name"));

【遍历Cursor】
使用任何一种循环语法都可以遍历 Cursor
1、使用 while 语法

//方式一
if(c.moveToFirst()){
	while(!c.isAfterLast()){
		循环体
		c.moveToNext();
	}
}
//方式二
if(c.moveToFirst()){
	int pos = 0;
	while(post < c.getCount()){
		c.moveToPosition(post);
		循环体
		pos++;
	}
}

2、使用 do…while 语法

//方式一
if(c.moveToFirst()){
	do{
		循环体
		c.moveToNext();
	}while(!c.isAfterLast());
}
//方式二
if(c.moveToFirst()){
	do{
		循环体
	}while(c.moveToNext(););
}

3、使用 for 语法

for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
	循环体;
}

栗子:使用 CursorAdapter 显示数据查询结果

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/lv_contacts"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

item_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

MainActivity

public class MainActivity extends AppCompatActivity {
    private SQLiteDatabase db;

    private ListView listView;
    private SimpleCursorAdapter simpleCursorAdapter;
    private Cursor c;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建数据库
        createDatabase();
        //创建数据表
        createTable();
        //增加数据
        insertData();
        //删除数据
        //deleteData();
        //修改数据
        //updateData();
        //----------------------
        //现成的方法添加数据
        //callInsert();
        //现成的方法删除数据
        //callDelete();
        //现成的方法查询数据
        //callQuery();
        //callQueryNext();
        //新的查询
        c = callQueryNew();
        String[] from = {"name", "age", "phone", "email"};
        int[] to = {R.id.tv_name, R.id.tv_age, R.id.tv_phone, R.id.tv_email};
        simpleCursorAdapter = new SimpleCursorAdapter(this, R.layout.item_contact, c, from, to, 0);

        listView = (ListView) findViewById(R.id.lv_contacts);
        listView.setAdapter(simpleCursorAdapter);
    }

    private void createDatabase() {
        String name = "test.db";
        int mode = MODE_PRIVATE;
        SQLiteDatabase.CursorFactory cursorFactory = null;
        db = openOrCreateDatabase(name, mode, cursorFactory);
    }

    private void createTable() {
        String sql = "CREATE TABLE users (" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                "name VARCHAR(10) UNIQUE NOT NULL, " +
                "age INTEGER, " +
                "phone CHAR(11) UNIQUE, " +
                "email VARCHAR(32) UNIQUE" +
                ")";
        db.execSQL(sql);
    }

    private void insertData() {
        String sql1 = "INSERT INTO users " +
                "(name,age,phone,email) " +
                "values " +
                "('Errol',22,'13333333333','errol@qq.com')";
        db.execSQL(sql1);
        String sql2 = "INSERT INTO users " +
                "(name,age,phone,email) " +
                "values " +
                "('Billy',33,'18888888888','billy@qq.com')";
        db.execSQL(sql2);
    }

    private void deleteData() {
        String sql = "DELETE FROM users WHERE name = 'Tony' OR age > 30";
        db.execSQL(sql);
        Log.d("SQL", "删除成功");
    }

    private void updateData() {
        String sql = "UPDATE users SET age = 24 WHERE name = 'Errol'";
        db.execSQL(sql);
    }

    private void callInsert() {
        String table = "users";
        String nullColumnHack = null;
        ContentValues values = new ContentValues();
        values.put("name", "Pablo");
        values.put("age", 36);
        values.put("phone", "911");
        values.put("email", "pablo@narco.com");
        long id = db.insert(table, nullColumnHack, values);
        Log.d("SQLITE", "新增加的数据id:" + id);

        //如果想要增加多条数据,应该 new ContentValues(),或者调用 values.clear()方法清空数据,再put值
        values = new ContentValues();
        values.put("name", "Steve");
        values.put("age", 28);
        db.insert(table, nullColumnHack, values);
    }

    /*private void callDelete() {
        String table = "users";
        String name = "Lily";
        int age = 50;
        String whereClause = "age>" + age + " OR name='" + name + "'";
        String[] whereArgs = null;
        int affectedRows = db.delete(table, whereClause, whereArgs);
        Log.d("SQLITE", "受影响的行数" + affectedRows);
    }*/

    private void callDelete() {
        String table = "users";
        String name = "Lily";
        int age = 50;
        String whereClause = "age>? OR name=?";
        String[] whereArgs = {age + "", name};
        int affectedRows = db.delete(table, whereClause, whereArgs);
        Log.d("SQL", "受影响的行数" + affectedRows);
    }

    //查询第一条数据
    private void callQuery() {
        //查询数据
        String table = "users";
        String[] columns = {"name", "age", "phone", "email"};//查询的字段列表
        String selection = null;//查询的where字句
        String[] selectionArgs = null;
        String groupBy = null;
        String having = null;
        String orderBy = null;
        //处理数据
        Cursor c = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
        if (c.moveToFirst()) {
            String name = c.getString(0);
            int age = c.getInt(1);
            String phone = c.getString(2);
            String email = c.getString(3);
            Log.d("SQLITE", "name:" + name + " age:" + age + " phone:" + phone + " email:" + email);
            c.close();
        }
    }

    //查询第二条数据
    private void callQueryNext() {
        //查询数据
        String table = "users";
        String[] columns = {"name", "age", "phone", "email"};//查询的字段列表
        String selection = null;//查询的where字句
        String[] selectionArgs = null;
        String groupBy = null;
        String having = null;
        String orderBy = null;
        //处理数据
        Cursor c = db.query(table, columns, selection, selectionArgs, groupBy, having, groupBy);
        c.moveToFirst();
        c.moveToNext();
        String name = c.getString(0);
        int age = c.getInt(1);
        String phone = c.getString(2);
        String email = c.getString(3);
        Log.d("SQLITE", "name:" + name + " age:" + age + " phone:" + phone + " email:" + email);
        c.close();
    }

    private Cursor callQueryNew() {
        //查询数据
        String table = "users";
        String[] columns = {"_id", "name", "age", "phone", "email"};//查询的字段列表
        String selection = null;//查询的where字句
        String[] selectionArgs = null;
        String groupBy = null;
        String having = null;
        String orderBy = null;
        //处理数据
        Cursor c = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
        return c;
    }
}

把之前的程序卸载,重新运行程序
在这里插入图片描述

注意,使用CursorAdapter,在创建表时需要新增“_id”字段。名称固定

查询时也需要查询出此字段才可以

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值