如何在SQLite中实现Workouts与Exercises表的一对多关联查询
实现训练计划与训练动作的一对多关联
嘿,我来帮你搞定这个训练计划和训练动作的关联问题!既然已经有了两张表和基础的查询方法,我们只需要几步就能让每个Workout对象带上它对应的所有Exercise列表。
1. 确认表结构的外键关联
首先得确保你的exercises表有一个外键字段(比如workout_id),用来关联workouts表的主键(比如id)。这是一对多关系的基础——每个训练动作都属于某个训练计划,所以exercises.workout_id要指向workouts.id。
2. 更新Workout实体类
在你的Workout类里添加一个用来存储对应训练动作的列表属性,记得加上getter和setter:
public class Workout { // 原有属性,比如id、name、description等 private int id; private String name; // 新增的训练动作列表 private List<Exercise> exercises; // 原有getter、setter public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 新增的getter、setter public List<Exercise> getExercises() { return exercises; } public void setExercises(List<Exercise> exercises) { this.exercises = exercises; } }
3. 修改getAllWorkouts方法
现在我们要修改原有的getAllWorkouts方法,让它在获取每个训练计划后,再查询该计划对应的所有训练动作,并关联到Workout对象中。可以写一个辅助方法来根据训练计划ID查询动作,这样代码更清晰:
辅助方法:根据训练计划ID获取对应的训练动作
private List<Exercise> getExercisesByWorkoutId(int workoutId) { List<Exercise> exerciseList = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); // 查询条件:exercises表中workout_id等于传入的ID String selection = "workout_id = ?"; String[] selectionArgs = { String.valueOf(workoutId) }; Cursor cursor = db.query( "exercises", // 表名 null, // 查询所有列 selection, // WHERE条件 selectionArgs,// 条件参数 null, // GROUP BY null, // HAVING null // ORDER BY ); if (cursor.moveToFirst()) { do { Exercise exercise = new Exercise(); // 假设Exercise类有id、name、sets等属性,根据实际字段调整 exercise.setId(cursor.getInt(cursor.getColumnIndexOrThrow("id"))); exercise.setName(cursor.getString(cursor.getColumnIndexOrThrow("name"))); exercise.setSets(cursor.getInt(cursor.getColumnIndexOrThrow("sets"))); // 其他属性... exerciseList.add(exercise); } while (cursor.moveToNext()); } cursor.close(); db.close(); return exerciseList; }
修改后的getAllWorkouts方法
public ArrayList<Workout> getAllWorkouts() { ArrayList<Workout> workoutArrayList = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); // 查询所有训练计划 Cursor cursor = db.query( "workouts", null, null, null, null, null, null ); if (cursor.moveToFirst()) { do { Workout workout = new Workout(); // 填充Workout原有属性,根据实际字段调整 workout.setId(cursor.getInt(cursor.getColumnIndexOrThrow("id"))); workout.setName(cursor.getString(cursor.getColumnIndexOrThrow("name"))); workout.setDescription(cursor.getString(cursor.getColumnIndexOrThrow("description"))); // 获取该训练计划对应的所有训练动作 List<Exercise> exercises = getExercisesByWorkoutId(workout.getId()); workout.setExercises(exercises); workoutArrayList.add(workout); } while (cursor.moveToNext()); } cursor.close(); db.close(); return workoutArrayList; }
4. 注意事项
- 记得处理数据库操作可能出现的异常,比如可以在方法里加上
try-catch块,避免程序崩溃。 - 如果你的表字段名和示例不同,要对应调整
getColumnIndexOrThrow里的字段名。 - 每次数据库操作后记得关闭
Cursor和SQLiteDatabase,避免资源泄漏。
这样修改后,调用getAllWorkouts()就能得到每个训练计划都包含其对应训练动作列表的结果啦!
内容的提问来源于stack exchange,提问作者user303749
相关产品推荐
相关产品推荐

