如何将表映射到 Java 个对象

How do I map tables to Java objects

举个例子,我有三个这样的 table。 database image 我如何将第三个 table 映射到 java 对象。

class StudentCourse{
    Student student;
    Course course;
    Double score;
}

class StudentCourse{
    Long studentId;
    Long courseId;
    Double score;
}

如果我使用第一个,在我更新数据库中的一些数据后,例如学生 informations.The 下次我从数据库中查询 StudentCourse(我使用 mybatis)时,缓存会导致数据不正确吗? 如果我使用第二个,如果我想列出学生的课程分数,我必须首先查询 StudentCourse 列表,然后通过 courseId 从数据库中查询课程信息,对于每个结果我需要额外的查询。我认为那会降低程序的效率。 还有其他方法可以解决这个问题吗?

对于第一个。 mybatis第二次查询,如果数据还没有更新,就从缓存中获取结果。

    private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
        this.localCache.putObject(key, ExecutionPlaceholder.EXECUTION_PLACEHOLDER);

        List list;
        try {
            list = this.doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
        } finally {
            this.localCache.removeObject(key);
        }

        this.localCache.putObject(key, list);
        if (ms.getStatementType() == StatementType.CALLABLE) {
            this.localOutputParameterCache.putObject(key, parameter);
        }

        return list;
    }

如果我有这样的 resultMap

    <resultMap id="studentcourse" type="StudentCourse">
        <association property="student" resultMap="Student" />
        <association property="course" resultMap="Course"/>
        <result property="score" column="score"/>
    </resultMap>

首先我从数据库中获取一个 StudentCourse 对象,localCache 缓存 object.And 然后我更新 StudentCourse 中的课程(更改数据库记录)。第二次我获取一些 StudentCourse 它将 return一个结果localcache.So StudentCourse里面的课程信息是脏的data.How如果我选择第一个就处理它。

理想情况下,您会使用最能为您的域建模的 class 设计,并担心映射到单独持久层中的数据存储。如果您需要大幅更改模型以允许持久层运行,那么您需要一个新的 ORM!虽然我不熟悉 mybatis,但我希望它不会在每次更改基础数据时都创建一个新对象。

coursestudent table 中的键充当 student_course table 中的外键。外键最好表示为 Java 中的引用。在 Java 级别使用密钥会强制执行额外的间接级别,并使您面临完整性问题(例如,如果外键更改)。

所以我建议:

class StudentCourse {
    private final Student student;
    private final Course course;
    private double score;
}

您也可以考虑将它放在其他 classes 之一中 - 这可能更方便,具体取决于 classes 的使用方式:

class Student {
    private final int id;
    private String name;
    private List<CourseScores> scores = new ArrayList<>();

    public void addCourseScore(Course course, double score) {
        scores.add(new CourseScore(course, score));
    }

    private record CourseScores(Course course, double score) { };
}

如果您的 ORM 不为您解析键(即在检索数据时自动查找引用的对象),那么您需要自己做。然而,这是一个非常简单的对象:

class College {
    private Map<Integer,Student> students;
    private Map<Integer,Course> courses;
}

因此将 student_course 数据转换为上述模型的代码可能如下所示:

ResultSet data;
while (!data.isAfterLast()) {
    Student student = college.getStudent(data.getInteger("student"));
    Course course = college.getCourse(data.getInteger("course"));
    double score = data.getDouble("score");
    student.addCourseScore(course, score);
    data.next();
}