【问题标题】:How to create data in database only once如何在数据库中只创建一次数据
【发布时间】:2018-09-05 05:14:58
【问题描述】:

我需要创建一个方法,它将数据添加到数据库中,然后,微调器应该显示它。正如我测试的那样,显示效果很好,但我不知道如何告诉数据库,我只想创建一次数据。例如,我有一个名为 chestExercises 的表,其中包含三列 firstColumn、secondColumn、thirdColumn 的值:

firstColumn = "exerciseOne"
secondColumn = "exerciseTwo"
thirdColumn = "exerciseThree"

现在,我想从程序中只创建一次这些数据。正如我之前写的,我做了一些“测试”,数据库一直在创建这些数据,我不想重复。所以..我怎么能“告诉”数据库,我只想做一次?

数据库

 public databaseHelper(Context context) {
    super(context, DATABASE_NAME, null, 1);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_2 + " TEXT," + COLUMN_3 + " TEXT," + COLUMN_4 + " TEXT)");

}

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

public boolean insertData() {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(COLUMN_2, "1");
    contentValues.put(COLUMN_3, "2");
    contentValues.put(COLUMN_4, "3");
    long result = db.insert(TABLE_NAME, null, contentValues);

    if (result == -1) {
        return false;
    } else
        return true;
}

public List<String> getAllLabels() {
    List<String> labels = new ArrayList<String>();

    String selectQuery = "SELECT  * FROM " + TABLE_NAME;

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);
    if (cursor.moveToFirst()) {
        do {
            labels.add(cursor.getString(1));
            labels.add(cursor.getString(2));
            labels.add(cursor.getString(3));
        } while (cursor.moveToNext());
    }
    cursor.close();
    db.close();

    return labels;
}

}

主活动

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
Spinner spinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    spinner = (Spinner) findViewById(R.id.spinner);
    databaseHelper db = new databaseHelper(getApplicationContext());
    if (spinner == null){
        db.insertData();
    }else {
        Toast.makeText(MainActivity.this,
                "Your Message", Toast.LENGTH_LONG).show();
    }
    loadData();
}

public void loadData(){
    databaseHelper db = new databaseHelper(getApplicationContext());
    List<String> labels = db.getAllLabels();
    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_spinner_item, labels);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(dataAdapter);
}

@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
    String label = adapterView.getItemAtPosition(i).toString();
    Toast.makeText(adapterView.getContext(),"Selected: "+label,Toast.LENGTH_LONG).show();
}

@Override
public void onNothingSelected(AdapterView<?> adapterView) {

}
}

【问题讨论】:

  • 我想你想要什么没有重复的数据..对吗?
  • 你的问题是矛盾的......一次创建平均值可能就像你只想要数据库中的一行
  • 请更具体地说明一次究竟是什么意思
  • 这并不矛盾。我清楚地定义了它应该是什么样的,但是好的,我会重复一遍。我想创建一些方法,它将在特定行中生成数据。例如,假设数据库包含健身练习。数据库应如下所示: 表名 = chestExercises 第一行:firstExercise = 一些练习 第二行:secondExercise = 一些练习 我想让它像最终的一样,它不会被编辑,它必须只创建一次,直到用户删除应用程序(所以它应该只创建一次,此数据将显示在微调器中)
  • 嗯,您可以使用共享首选项....您可以检查应用程序是否第一次打开...如果是,则插入其他加载数据

标签: android sqlite spinner


【解决方案1】:

选项 1 - 有一个合适的约束

一种选择是定义表,使 3 列组合形成 UNIQUE 约束,因此如果组合列存在,则会导致冲突。

例如

db.execSQL("create table " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_2 + " TEXT," + COLUMN_3 + " TEXT," + COLUMN_4 + " TEXT, UNIQUE (" + COLUMN_2 + "," + COLUMN_3 + "," + COLUMN_4 + " ))");

在这种情况下,不会插入相同的值组合(因为 insert 方法有效地使用了 INSERT OR IGNORE,因此如果发生冲突,则忽略 INSERT)。

选项 2 - 检查表的行数

另一种方法是通过检查行数来检查表是否已经有任何数据。

您可以在 DatabaseHelper 类中有一个方法,例如:-

public boolean isTableEmpty(String tablename) {
    return DatabaseUtils.queryNumEntries(this.getWritableDatabase(),tablename) < 1;
}
  • 当然,这可以修改以测试其他场景

选项 3 - 在插入之前查询表以查看该行是否存在,例如

public boolean insertDataCheckingForDuplicate(String value1, String value2, String value3) {
    SQLiteDatabase db = this.getWritableDatabase();
    int rowcount = 0;

    String whereclause = COLUMN_2 + "=? AND " + COLUMN_3 + "=? AND " + COLUMN_4 + "=?";
    String[] whereargs = new String[]{value1,value2,value3};
    Cursor csr = db.query(TABLE_NAME,null,whereclause,whereargs,null,null,null);
    rowcount = csr.getCount();
    csr.close();
    if (rowcount > 0) {
        return false;
    }

    ContentValues contentValues = new ContentValues();
    contentValues.put(COLUMN_2, value1);
    contentValues.put(COLUMN_3, value2);
    contentValues.put(COLUMN_4, value3);
    long result = db.insert(TABLE_NAME, null, contentValues);

    if (result == -1) {
        return false;
    } else
        return true;
}

选项 4 - 使用预加载的数据库。

使用这种方法,您可以提供一个预加载的数据库(即存在基础数据)。数据库放置在资产文件夹中,并在首次打开数据库时从资产文件夹复制到相关位置。该进程查看数据库是否存在,如果存在则打开数据库,如果不存在则复制数据库。

您可以使用 SQLiteOpenAssethelper 来简化此过程,请参阅android-sqlite-asset-helper。在 StackOverflow 上也有很多关于如何自己完成此操作的示例。

【讨论】:

    猜你喜欢
    • 2023-02-25
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多