【问题标题】:Adding and Deleting Items from Database从数据库中添加和删除项目
【发布时间】:2021-04-17 17:39:32
【问题描述】:

我是 Android Studio 的新手,我正在尝试创建一个允许用户创建自己的库存项目的库存应用程序。我正在使用 SQlite 数据库来执行此操作。我已经创建了存储结果的 DBHelper 类和 Item 类。

但是,我不确定如何在我在一些 FIXME cmets 中编写的 DisplayInventory 类 (MainActivity) 中继续此操作,以帮助显示我在说什么。

DisplayInventory 类

// TESTING SQLite CODE HERE

public void insertItem(int position) {
    //FIXME: This is where I need to ADD items to the database
    // inventoryDB.addItem();
    mInventoryItemList.add(position, new InventoryItem(R.drawable.ic_delete, "Tap to Edit", "Items: ", (android.widget.Button) Button, (android.widget.Button) Button));
    mAdapter.notifyItemInserted(position);
}

public void removeItem(int position) {
    // FIXME: This is where I DELETE items from database
    // inventoryDB.deleteItem(); <== This method needs to be written in InventoryDBHelper class
    mInventoryItemList.remove(position);
    mAdapter.notifyItemRemoved(position);
}

public void createExampleList() {
    mInventoryItemList = new ArrayList<>();

    // get all items from the database
    Item[] items = inventoryDB.getAllItems();
    // loop through all items to build the array list
    for (int i = 0; i < items.length; ++i){
        // FIXME: this is where I need to build my ArrayList based on the contents of the DB
        //  for new users this will be empty. However, as they add items then the database
        //  will be populated and this will return data the next time.
    }

}

//TESTING CODE ENDS HERE

InventoryDBHelper

public class InventoryDBHelper extends SQLiteOpenHelper {

private Context context;
private static final String DATABASE_NAME = "InventoryList.db";
private static final int DATABASE_VERSION = 1;

private static final String TABLE_NAME = "my_inventory";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_TITLE = "item_name";
private static final String COLUMN_OWNER = "item_owner";
private static final String COLUMN_ITEMNUMBER = "number_items";

public InventoryDBHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.context = context;
}

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
    String query = "CREATE TABLE " + TABLE_NAME +
                    " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    COLUMN_TITLE + " TEXT, " +
                    COLUMN_OWNER + " TEXT, " +
                    COLUMN_ITEMNUMBER + " INTEGER);";
    sqLiteDatabase.execSQL(query);

}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
    onCreate(sqLiteDatabase);
}

void addItem(String title, String owner, int numItem) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues cv = new ContentValues();

    cv.put(COLUMN_TITLE, title);
    cv.put(COLUMN_OWNER, owner);
    cv.put(COLUMN_ITEMNUMBER, numItem);
    long result = db.insert(TABLE_NAME, null, cv);

    if(result == -1) {
        Toast.makeText(context, "FAILED", Toast.LENGTH_SHORT).show();
    }
    else {
        Toast.makeText(context, "Added Successful", Toast.LENGTH_SHORT).show();
    }
}

public Item[] getAllItems(){
    // list of items to return
    Item[] returnItems;

    // initialize a readable database connection
    SQLiteDatabase db = this.getReadableDatabase();

    String query = "SELECT " +
            COLUMN_ID + "," +
            COLUMN_TITLE + "," +
            COLUMN_OWNER + "," +
            COLUMN_ITEMNUMBER +
            " FROM " + TABLE_NAME + ";";

    Cursor cursor = db.rawQuery(query, null);
    returnItems = unpackRecordData(cursor);
    cursor.close();

    return returnItems;
}

private Item[] unpackRecordData(Cursor cursor){
    Item[] items = new Item[cursor.getCount()];

    int i = 0;
    while (cursor.moveToNext()){
        Item item = new Item(
                // Item.id
                cursor.getInt(
                        cursor.getColumnIndexOrThrow(COLUMN_ID)
                ),
                // Item.title
                cursor.getString(
                        cursor.getColumnIndexOrThrow(COLUMN_TITLE)
                ),
                // Item.owner
                cursor.getString(
                        cursor.getColumnIndexOrThrow(COLUMN_OWNER)
                ),
                // Item.itemNumber
                cursor.getInt(
                        cursor.getColumnIndexOrThrow(COLUMN_ITEMNUMBER)
                )
        );
        // add Item to the list of items
        items[i] = item;
    }

    return items;
}

}

物品类

public class Item {

// Item Database columns to properties
private int id;
private String title;
private String owner;
private int itemNumber;

// class constructor
public Item(int id, String title, String owner, int itemNumber){
    this.id = id;
    this.title = title;
    this.owner = owner;
    this.itemNumber = itemNumber;
}

// getters and setters
public void setId(int id){
    this.id = id;
}
public int getId(){
    return this.id;
}

public void setTitle(String title){
    this.title = title;
}
public String getTitle(){
    return this.title;
}

public void setOwner(String owner){
    this.owner = owner;
}
public String getOwner(){
    return this.owner;
}

public void setItemNumber(int itemNumber){
    this.itemNumber = itemNumber;
}
public int getItemNumber(){
    return this.itemNumber;
}

}

【问题讨论】:

  • 使用你的 db 类作为单例,那么所有对 db 的操作都应该在后台线程中

标签: java sqlite android-studio


【解决方案1】:

以下示例显示了正在执行的所有三种类型的操作。它基于您的代码,并有一些 cmets 来解释 建议的更改添加(注释掉)和代码。

第一个InventoryDBHelper

public class InventoryDBHelper extends SQLiteOpenHelper {

    private Context context;
    private static final String DATABASE_NAME = "InventoryList.db";
    private static final int DATABASE_VERSION = 1;
    private SQLiteDatabase db; //<<<<<<<< ADDED

    /*
        CHANGED to public (can be useful)
     */
    public static final String TABLE_NAME = "my_inventory";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_TITLE = "item_name";
    public static final String COLUMN_OWNER = "item_owner";
    public static final String COLUMN_ITEMNUMBER = "number_items";

    private static volatile InventoryDBHelper instance;

    private InventoryDBHelper(Context context) {    //<<<<<<<<<< CHANGED TO PRIVATE
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        db = this.getWritableDatabase(); // Instantiates db variable that has full scope
        this.context = context;
    }

    /*
        ADDED so a singleton is used
     */
    public static InventoryDBHelper getInstance(Context context) {
        if (instance == null) {
            instance = new InventoryDBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        String query = "CREATE TABLE " + TABLE_NAME +
                " (" + COLUMN_ID + " INTEGER PRIMARY KEY," + //" INTEGER PRIMARY KEY AUTOINCREMENT," <<<<<<<<<< NO NEED FOR AUTOINCREMENT (has overheads)
                COLUMN_TITLE + " TEXT, " +
                COLUMN_OWNER + " TEXT, " +
                COLUMN_ITEMNUMBER + " INTEGER);";
        sqLiteDatabase.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(sqLiteDatabase);
    }

    long addItem(String title, String owner, int numItem) { //<<<<<<<<<< CHANGED so result can be returned
        // SQLiteDatabase db = this.getWritableDatabase(); //<<<<<<<<<< NOT NEEDED with db as class variable
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_TITLE, title);
        cv.put(COLUMN_OWNER, owner);
        cv.put(COLUMN_ITEMNUMBER, numItem);
        long result = db.insert(TABLE_NAME, null, cv);

        if(result == -1) {
            Toast.makeText(context, "FAILED", Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(context, "Added Successful", Toast.LENGTH_SHORT).show();
        }
        return result; //<<<<<<<< ADDED might as well return the result
    }

    /*
        ADDED so you can add from a passed item
     */
    long addItem(Item item) {
        return addItem(item.getTitle(),item.getOwner(),item.getItemNumber());
    }


    public Item[] getAllItems(){
        // list of items to return
        Item[] returnItems;

        // initialize a readable database connection
        //SQLiteDatabase db = this.getReadableDatabase(); //<<<<<<<<<< NOT NEEDED HERE
        // PS getReadable gets a writeable database in most situations

        /* NOT NEEDED HERE
        String query = "SELECT " +
                COLUMN_ID + "," +
                COLUMN_TITLE + "," +
                COLUMN_OWNER + "," +
                COLUMN_ITEMNUMBER +
                " FROM " + TABLE_NAME + ";";

         */

        // ADDED use the convienence query method equivalent to SELECT * FROM my_inventory (SQL is built for you)
        Cursor cursor = db.query(TABLE_NAME,null,null,null,null,null,null);
        //Cursor cursor = db.rawQuery(query, null);
        returnItems = unpackRecordData(cursor);
        cursor.close();
        return returnItems;
    }

    /*
        ADDED to remove an item from
     */
    long removeItem(long itemId) {
        return db.delete(TABLE_NAME,COLUMN_ID+"=?",new String[]{String.valueOf(itemId)});
    }
    /*
        ADDED to allow removal of an Item via Item object
     */
    long removeItem(Item item) {
        return removeItem(item.getId());
    }

    private Item[] unpackRecordData(Cursor cursor){
        Item[] items = new Item[cursor.getCount()];

        int i = 0;
        while (cursor.moveToNext()){
            Item item = new Item(
                    // Item.id
                    cursor.getInt(
                            cursor.getColumnIndexOrThrow(COLUMN_ID)
                    ),
                    // Item.title
                    cursor.getString(
                            cursor.getColumnIndexOrThrow(COLUMN_TITLE)
                    ),
                    // Item.owner
                    cursor.getString(
                            cursor.getColumnIndexOrThrow(COLUMN_OWNER)
                    ),
                    // Item.itemNumber
                    cursor.getInt(
                            cursor.getColumnIndexOrThrow(COLUMN_ITEMNUMBER)
                    )
            );
            // add Item to the list of items
            items[i++] = item; //ERROR FIXED was i so i was always 0 not 0 1 2 etc
        }
        return items;
    }
}
  • 请参阅 AUTOINCREMENT 了解不使用 AUTOINCREMENT 的更多原因

Item 没有改变(虽然我建议使用 long 而不是 int 作为 id)

  • SQLite rowid(您的 id 列是 rowid 的别名)可以是 64 位有符号整数(对于 int 而言太大)。

从数据库中添加、提取和删除项目的示例如下:-

public class MainActivity extends AppCompatActivity {

    InventoryDBHelper inventoryDBHelper; //<<<<<<<<< Want to use the Database in this activity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        inventoryDBHelper = InventoryDBHelper.getInstance(this); // Gets an instance of the Database

        //EXAMPLE Examples of Adding Items
        inventoryDBHelper.addItem("MyItem","Fred",1);
        inventoryDBHelper.addItem(new Item(-1000 /* irrelevant when adding*/,"Another Item","Mary",2));

        //EXAMPLE Get a list of all Items
        Item[] items = inventoryDBHelper.getAllItems();

        //EXAMPLE  Remove all Items
        for(Item i: items) {
            Log.d("INVENTRYINFO","Attempting to remove Item " + i.getTitle());
             if (inventoryDBHelper.removeItem(i) > 0) {
                 Toast.makeText(this,"Item " + i.getTitle() + " deleted",Toast.LENGTH_LONG).show();
             } else {
                 Toast.makeText(this,"Item " + i.getTitle() + " NOT DELETED",Toast.LENGTH_LONG).show();
             }
            // could use inventoryDBHelper.removeItem(i.getId()); //instead
        }
    }
}

您只需要根据自己的需要进行调整。

上面是一个工作示例(设计为运行一次)它添加 2 个项目,提取它们作为一个项目数组,然后使用该列表来 全部删除

在 for each 循环中有一个断点,可以删除以下项目:-

  • 即已添加和提取 2 项

在进行之后(在所有项目都被删除之后),日志包含:-

D/INVENTRYINFO: Attempting to remove Item MyItem
D/INVENTRYINFO: Attempting to remove Item Another Item

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-08
    • 2017-01-29
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多