取出SQLite数据(基本游标)

前面一节中已经为Starbuzz创建了一个SQLite帮助器。
目前还是从Java Drink类获取数据,这时候要修改这个应用从SQLite数据库获取数据。
本文所有代码均存放于
https://github.com/MADMAX110/Starbuzz

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

基本步骤:
1、得到Starbuzz数据库的一个引用
2、创建一个游标从数据库读取数据
3、导航到饮料记录
4、在DrinkActiviy中显示饮料的详细信息

1、得到数据库引用

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

    SQLiteOpenHelper starbuzzDatabaseHelper = new StarbuzzDatabaseHelper(this);

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

    SQLiteDatabase db = starbuzzDatabaseHelper.getReadableDatabase();
    SQLiteDatabase db = starbuzzDatabaseHelper.getWritableDatabase();

如果Android没能得到数据库的一个引用,会抛出一个SQLiteExeception异常。例如,如果调用getWriteableDatabase来读写数据库,但是由于磁盘已满而无法写入数据库就会发生这种情况。
如果得到异常就可以使用一个Toast(一个弹出式消息)告诉用户这个消息不可用。
得到数据库的一个引用后,就可以使用游标从数据库中获取数据了。

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

创建游标

Cursor cursor = db.query(...);

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

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

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

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

ASC关键字表示你希望按升序对这一列排序。默认的都会按升序队列排序,所以也可以省略ASC,倘若要以降序排序则要使用DESC。
还可以对多个列进行排序,例如对FAVORITE降序排列,然后对NAME按升序排列。

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

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

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

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

    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。

if (cursor.moveToFirst()){
}

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

4、获取游标值

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

String name = cursor.getString(0);
int imageRes = cursor.getInt(2);

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

cursor.close();
db.close();

完整的DrinkActivity代码

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、适配器向列表视图返回数据
使用简单游标适配器的做法与使用数组适配器很类似:要初始化适配器,然后把它关联到列表视图。

    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代码:

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();
    }
}

你可能感兴趣的:(Android实践,sqlite)