我正在创建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))";
}
我希望我的锻炼计划看起来像这样:
那我该如何将这3个练习保存到一栏中?
答案 0 :(得分: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 :(得分:1)
您无需将所有练习名称都推到一栏中(这与您创建的表方案相矛盾,如果这样做,将很难进行操作),您需要将每个练习插入到TABLE_TRAININGEXERCISE中自己的记录中,然后将其链接到一个锻炼中,下一步是将ArrayList添加到锻炼模型中,通过使用使用锻炼从TABLE_TRAININGEXERCISE获取所有记录的方法,您将在其中填充与该锻炼ID相关的所有锻炼的列表ID。
这样,您就可以更轻松地进行锻炼锻炼(插入,更新或删除) 而且,您可以通过打印锻炼名称并在其锻炼过程中循环并用逗号将其加入来实现所需的输出。