SQLite для приложения для дегустации еды - PullRequest
0 голосов
/ 03 июля 2018

У меня есть такой класс =>

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. Человек может проверить checkBox и сделать его true, если попробуете эту еду.

Но после закрытия приложения и его повторного запуска флажок исчезает. Becasue line1 до line8 снова работает и флажок по умолчанию заполнен false снова.

Я хочу, чтобы эти line1 до line8 работали один раз в первом запуске приложения. И после этого, если приложение закрылось и открывалось снова, продолжайте настройку последнего состояния базы данных SQLite (я не хочу инициализировать снова и снова)

Как мне это сделать?

1 Ответ

0 голосов
/ 04 июля 2018

Я считаю, что основная проблема, с которой вы столкнулись, заключается в том, что у вас сложилось впечатление, что База данных каким-то образом автоматически будет взаимодействовать или отражать объект питания. Не будет

Для сохранения статуса 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 метод получения, а также метод установки 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. Один по идентификатору, другой по названию еды. Отмечая, что последнее не рекомендуется, так как вы не можете быть уверены, какая строка обновляется, если есть несколько строк с одинаковым названием еды.

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 , были сохранены в базе данных.

...