【问题标题】:How to insert several values from one table to other table one column?如何将一个表中的多个值插入到另一个表的一列中?
【发布时间】:2019-09-29 21:46:49
【问题描述】:

我正在创建 Android 应用程序,并且在一项活动中我需要创建锻炼计划。从微调器中,我选择练习名称(来自其他表)。我可以选择不止一项运动。那么哪种方式最好呢?我尝试向 ArrayList 添加几个练习并将 ArrayList 保存到数据库,但我没有找到方法。而且我需要能够编辑锻炼计划(例如:删除或添加锻炼),所以我认为 ArrayList 不是一个解决方案。

我意识到这是多对多的关系(很多锻炼可以在很多锻炼计划中),所以我创建了包含锻炼 ID 和锻炼 ID 的表格:

   private static final String CREATE_TABLE_TRAININGEXERCISE = 
"CREATE TABLE " + TABLE_TRAININGEXERCISE + "(" + TEXERCISE_ID + 
" INTEGER," + TWORKOUT_ID + " INTEGER," + "FOREIGN KEY (TExerciseID) REFERENCES "
 + TABLE_EXERCISE + " (ExerciseID)," +
 " FOREIGN KEY (TWorkoutID) REFERENCES " + TABLE_WORKOUT + " (WorkoutID))";
}

我希望我的锻炼计划看起来像这样:

  • 标题: 胸部
  • 练习: 卧推 4x8| 上斜卧推 3x12| 苍蝇 3x12|

那么如何将这 3 个练习保存到一栏中?

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    这是一个示例,它可以根据您的架构即满足您的要求,即

    1. 它通过映射表 (TRAININGEXERCISE) 从 ArrayList(ArrayList 因为它使用 id's)向锻炼添加一些练习。
    2. 它会产生类似于您希望的输出(到日志),例如示例日志

    :-

    2019-05-13 13:13:46.736  D/MYDATA: Workout: Chest
            EXERCISES: Bench press,Incline bench press,Flies
    2019-05-13 13:13:46.736  D/MYDATA: Workout: Abdomen
            EXERCISES: hump,lug,roll
    2019-05-13 13:13:46.736  D/MYDATA: Workout: Everything
            EXERCISES: hump,lug,roll,kneel,Bench press,Incline bench press,Flies,Flip
    

    使用的数据库助手 DBHelper.java 是:-

    public class DBHelper extends SQLiteOpenHelper {
    
        public static final String DBNAME = "workout";
        public static final int DBVERSION = 1;
    
        public static final String TABLE_TRAININGEXERCISE = "training_excercise"; //<<<<<<<< OOOPS spelling :)
        public static final String TABLE_WORKOUT = "workout";
        public static final String TABLE_EXERCISE = "exersise"; //<<<<<<< OOOPS spelling :)
        public static final String TWORKOUT_ID = "WorkoutID";
        public static final String TWORKOUT_NAME = "workour_name";
    
        public static final String TEXERCISE_ID = "ExerciseID";
        public static final String TEXERCISE_NAME = "exercise_name";
    
        public static final String TTEEXERCISELINK = "TExerciseID"; //<<<<<<<<<< ADDED
        public static final String TTEWORKOUTLINK = "TWorkoutID"; //<<<<<<<<<< ADDED
    
        // Note as entities are always derived from constants above the spelling mistakes are irrelvant
        // (need a better smellchecker :) )
    
        //<<<<<<<<<< ENOUGH TO DEMONSTRATE >>>>>>>>>>
        private static final String CREATE_TABLE_WORKOUT =
                "CREATE TABLE " + TABLE_WORKOUT + "(" +
                        TWORKOUT_ID + " INTEGER PRIMARY KEY," +
                        TWORKOUT_NAME + " TEXT" +
                        ")";
    
        //<<<<<<<<<< ENOUGH TO DEMONSTRATE >>>>>>>>>>
        private static final String CREATE_TABLE_EXERCISE =
                "CREATE TABLE " + TABLE_EXERCISE + "(" +
                        TEXERCISE_ID + " INTEGER PRIMARY KEY," +
                        TEXERCISE_NAME + " TEXT " +
                        ")";
    
        //<<<<<<<<<<NOTE Uses constants for all entity names >>>>>>>>>> (see new ones above)
        private static final String CREATE_TABLE_TRAININGEXERCISE =
                "CREATE TABLE " + TABLE_TRAININGEXERCISE + "(" +
                        TTEEXERCISELINK + " INTEGER," +
                        TTEWORKOUTLINK + " INTEGER," +
    
                        "FOREIGN KEY (" + TTEEXERCISELINK + ") " +
                        "REFERENCES " + TABLE_EXERCISE + " (" + TEXERCISE_ID + ")," +
    
                        " FOREIGN KEY (" + TTEWORKOUTLINK + ") " +
                        "REFERENCES " + TABLE_WORKOUT + " (" + TWORKOUT_ID + "))";
    
        public DBHelper(Context context) {
            super(context, DBNAME, null, DBVERSION);
        }
    
        @Override
        public void onConfigure(SQLiteDatabase db) {
            super.onConfigure(db);
            db.setForeignKeyConstraintsEnabled(true); //<<<<<<<<<< MUST HAVE FOR FOREIGN KEYS
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_TABLE_EXERCISE);
            db.execSQL(CREATE_TABLE_WORKOUT);
            db.execSQL(CREATE_TABLE_TRAININGEXERCISE);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    
        public long addWorkout(String name) {
            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues cv = new ContentValues();
            cv.put(TWORKOUT_NAME,name);
            return db.insert(TABLE_WORKOUT,null,cv);
        }
    
        public long addExecise(String name) {
            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues cv = new ContentValues();
            cv.put(TEXERCISE_NAME,name);
            return db.insert(TABLE_EXERCISE,null,cv);
        }
    
        public long addExcerciseToWorkout(long workoutid, long exerciseid) {
            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues cv = new ContentValues();
            cv.put(TTEWORKOUTLINK,workoutid);
            cv.put(TTEEXERCISELINK,exerciseid);
            return db.insert(TABLE_TRAININGEXERCISE,null,cv);
        }
    
        //<<<<<<<<<< ADD MANY EXERCISES to a WORKOUT via an ArrayList
        public void addManyExcercisesToWorkout(long workoutid,ArrayList<Long> exerciseids) {
            ArrayList<Long> rv = new ArrayList<>();
            SQLiteDatabase db = this.getWritableDatabase();
            db.beginTransaction();
            for (Long l: exerciseids) {
                long thisid = addExcerciseToWorkout(workoutid,l);
            }
            db.setTransactionSuccessful();
            db.endTransaction();
        }
    
        //<<<<<<<<<< Get all the exercises per workout via the group_concat function >>>>>>>>>>
        public void logAllWorkoutsWithExcercises() {
            SQLiteDatabase db = this.getWritableDatabase();
            //<<<<<<<<<< column name aliases (not required but desireable as they can be quite cumbersome) >>>>>>>>>>
            String workoutname_column_alias = "thisworkoutname";
            String concantenated_exercises_alias = "all_exercises";
    
            String tables = TABLE_WORKOUT +
                    " JOIN " + TABLE_TRAININGEXERCISE + " ON " + TABLE_WORKOUT + "." + TWORKOUT_ID + "="  + TTEWORKOUTLINK +
                    " JOIN " + TABLE_EXERCISE + " ON " + TTEEXERCISELINK +  "=" + TABLE_EXERCISE + "." + TEXERCISE_ID;
            String[] columns = new String[]{
                    TABLE_WORKOUT + "." + TWORKOUT_NAME + " AS " + workoutname_column_alias,
                    "'\n\tEXERCISES: '||group_concat(" +
                            TABLE_EXERCISE + "." + TEXERCISE_NAME +
                            ") AS " + concantenated_exercises_alias
            };
            String groupby = TABLE_WORKOUT + "." + TWORKOUT_ID;
            // Query resolves to :-
            /*
                SELECT 
                    workout.workour_name AS thisworkoutname, 
                    'EXERCISES: '||group_concat(exersise.exercise_name) AS all_exercises 
                FROM workout 
                    JOIN training_excercise ON  workout.WorkoutID=TWorkoutID 
                    JOIN exersise ON TExerciseID=exersise.ExerciseID 
                    GROUP BY workout.WorkoutID
            */
            Cursor csr = db.query(tables,columns,null,null,groupby,null,null);
            while (csr.moveToNext()) {
                Log.d(
                        "MYDATA",
                        "Workout: " +
                                csr.getString(csr.getColumnIndex(workoutname_column_alias)) +
                                csr.getString(csr.getColumnIndex(concantenated_exercises_alias))
                );
            }
            csr.close();
        }
    }
    

    测试是通过以下活动完成的:-

    public class MainActivity extends AppCompatActivity {
        String[] allexcercises = new String[]{"hump", "lug", "roll", "kneel", "Bench press", "Incline bench press", "Flies","Flip"};
        // Note assume that hump is id 1, lug id 2 etc
        String[] allworkouts = new String[]{"Chest","Abdomen","Everything"};
    
        ArrayList<Long> chest_excercises = new ArrayList<>();
        ArrayList<Long> abdomen_excercises = new ArrayList<>();
        ArrayList<Long> everything_excercises = new ArrayList<>();
    
        DBHelper mDBHlpr;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mDBHlpr = new DBHelper(this);
            addSomeData(); //<<<<<<<<<< Adds the testing data (only designed to run once)
            mDBHlpr.logAllWorkoutsWithExcercises(); //<<<<<<<<<< Output workouts with excercises
        }
    
        private void addSomeData() {
            // Excercises
            mDBHlpr.getWritableDatabase().beginTransaction();
            for (String excercise: allexcercises) {
                mDBHlpr.addExecise(excercise);
            }
            for (String workout: allworkouts) {
                mDBHlpr.addWorkout(workout);
            }
            mDBHlpr.getWritableDatabase().setTransactionSuccessful();
            mDBHlpr.getWritableDatabase().endTransaction();
    
            // Build ArrayLists as if from multiple spinner selections
            chest_excercises.add(new Long(5));
            chest_excercises.add(new Long(6));
            chest_excercises.add(new Long(7));
    
            abdomen_excercises.add(new Long(1));
            abdomen_excercises.add(new Long(2));
            abdomen_excercises.add(new Long(3));
    
            // Add all excercises to the everything workout ArrayList
            for(int l=1; l <= allexcercises.length; l++) {
                everything_excercises.add(new Long((long) l));
            }
            // Add multiple exercises per workout
            mDBHlpr.addManyExcercisesToWorkout(1,chest_excercises);
            mDBHlpr.addManyExcercisesToWorkout(2,abdomen_excercises);
            mDBHlpr.addManyExcercisesToWorkout(3,everything_excercises);
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      您不需要将所有练习名称都放在一列中(这与您创建的表格方案相矛盾,如果这样做将很难操作练习),您需要将每个练习插入到 TABLE_TRAININGEXERCISE 中自己的记录中,然后将其链接到单个锻炼,下一步是将 ArrayList 添加到锻炼模型中,您将通过添加使用锻炼从 TABLE_TRAININGEXERCISE 获取所有记录的方法来填充与同一锻炼 ID 相关的所有锻炼的列表身份证。

      这样您就可以更轻松地操作锻炼练习(插入、更新或删除) 您可以通过打印锻炼名称并循环其锻炼并用逗号连接它们来实现所需的输出。

      【讨论】:

      • @YoussefShammas 知道了!但是如何将 ArrayList 添加到锻炼模型中?我知道如何将简单数据插入数据库,但我从未在数据库中使用过 ArrayList
      • ArrayList 是一个简单数据结构的集合,因此您可以遍历数组的项目并开始一次添加一个,就像对待任何其他对象一样
      猜你喜欢
      • 1970-01-01
      • 2012-03-06
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多