SQLite用于美食应用程序

时间:2018-07-03 13:53:14

标签: android sqlite android-sqlite

我有一个像这样的课程=>

public class food{
       private String foodName;
       private boolean isTasting;
       private int foodNum;

       food(String foodName,boolean isTasting){
            this.foodName=foodName;
            this.isTasting=isTasting;
       }
       public String getFoodName(){
            return foodName;
       }

}

在我的MainActivity类中,我创建了一个食物对象数组,并将它们添加到SQLite数据库中。

public class MainActivity extends Activity {
    MyDBHandler dbHandler;
    food[] foods= new foods[4];

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

        dbHandler = new MyDBHandler(this, null, null, 1);

         foods[0]=new food("apple",false);    //line1
         foods[1]=new food("butter",false);    //line2
         foods[2]=new food("cheese",false);    //line3
         foods[3]=new food("eggs",false);      //line4

         dbHandler.addFood(foods[0]);        //line5
         dbHandler.addFood(foods[1]);       //line6
         dbHandler.addFood(foods[2]);       //line7
         dbHandler.addFood(foods[3]);       //line8
    }
}

我的MyDBHandler类=>

public class MyDBHandler extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME ="foodList.db";
    public static final String TABLE_FOODS = "foods";
    public static final String COLUMNS_ID = "foodNum";
    public static final String COLUMNS_FOODNAME = "foodName";

    public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String query =  "CREATE TABLE "+ TABLE_FOODS+ "("+
                COLUMNS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMNS_FOODNAME + " TEXT " +
                ");";
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(" DROP TABLE IF EXISTS " + TABLE_FOODS);
        onCreate(db);
    }
    //Add new row to database
    public void addFood(food food){
        ContentValues values = new ContentValues();
        values.put(COLUMNS_FOODNAME,food.getFoodName());
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_FOODS,null,values);
        db.close();
    }

}

我默认将isTaste数据字段初始化为false。如果可以品尝该食物,则可以选中该复选框并使其true

但是在应用程序关闭并再次启动后,复选框消失了。 由于line1line8再次起作用,并且复选框再次默认填充false

我希望这些line1line8在第一个启动应用中工作一次。此后,如果应用关闭并再次打开,则继续SQLite数据库的最后状态。我不想一次又一次地初始化)

我该怎么办?

1 个答案:

答案 0 :(得分:0)

我相信您的核心问题是,您对数据库的印象是,它将以某种方式自动与食物对象进行交互或反映食物对象。不会的

要保留 isTaste 状态,则需要更新数据库中的相应数据。

因此,您需要在其中添加 isTaste 值的列。 SQLite没有布尔类型的列,因此您可以使用INTEGER列类型,其中0代表false,任何非零值代表true。

所以我建议添加以下行:-

    public static final String COLUMN_ISTASTE = "foodIsTaste";

然后更改:-

@Override
public void onCreate(SQLiteDatabase db) {
    String query =  "CREATE TABLE "+ TABLE_FOODS+ "("+
            COLUMNS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            COLUMNS_FOODNAME + " TEXT " 
            ");";
    db.execSQL(query);
}

至:-

@Override
public void onCreate(SQLiteDatabase db) {
    String query =  "CREATE TABLE "+ TABLE_FOODS+ "("+
            COLUMNS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            COLUMNS_FOODNAME + " TEXT, " + //<<< COMMA ADDED after TEXT
            COLUMN_ISTASTE + " INTEGER DEFAULT 0" + //<<<< ADDED
            ");";
    db.execSQL(query);
}

因此添加了一个列,用于存储 isTaste 值(如果该列未提供值,则默认为0)。

您可能希望更改addFood或添加第二个addFood方法,以设置 foodIsTaste 列。或作为第三种替代方法,是通过传递设置两个值的食物对象的方法。

新的addFood方法,用于添加食物和foodIsTaste列的状态作为单独的参数。

//Add new row to database, specifying the value for isTaste
public void addFood(food food, boolean isTaste){
    ContentValues values = new ContentValues();
    values.put(COLUMNS_FOODNAME,food.getFoodName());
    values.put(COLUMN_ISTASTE,isTaste);
    SQLiteDatabase db = getWritableDatabase();
    db.insert(TABLE_FOODS,null,values);
    db.close();
}

新的addFood方法,该方法根据传递的食物对象添加食物和foodIstaste列的状态。

  • 注意,已将 isTasting 的getter方法和setter方法setTasting添加到 food 类中,具体如下:

    public boolean isTasting() { return isTasting; } public void setTasting(boolean tasting) { isTasting = tasting; }

:-

public void addFoodAlternative(food food) {
    ContentValues values = new ContentValues();
    values.put(COLUMNS_FOODNAME,food.getFoodName());
    values.put(COLUMN_ISTASTE,food.isTasting());
    SQLiteDatabase db = this.getWritableDatabase();
    db.insert(TABLE_FOODS,null,values);
    db.close();
}

您还需要一些方法来允许更改 isTaste 状态。例如这是两种允许更新 foodIsTaste 列的方法。一个根据ID,另一个根据食物名称。请注意,不建议使用后者,因为如果有多个具有相同食物名称的行,您将无法确定更新哪一行。

public void updateTaste(long id, boolean isTaste) {
    ContentValues values = new ContentValues();
    values.put(COLUMN_ISTASTE,isTaste);
    SQLiteDatabase db = this.getWritableDatabase();
    db.update(TABLE_FOODS,values,COLUMNS_ID + "=?", new String[]{String.valueOf(id)});
    db.close();
}

public void updateTaste(String foodname, boolean isTaste) {
    ContentValues values = new ContentValues();
    values.put(COLUMN_ISTASTE,isTaste);
    SQLiteDatabase db = this.getWritableDatabase();
    db.update(TABLE_FOODS,values,COLUMNS_FOODNAME + "=?", new String[]{String.valueOf(foodname)});
    db.close();
}

使用上述内容,您应该能够在两次运行之间管理和保留 isTaste 状态。

放在一起

如果遵循上述要求,那么您将拥有以下代码:-

food.java

public class food{
    private String foodName;
    private boolean isTasting;
    private long foodNum;

    food(String foodName,boolean isTasting){
        this.foodName=foodName;
        this.isTasting=isTasting;
    }
    public String getFoodName(){
        return foodName;
    }

    public boolean isTasting() {
        return isTasting;
    }

    public void setTasting(boolean tasting) {
        isTasting = tasting;
    }
}

MyDBHanlder.java

public class MyDBHandler extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME ="foodList.db";
    public static final String TABLE_FOODS = "foods";
    public static final String COLUMNS_ID = "foodNum";
    public static final String COLUMNS_FOODNAME = "foodName";
    public static final String COLUMN_ISTASTE = "foodIsTaste";

    public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String query =  "CREATE TABLE "+ TABLE_FOODS+ "("+
                COLUMNS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMNS_FOODNAME + " TEXT, " + //<<< COMMA ADDED after TEXT
                COLUMN_ISTASTE + " INTEGER DEFAULT 0" + //<<<< ADDED
                ");";
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(" DROP TABLE IF EXISTS " + TABLE_FOODS);
        onCreate(db);
    }
    //Add new row to database
    public void addFood(food food){
        ContentValues values = new ContentValues();
        values.put(COLUMNS_FOODNAME,food.getFoodName());
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_FOODS,null,values);
        db.close();
    }

    //Add new row to database, specifying the value for isTaste
    public void addFood(food food, boolean isTaste){
        ContentValues values = new ContentValues();
        values.put(COLUMNS_FOODNAME,food.getFoodName());
        values.put(COLUMN_ISTASTE,isTaste);
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_FOODS,null,values);
        db.close();
    }

    public void addFoodAlternative(food food) {
        ContentValues values = new ContentValues();
        values.put(COLUMNS_FOODNAME,food.getFoodName());
        values.put(COLUMN_ISTASTE,food.isTasting());
        SQLiteDatabase db = this.getWritableDatabase();
        db.insert(TABLE_FOODS,null,values);
        db.close();
    }

    public void updateTaste(long id, boolean isTaste) {
        ContentValues values = new ContentValues();
        values.put(COLUMN_ISTASTE,isTaste);
        SQLiteDatabase db = this.getWritableDatabase();
        db.update(TABLE_FOODS,values,COLUMNS_ID + "=?", new String[]{String.valueOf(id)});
        db.close();
    }

    public void updateTaste(String foodname, boolean isTaste) {
        ContentValues values = new ContentValues();
        values.put(COLUMN_ISTASTE,isTaste);
        SQLiteDatabase db = this.getWritableDatabase();
        db.update(TABLE_FOODS,values,COLUMNS_FOODNAME + "=?", new String[]{String.valueOf(foodname)});
        db.close();
    }
}

如果 MainActivity.java 具有:-

    MyDBHandler dbHandler;
    food[] foods= new food[4]; //<<<< Correction food[4] not foods[4]
    dbHandler = new MyDBHandler(this, null, null, 1);
    SQLiteDatabase db = dbHandler.getWritableDatabase(); // Get Database

    //Only add rows for the first run
    if (DatabaseUtils.queryNumEntries(db,MyDBHandler.TABLE_FOODS) == 0) {
        Log.d("DB INIT INFO","The database contains no rows so adding 4 rows");
        foods[0]=new food("apple",false);    //line1
        foods[1]=new food("butter",true);    //line2
        foods[2]=new food("cheese",false);    //line3
        foods[3]=new food("eggs",false);      //line4

        dbHandler.addFoodAlternative(foods[0]);        //line5
        dbHandler.addFoodAlternative(foods[1]);       //line6
        dbHandler.addFoodAlternative(foods[2]);       //line7
        dbHandler.addFoodAlternative(foods[3]);       //line8
    }

    dbHandler.updateTaste("eggs",true);
    db = dbHandler.getWritableDatabase(); // Need to re-open database

    // Get the data from the database
    Cursor mCsr = db.query(MyDBHandler.TABLE_FOODS, null,null,null,null,null,null);

    // Loop through each row of the extracted data outputting the values to the log
    while (mCsr.moveToNext()) {
        boolean istatse = mCsr.getInt(mCsr.getColumnIndex(MyDBHandler.COLUMN_ISTASTE)) > 0;
        Log.d("ROWINFO","Row at position " +
                String.valueOf(mCsr.getPosition() + 1) +
                " " +MyDBHandler.COLUMNS_ID + " = " +
                String.valueOf(mCsr.getLong(mCsr.getColumnIndex(MyDBHandler.COLUMNS_ID))) +
                " " + MyDBHandler.COLUMNS_FOODNAME + " = " +
                mCsr.getString(mCsr.getColumnIndex(MyDBHandler.COLUMNS_FOODNAME)) +
                " " + MyDBHandler.COLUMN_ISTASTE + " = " +
                String.valueOf(istatse)
        );
    }
}

首次运行该应用程序时( 删除该应用程序的数据以反映其首次运行,以便删除数据库 ),然后日志将显示:-

07-03 23:28:44.881 2566-2566/? D/DB INIT INFO: The database contains no rows so adding 4 rows
07-03 23:28:44.905 2566-2566/? D/ROWINFO: Row at position 1 foodNum = 1 foodName = apple foodIsTaste = false
    Row at position 2 foodNum = 2 foodName = butter foodIsTaste = true
    Row at position 3 foodNum = 3 foodName = cheese foodIsTaste = false
    Row at position 4 foodNum = 4 foodName = eggs foodIsTaste = true

随后运行时,日志将显示相同的信息,只是行 数据库不包含任何行,因此要添加4行

即 包括 isTaste 值的数据已保存在数据库中。