使用 DAO 模式建模数据并访问它

Modelling data and accessing it using the DAO pattern

我正在 Java 中创建一个非常简单的应用程序,它将在嵌入式 Derby 数据库中存储问题。我决定使用 DAO 模式来访问数据库中的数据。我不能为这个项目使用 ORM。

一个问题将包含我通常会在关系数据库中使用多对一关系建模的数据。此数据的一个示例是:

考虑到上述情况,我将创建三个 table(括号表示列):

我的第一个问题是:

像我上面建议的那样跨三个 table 对我的数据进行建模是否会是不好的 practice/the 错误的方法?将分数和类别存储在单独的 table 中有什么好处吗?或者将它们合并到问题 table 中会更好吗?链接到具有单个列(id 除外)的 table 的多对一关系对我来说似乎是多余的,因为我们没有存储引用 Score/Category table 的 id,而是可以简单地存储 category/score 的值(因为 category/score table 不存储任何附加信息)。

我的第二个问题是:

如果在单独的 table 中对我的数据建模是正确的方法,那么我将如何使用 DAO 模式访问数据?我的困惑来自以下几点:

我会创建一个 DAO 来填充一个 Question 模型对象,它看起来有点像这样:

public class Question {
    String question;
    String category;
    Integer score;
}

我会像这样创建 DAO 接口的具体实现:

public class QuestionAccessObject implements QuestionDao {
    private static final String TABLE_1 = "QUESTION"; 
    private static final String TABLE_2 = "SCORE";
    private static final String TABLE_3 = "CATEGORY";

    @Override
    public List<Question> getAllQuestions() {
        List<Question> questions = new ArrayList<>();

        //Run a query with joins across the three tables and iterate over the result to populate the list
        return questions;
    }
}

每个 DAO 对象不应该只与数据库中的一个 table 相关吗?我上面列出的方法似乎不是解决此问题的最正确方法。单独的 tables 也会使将数据插入数据库变得非常混乱(我不明白如何使用 DAO 模式和多个 tables 采取干净的方法)。为 Score 和 Category table 创建一个 DAO 真的没有意义..(如果我这样做,我将如何填充我的模型?)

Would modelling my data across three tables like I suggest above be bad practice/the wrong way to go about this? Is there any benefit in storing score and category in separate tables....?

有待商榷。在 score 的情况下,我宁愿将此信息与 question 一起使用。另一方面,category 将在分开的 table 中,因为更多的问题将共享同一类别,所以它非常有意义。

Shouldn't each DAO object only be concerned with a single table in the database?

是的,DAO,一个对象应该关注单一数据源——正如您所说。我当然会尽量避免任何 ComplexDao,因为那些 类 往往会变得更加复杂,并且方法的数量会随着时间的推移而增加。

有一个服务层将这些结果组合在一起,并使用相同的服务向控制器提供输出。

跨不同表对数据建模是一种正确的方法(不一定是最好的)。

分隔表有助于数据库规范化:https://en.wikipedia.org/wiki/Database_normalization

有人可能会争辩说 DAO 模式意味着每个 DAO 对象都与单个实体有关。与 ORM 的工作方式类似,一个实体可以轻松引用其他实体。

当您查询问题时,您也可以只 return 问题对象中的类别和分数 ID,并强制图书馆用户使用这些 ID 值获取分数值和类别值(延迟获取)及其各自的 DAO(分数和类别)。

所以我相信你所做的看起来不错

希望这对您有所帮助