【问题标题】:Creating example values in SQLite database using strings from strings.xml使用 strings.xml 中的字符串在 SQLite 数据库中创建示例值
【发布时间】:2017-01-22 19:51:28
【问题描述】:

我得到了这个类,它在应用程序的第一次运行时创建数据库。我想用 strings.xml 中的一些示例值填充一张表。基本上我会这样做:

private static final String CATEGORIES_FILL = "INSERT INTO categories VALUES ('', " + getString(R.string.fuel) + "); " +
                                              "INSERT INTO categories VALUES ('', " + getString(R.string.food) + "); " +
                                              "INSERT INTO categories VALUES ('', " + getString(R.string.treatment) + "); " +
                                              "INSERT INTO categories VALUES ('', " + getString(R.string.salary) + "); ";

问题是,类不是活动,字符串必须是静态的才能使用

db.execSQL(CATEGORIES_FILL);

请更正我的方法,以便我可以使用 strings.xml 来做到这一点。

我认为我可以在使用 try 块围绕它的活动类中执行此操作,但我不喜欢每次打开活动时都执行此操作的想法。

数据库类的片段

private static class DatabaseHelper extends SQLiteOpenHelper {


    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);


        final String CATEGORIES_FILL = "INSERT INTO categories VALUES ('', " + context.getString(R.string.fuel) + "); " +
        "INSERT INTO categories VALUES ('', " + context.getString(R.string.food) + "); " +
        "INSERT INTO categories VALUES ('', " + context.getString(R.string.treatment) + "); " +
        "INSERT INTO categories VALUES ('', " + context.getString(R.string.salary) + "); "; 
    }

    /* Tworzenie tabel
     * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DATABASE_CREATE);
        db.execSQL(CATEGORIES_FILL); //need the way to access this final here
        db.execSQL(EXPENSES_CREATE);
        db.execSQL(INCOMES_CREATE);
        db.execSQL(BUGS_CREATE);            
    }

【问题讨论】:

    标签: android android-xml


    【解决方案1】:

    有点像这样。

    添加到 res/values/.xml 并将您的字符串引用添加到字符串数组。

    <resources>
        <string-array name="categories">
            <item>@string/fuel</item>
            <item>@string/food</item>
            <item>@string/treatment</item>
            <item>@string/salary</item>
        </string-array>
    </resources>
    

    在您的数据库上创建一个 SQLiteStatement。

    SQLiteDatabase db = ...;
    SQLiteStatement insert = db.compileStatement("INSERT INTO categories (yourcolumnnamehere) VALUES (?)");
    
    //process each string
    for (String category : getResources().getStringArray(R.array.categories)) 
    {
        insert.bindValue(1, category);
        long id = insert.executeInsert(); // In case you care about the row id.
    }
    

    编辑:并且,考虑在你的课程之后做一些类似的事情(我可能在那里留下了一两个错误,但你应该了解它的要点):

    private static class DatabaseHelper extends SQLiteOpenHelper {
        ...
        // Replace 'yourcolumnnamehere' with whatever your column is actually named.
        private static final String INSERT_CATEGORY = "INSERT INTO categories (yourcolumnamehere) VALUES (?)"
        ...
        ...
    
        private final String[] mCategories;
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            mCategories = context.getResources().getStringArray(R.array.categories);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);
    
            // Here you create the SQLiteStatement that will be used
            // to add categories. The values are stored in mCategories.
            SQLiteStatement statement = db.compileStatement(INSERT_CATEGORY);
            for (String category : mCategories) {
                statement.bindValue(1, category);
                statement.executeInsert();
            }
            statement.close();
    
            db.execSQL(EXPENSES_CREATE);
            db.execSQL(INCOMES_CREATE);
            db.execSQL(BUGS_CREATE);            
        }
    

    【讨论】:

    • 但是如果类没有扩展 Activity 对吗? (?)地方的输入是什么
    • 任何上下文都可以为您获取资源。 ?是将值绑定到预编译的 SQLite 语句时使用的占位符。由于您无法访问上下文,因此您在哪里执行此操作。
    • 那么,对于任何理智的实现,我接受 SQLiteOpenHelper 的子类吗? SQLiteOpenHelper 构造函数采用 Context,保存对您自己的参数的引用(因为它没有定义有用的 getContext)并使用它。
    • 是的,你有一个可用的上下文。调用 context.getResources() .getStringArray(R.array.categories) 来检索存储在资源中的字符串数组。虽然您“可以”制作包含您的值的完整 SQL 字符串,但最好使用 SQLiteStatement,因为绑定的列值将被正确转义并且不会破坏您的 SQL。
    • 将其作为字段存储在您的 DatabaseHelper 中。我已经编辑了答案。
    【解决方案2】:
    <string-array name="categories">
            <item>aaaaaa</item>
            <item>bbbbbbbb</item>
            <item>cccccccc</item>
            <item>ddddd</item>
    </string-array>
    

    不是添加 String ,而是将字符串数组添加到 string.xml 然后在 Java 中使用:

    String[] categoriesAndDescriptions = getResources().getStringArray(R.array.categories);
        for(String cad : categoriesAndDescriptions) {
            String categoryAndDesc = cad;
            list.add(categoryAndDesc);
        }
    

    list 是 ArrayList,得到一个值后存储到 Arraylist 中。

    现在填充此 ArayList 以插入查询,您可以使用 list.get(0) 获取第一个值

    【讨论】:

    • getResources 也是基于 Context 类的。我不能在非活动类上使用 id
    【解决方案3】:

    试试这个

    private Resources mResources;
    
    DatabaseHelper(Context context) {
       super(context, DATABASE_NAME, null, DATABASE_VERSION);
    
       mResources = context.getResources();
    
       final String CATEGORIES_FILL = "INSERT INTO categories VALUES ('', " + mResources.getString(R.string.fuel) + "); " +
                    "INSERT INTO categories VALUES ('', " + mResources.getString(R.string.food) + "); " +
                    "INSERT INTO categories VALUES ('', " + mResources.getString(R.string.treatment) + "); " +
                    "INSERT INTO categories VALUES ('', " + mResources.getString(R.string.salary) + "); "; 
                }
    

    【讨论】:

      猜你喜欢
      • 2019-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多