【问题标题】:Modelling data and accessing it using the DAO pattern使用 DAO 模式对数据进行建模和访问
【发布时间】:2018-08-17 20:46:06
【问题描述】:

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

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

  • 一个问题将有一个类别。一个类别会有多个问题。
  • 一个问题的分数为 1000、2000 或 3000。一个分数包含许多问题。

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

  • 问题(id、question、scoreId、categoryId)
  • 分数(id、分数)
  • 类别(id、类别)

我的第一个问题是:

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

我的第二个问题是:

如果跨不同表对数据进行建模是正确的方法,那么我将如何使用 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对象不应该只关心数据库中的一个表吗?我上面列出的方法似乎不是解决这个问题的最正确方法。单独的表也会使向数据库中插入数据变得非常混乱(我不明白如何使用 DAO 模式和多个表采取干净的方法)。为 Score 和 Category 表创建 DAO 并没有什么意义。(如果我这样做了,我将如何填充我的模型?)

【问题讨论】:

    标签: java relational-database data-modeling dao


    【解决方案1】:

    像我上面建议的那样跨三个表建模我的数据是不好的做法/错误的方法吗?在单独的表中存储分数和类别有什么好处......?

    这是一个讨论的问题。如果是score,我宁愿将此信息与question 联系起来。另一方面,category 将位于分隔表中,因为更多问题将共享同一类别,因此非常有意义。

    每个DAO对象不应该只关心数据库中的一个表吗?

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      当您查询问题时,您也可以只返回问题对象内的类别和分数 ID,并强制库用户使用这些 ID 值及其各自的 DAO(分数和类别)。

      所以我相信你正在做的事情看起来不错

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2012-07-22
        • 2012-07-26
        • 2018-05-19
        • 2011-09-08
        • 2013-03-25
        • 2015-03-08
        • 2014-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多