Как вставить несколько значений из одной таблицы в другую таблицу одним столбцом? - PullRequest
0 голосов
/ 13 мая 2019

Я создаю приложение для Android, и в одном упражнении мне нужно создать план тренировки.Из прядильщика я выбираю название упражнения (из другой таблицы).Я могу выбрать более одного упражнения.Так какой путь лучше всего сделать это?Я попытался добавить несколько упражнений в ArrayList и сохранить этот ArrayList в базе данных, но я не нашел способа сделать это.И мне нужно иметь возможность редактировать план тренировки (например, удалять или добавлять упражнения), поэтому я думаю, что ArrayList не является решением.

Я понял, что это отношения многие ко многим (много упражнений может входить в план тренировок), поэтому я создал таблицу, которая содержит идентификатор упражнения и идентификатор тренировки:

   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))";
}

Iхочу, чтобы мой план тренировок выглядел примерно так:

  • Название: Грудь
  • Упражнения: жим 4x8 |Наклонный жим 3х12 |Мухи 3х12 |

Итак, как мне сохранить эти 3 упражнения в одном столбце?

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Вот пример, который выполняет и то, что вы просите, основываясь на вашей схеме, т.е.

  1. . Он добавляет ряд упражнений к тренировке через таблицу сопоставления (TRAININGEXERCISE) из ArrayList (ArrayList как таковой).использует идентификаторы).
  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);

    }
}
1 голос
/ 13 мая 2019

Вам не нужно помещать все имена упражнений в один столбец (что противоречит созданной вами схеме таблиц, и вам будет сложно манипулировать упражнениями), вам нужно вставить каждое упражнение в его собственную запись в TABLE_TRAININGEXERCISE иЧтобы связать его с одной тренировкой, следующим шагом будет добавление ArrayList в модель тренировки, в которой вы будете заполнять список всех упражнений, связанных с тем же идентификатором тренировки, с помощью добавления метода, который выбирает все записи из TABLE_TRAININGEXERCISE, используя тренировку.ID.

Таким образом, вам проще управлять тренировочными упражнениями (вставлять, обновлять или удалять), и вы можете получить желаемый результат, напечатав имя тренировки и зацикливая его упражнения и соединяя их запятыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...