You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:08:53