Ограничить таблицу SQLite определенным количеством строк

У меня есть обработчик Sqlite для сохранения и извлечения строк, которые содержат некоторые данные. Что я хочу, это ограничить количество строк до 10 только в любой данный момент. Предположим, что уже добавлено 10 строк, и я сохраняю еще одну строку, она должна сначала удалить самую старую строку, а затем вставить последнюю запись. Я искал его, и единственный ответ, который я нашел, — это Создание триггера. Но в SQLite не было объяснения, как это сделать. Есть ли лучший способ сделать это?

public class SQLiteHandler extends SQLiteOpenHelper {

    private static final String TAG = "sammy_";

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "android_api";

    // Profile Settings table name
    private static final String TABLE_ITEM = "item";

    // Profile Settings information names
    private static final String KEY_ID = "id";
    private static final String KEY_TYPE = "type";
    private static final String KEY_TITLE = "title";
    private static final String KEY_SUBTITLE = "subtitle";
    private static final String KEY_APIID = "apiid";



    public SQLiteHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {

        String CREATE_PROF_TABLE = "CREATE TABLE " + TABLE_ITEM + "("+KEY_ID+" INTEGER PRIMARY KEY, "+KEY_TYPE+" TEXT, "+KEY_TITLE+" TEXT, "+KEY_SUBTITLE+" TEXT, "+KEY_APIID+" TEXT" + ")";

        db.execSQL(CREATE_PROF_TABLE);

        System.out.println("sammy_Database tables created");
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEM);

        // Create tables again
        onCreate(db);
    }


    /**
     * Storing Prof_settings details in database
     * */
    public void addContents(String type, String title, String subtitle, String apiid){

        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();

        values.put(KEY_TYPE, type);
        values.put(KEY_TITLE, title);
        values.put(KEY_SUBTITLE, subtitle);
        values.put(KEY_APIID, apiid);

        long id = db.insert(TABLE_ITEM, null, values); // insert to 1st row
        db.close(); // Closing database connection

        //Log.d(TAG, "New profile settings inserted into sqlite: " + id);
        System.out.println("sammy_New content inserted into sqlite: "+id);

    }




    /**
     * Getting data from database
     * */
    public ArrayList<HashMap<String, String>> getAllContents()
    {
        ArrayList<HashMap<String, String>> array_list = new ArrayList<HashMap<String, String>>();

        SQLiteDatabase db = this.getReadableDatabase();
        //Cursor res = db.rawQuery("SELECT * " + " FROM " + TABLE_PROF + " GROUP BY " + KEY_NAME + " ORDER BY " + KEY_MOBILE + " COLLATE NOCASE;", null);
        String selectQuery = "SELECT  * FROM " + TABLE_ITEM;
        Cursor res = db.rawQuery(selectQuery, null);
        res.moveToFirst();

        while (res.isAfterLast() == false)
        {
            HashMap<String, String> hashmap= new HashMap<String, String>();
            hashmap.put("type", res.getString(res.getColumnIndex(KEY_TYPE)));
            hashmap.put("title", res.getString(res.getColumnIndex(KEY_TITLE)));
            hashmap.put("subtitle", res.getString(res.getColumnIndex(KEY_SUBTITLE)));
            hashmap.put("apiid", res.getString(res.getColumnIndex(KEY_APIID)));

            array_list.add(hashmap);
            res.moveToNext();
        }
        return array_list;
    }

    /**
     * Re create database Delete all tables and create them again
     * */
    public void deleteContents() {
        SQLiteDatabase db = this.getWritableDatabase();
        // Delete All Rows
        db.delete(TABLE_ITEM, null, null);
        db.close();
        System.out.println("sammy_Deleted all contents from sqlite");
        //Log.d(TAG, "Deleted all profile info from sqlite");
    }

}

4 ответа

  1. Я бы рекомендовал не пытаться очистить базу данных при вставке новых записей. Вместо этого просто храните метку времени для каждой записи, и когда вам нужны последние 10, просто используйте:

    ORDER BY timestamp DESC LIMIT 10
    

    Одним из вариантов отслеживания 10 самых последних записей в коде Java приложения было бы использование LinkedHashMap, который можно настроить для сохранения только 10 самых последних записей.

  2. @Сэм,

    Чувак предполагая, что вы хотите только 10 записей в вашей таблице то, что вы можете сделать, это при добавлении новой записи возьмите счет, если он равен 10 вы можете удалить первую запись (старая запись) в зависимости от вашего первичного ключа в вашем случае я думаю, что его id

    поэтому создайте функцию, которая возвращает количество

    public int getProfilesCount() {
        String countQuery = "SELECT  * FROM " + TABLE_NAME;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        int cnt = cursor.getCount();
        cursor.close();
        return cnt;
    }
    

    так как вы не используете какое-либо поле метки времени, что вы делаете, чтобы решить самую старую запись на основе вашегоid, так как это primary key

    так что внутри вашей addContentsфункции добавьте код, который я дал внутри комментария

    /**
     * Storing Prof_settings details in database
     * */
    public void addContents(String type, String title, String subtitle, String apiid){
    
        SQLiteDatabase db = this.getWritableDatabase();
    
        ContentValues values = new ContentValues();
    
        values.put(KEY_TYPE, type);
        values.put(KEY_TITLE, title);
        values.put(KEY_SUBTITLE, subtitle);
        values.put(KEY_APIID, apiid);
        // the code you have to add
        int count = getProfilesCount(); // check for number of records
        if(count == 10) {
            db.execSQL("DELETE FROM " + TABLE_NAME+ " ORDER BY  "+KEY_ID+"LIMIT 1"); // will delete oldest record
        } // add till here
    
        long id = db.insert(TABLE_ITEM, null, values); // insert to 1st row
        db.close(); // Closing database connection
    
        //Log.d(TAG, "New profile settings inserted into sqlite: " + id);
        System.out.println("sammy_New content inserted into sqlite: "+id);
    
    }
    
  3. Есть два способа сделать как ваш запрос.

    1. Fist one is that, handle that one get total no of rows and check, if these are more than 10, then first delete an old row and then run the insert command else directly execute the insert command.
    2. Во-вторых, вместо того, чтобы обрабатывать это условие самостоятельно, дайте его триггеру, он автоматически обработает эту ситуацию
      из этих двух способов второй лучше, потому что ни один из ударов по базе данных не имеет значения в производительности, поэтому в случае триггера будет только один удар по базе данных.