取出SQLite数据(基本游标)

前面一节中已经为Starbuzz创建了一个SQLite帮助器。

目前还是从Java Drink类获取数据,这时候要修改这个应用从SQLite数据库获取数据。

本文所有代码均存放于
https://github.com/MADMAX110/Starbuzz

一、修改DrinkActivity来使用Starbuzz数据库

基本步骤:

1、得到Starbuzz数据库的一个引用

2、创建一个游标从数据库读取数据

3、导航到饮料记录

4、在DrinkActiviy中显示饮料的详细信息

1、得到数据库引用

首先需要用上一章创建的SQLite帮助器得到Starbuzz数据库的一个引用。为此我们先要得到SQLite帮助器的一个引用。

java 复制代码
    SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);

然后调用SQLite帮助器的getReadableDatabase()getWriteableDatabase() 得到数据库一个引用。前者只读,后者可以进行更新。这两者都会返回一个SQLiteDatabase对象,可以用来访问数据库。

java 复制代码
    SQLiteDatabase db = starbuzzDatabaseHelper.getReadableDatabase();
    SQLiteDatabase db = starbuzzDatabaseHelper.getWritableDatabase();

如果Android没能得到数据库的一个引用,会抛出一个SQLiteExeception异常。例如,如果调用getWriteableDatabase来读写数据库,但是由于磁盘已满而无法写入数据库就会发生这种情况。

如果得到异常就可以使用一个Toast(一个弹出式消息)告诉用户这个消息不可用。

得到数据库的一个引用后,就可以使用游标从数据库中获取数据了。

2、用游标从数据库获取数据

创建游标

java 复制代码
Cursor cursor = db.query(...);

最简单的数据库查询是从一个数据库的一个表中返回所有记录, 第一个参数是表名,第二个参数表示想要返回这些列中的值,如果想要返回一个表中的所有记录,将这些参数设置为null。

java 复制代码
Cursor cursor = db.query("DRINK", new String[]{"_id", "NAME", "DESCRIPTION"}, null, null, null, null, null);

默认情况下,表中数据按_id的顺序显示,这是因为输入数据时的顺序。如果希望按NAME的升序顺序,可以使用以下代码。

java 复制代码
    Cursor cursor = db.query("DRINK", new String[]{"_id", "NAME", "DESCRIPTION"}, null, null, null, null, null, "NAME ASC");

ASC关键字表示你希望按升序对这一列排序。默认的都会按升序队列排序,所以也可以省略ASC,倘若要以降序排序则要使用DESC。

还可以对多个列进行排序,例如对FAVORITE降序排列,然后对NAME按升序排列。

java 复制代码
Cursor cursor = db.query("DRINK", new String[]{"_id", "NAME", "DESCRIPTION"}, null, null, null, null, null, "FAVORITE DESC, NAME");

为数据设置过滤条件,返回特定的记录:例如返回DRINK列表中饮料名为Lattle的记录:

java 复制代码
Cursor cursor = db.query("DRINK", new String[]{"_id", "NAME", "DESCRIPTION"},  "NAME = ?", new String[] {"Lattle"}, null, null, null);

或是DRINK列表中_id为1的记录:

java 复制代码
    Cursor cursor = db.query("DRINK", new String[]{"_id", "NAME", "DESCRIPTION"},  "_id = ?", new String[] {Integer.toString(1)}, null, null, null);

3、导航到游标记录

要从一个游标获取某个特定记录的值,首先要导航到这个记录。

游标主要有4个方法,这些方法分别是moveToFirst、moveToLast、moveToPrevious、moveToNext。

要返回游标的第一个记录可以使用moveToFirst方法,如果发现一个记录,这个方法就会返回一个true值。如果游标未返回任何记录就会返回false。

java 复制代码
if (cursor.moveToFirst()){
}

同理、moveToLast是返回游标最后一个记录,moveToPrevious是前一个记录,moveToNext是后一个记录。

4、获取游标值

从第0列获取字符串,从第2列获取数值。

java 复制代码
String name = cursor.getString(0);
int imageRes = cursor.getInt(2);

最后,关闭游标和数据库。

java 复制代码
cursor.close();
db.close();

完整的DrinkActivity代码

java 复制代码
package com.hfad.starbuzz;

import androidx.appcompat.app.AppCompatActivity;

import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class DrinkActivity extends AppCompatActivity {

    public static final String EXTRA_DRINKID = "drinkId";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drink);

        int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);

        SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);
        try {
            SQLiteDatabase db = starbuzzDatabaseHelper.getReadableDatabase();
            Cursor cursor = db.query("DRINK",
                    new String[]{"NAME", "DESCRIPTION", "IMAGE_RESOURCE_ID"},
                    "_id = ?",
                    new String[] {Integer.toString(drinkId)},
                    null, null, null);
            if (cursor.moveToFirst()) {
                String nameText = cursor.getString(0);
                String descriptionText = cursor.getString(1);
                int photoId = cursor.getInt(2);

                TextView name = (TextView) findViewById(R.id.name);
                name.setText(nameText);

                TextView description = (TextView) findViewById(R.id.description);
                description.setText(descriptionText);

                ImageView photo = (ImageView) findViewById(R.id.photo);
                photo.setImageResource(photoId);
                photo.setContentDescription(nameText);
            }
            cursor.close();
            db.close();
        }catch (SQLException e){
            Toast toast = Toast.makeText(this,
                    "Database unavailable",
                    Toast.LENGTH_SHORT);
            toast.show();
        }
    }
}

二、修改DrinkCategoryActivity来使用Starbuzz数据库

这里的步骤与之前的有所不同,因为这里要显示一个列表视图,它使用饮料数据作为它的数据源。我们要把这个数据的数据源转换为Starbuzz数据库,

1、创建一个游标从数据库读取饮料数据。

2、将列表视图的数组适配器替换为一个游标适配器。

第一步与之前的一样,这里需要做的是替换列表视图中的数组数据。

简单游标适配器

原理:

1、列表视图向适配器请求数据

2、适配器向游标请求数据库中的数据

3、适配器向列表视图返回数据

使用简单游标适配器的做法与使用数组适配器很类似:要初始化适配器,然后把它关联到列表视图。

java 复制代码
    SimpleCursorAdapter listAdapter = new SimpleCursorAdapter(this , //当前活动
            android.R.layout.simple_list_item_1,//在列表视图中对应每一行显示一个值
            cursor,//这是游标
            new String[]{"NAME"},//使用游标的哪些列
            new int[]{android.R.id.text1},//希望在那些视图中显示这些数据
            0);//用来确定游标的行为,通常为0,这是默认值,也可以注册一个内容观察器
    listDrinks.setAdapter(listAdapter);

修改后的DrinkCategoryActivity代码:

java 复制代码
package com.hfad.starbuzz;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class DrinkCategoryActivity extends AppCompatActivity {

    private SQLiteDatabase db;
    private Cursor cursor;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drink_category);
        ListView listDrinks = (ListView) findViewById(R.id.list_drinks);
        SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);
        try {
            db = starbuzzDatabaseHelper.getReadableDatabase();
            cursor = db.query("DRINK",
                    new String[]{"_id", "NAME"},
                    null, null, null, null, null);
            SimpleCursorAdapter listAdapter = new SimpleCursorAdapter(this , //当前活动
                    android.R.layout.simple_list_item_1,//在列表视图中对应每一行显示一个值
                    cursor,//这是游标
                    new String[]{"NAME"},//使用游标的哪些列
                    new int[]{android.R.id.text1},//希望在那些视图中显示这些数据
                    0);//用来确定游标的行为,通常为0,这是默认值,也可以注册一个内容观察器
            listDrinks.setAdapter(listAdapter);
        }catch(SQLException e){
            Toast toast = Toast.makeText(this, "Database unavailable", Toast.LENGTH_SHORT);
            toast.show();
        }

        AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (position == 0) {
                    Intent intent = new Intent(DrinkCategoryActivity.this, DrinkCategoryActivity.class);
                    startActivity(intent);
                }
                Intent intent = new Intent(DrinkCategoryActivity.this, DrinkActivity.class);
                //向意图增加所单击列表项的ID,第一个参数表示使用这个常量名表示意图中的额外信息名
                //这样就能知道DrinkCategoryActivity和DrinkActivity在使用同一个字符串
                //创建DrinkActivity活动时要增加这个常量。
                intent.putExtra(DrinkActivity.EXTRA_DRINKID, (int)id);
                startActivity(intent);
            }
        };

       listDrinks.setOnItemClickListener(itemClickListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cursor.close();
        db.close();
    }
}
相关推荐
程序喵大人4 小时前
SQLITE问题整理
开发语言·数据库·c++·sqlite
计算机程序设计小李同学1 天前
基于Python的在线零食购物商城系统的设计与实现
数据库·sqlite
openinstall全渠道统计1 天前
开发者指南:广告投放系统搭建与前后端数据打通全流程
windows·git·oracle·eclipse·sqlite·github
Sammyyyyy2 天前
Django 6.0 发布,新增原生任务队列与 CSP 支持
数据库·后端·python·django·sqlite·servbay
赤龙绕月3 天前
SQLite NET
数据库·sqlite
透明的玻璃杯4 天前
sqlite数据库链接池二
数据库·oracle·sqlite
透明的玻璃杯4 天前
sqlite数据库连接池
jvm·数据库·sqlite
越甲八千5 天前
ASGI和AWSIG区别
数据库·python·sqlite
码农12138号5 天前
Bugku 2023 HackINI Virtual Shop 和 2023 HackINI Virtual Shop 2
web安全·sqlite·sql注入
飞Link6 天前
【Django】Django 调用外部 Python 程序的完整指南
后端·python·django·sqlite