JDBC 域设计和关系

JDBC Domain Design and Relationships

我以前用过 Hibernate / JPA,现在结合使用 Spring JDBC 和 MyBatis。

使用 JPA/Hibernate,如果你有一个客户,它有一个地址,你将有一个类似于下面代码的域结构。 (减去所有注释/配置/映射)。

在使用 JDBC 或 MyBatis 时,这仍然有意义吗?这是我所知道的组合域设计,has-a, belongs-to 等。然而,我见过的大多数 JDBC 代码示例都具有带回 ID 而不是集合的域对象,或者展平数据。这两种方法、可维护性等是否有任何性能优势。首先使用 JPA,我不确定 JDBC 做事的方式是什么。

public class Customer {

    private Long id;
    private String userName;
    private String password;
    private String firstName;
    private String lastName;
    private Collection<Address> addresses
    ...
}

public class Address {
    private Long id;
    private String streetAddress1;
    private String streetAddress2;
    private String city;
    private State state;
    private String postalCode;
}

public class State {
    private Long id;
    private String code;
    private String name;
    private Country country;
}

public class Country {
    private Long id;
    private String code;
    private String name;
}

我遇到了一个例子,这是他们的一个 类。

public class Question {
    private long questionId;
    private long categoryId;
    private long userId;
    private long areaId;
    private String question;
    private String verifyKey;
    private Date created;
    private User user;
    private List<Answer> answers;
    private long answerCount;
    private String name;
    // getters and setters omited...
}

为什么要获取 userId、areaId 和 categoryId 而不是实际获取关联对象?该 ID 可能对前端用户没有用,我想您可以使用该 ID 发出另一个查询来获取额外的数据,但是再次往返数据库似乎效率低下。

您可以将此域对象视为数据库 table 的 "footprint"。在您的示例中,来自 QuestionuserIdareaIdcategoryId 很可能是外键来自相应的 tables。在创建问题时,您永远不需要完整的对象数据,稍后可以使用单独的数据库请求检索它。如果您一次获取所有关联的对象,您将至少命中每个对象一个额外的 table(通过 join-s 或 subselect-s)。此外,这实际上与 Hibernate 所做的相同。默认情况下,如果需要未初始化的关联对象,它会延迟加载域对象并再次访问数据库。

那个时候,最好是获取那些没有域对象就不能存在的对象。在您的示例中,问题和列表是耦合的。

当然,如果您在应用程序的其他地方再次需要用户、类别或任何其他关联对象(假设对先前检索到的对象的引用已丢失),您将使用相同的查询访问数据库。它应该完成并且看起来效率低下,因为与 Hibernate 不同,普通 JDBC 和 SpringJDBC 都没有中间缓存。但这不是 JDBC 设计的目的。