Java 面向对象的数据库访问编程

Java 面向对象的数据库访问编程,java,database,oop,data-access-layer,3-tier,Java,Database,Oop,Data Access Layer,3 Tier,我正在做一个数据库访问的项目。下面是我实现的类的概要 public class Foo { private String id; private String name; private int x; private String y; private String z; ... public Foo(String id) throws SQLException { this.id=id; try (Stat

我正在做一个数据库访问的项目。下面是我实现的类的概要

public class Foo {

    private String id;
    private String name;
    private int x;
    private String y;
    private String z;
    ...

    public Foo(String id) throws SQLException {
       this.id=id;
       try (Statement stmt = MyConnectionManager().getConnection().createStatement()) {
          ResultSet rs = stmt.executeQuery("SELECT * FROM " + TABLE_NAME
                + " WHERE(id='" + this.id + "')");
          if (!rs.next()) {
             throw new NoExistException();
          }
          this.name = rs.getString("Name");
          this.x = ...
          ...
       } catch (SQLException ex) {
          throw ex;
       }
    }
    public int getId() {
       return this.id;
    }

    public String getName() {
    .
    .
    .

但是,当我查看大多数oop示例时,我发现大多数人使用附加类来访问数据库。我不知道我要说的是一个错误。这些代码访问数据库以初始化每个成员变量。但在我的代码中,数据库只被访问一次以初始化我的对象。我是否应该改变这种做法。如果我更改,当我的应用程序想要一起初始化更多对象时(可能是数百个),它会影响应用程序的速度。我认为这可能是一个重复的问题。但对于我的问题,我没有找到任何令人满意的答案

这是一种设计选择,有些人喜欢模块化他们的程序,这被认为是一种很好的做法,因为修改和维护不会影响其他类


如果您为数据库访问(重构)创建一个新类,它允许其他类访问该类,如果它们需要数据库访问。

这是一种设计选择,有些人喜欢模块化他们的程序,这被认为是一种良好的做法,因为修改和维护不会影响其他类

如果您为数据库访问(重构)创建了一个新类,那么如果其他类需要数据库访问,它也允许其他类访问该类。

您的方法违反了and-基本上,类不应该既是域类,也不应该访问数据库

每个成员变量都独立初始化,并且初始化涉及数据库调用的方法更糟糕,而且也不起作用,而且违反了前面提到的规则,根本无法执行

最常用的处理方法是通过一个类,在该类中,您可以执行数据库访问并将结果集映射到域类的新实例

在您的情况下,这意味着您最终会得到如下界面:

public interface FooDao
{
  public Collection<Foo> getAll() throws DaoException;

  public Foo getByIdentity(String id) throws DaoException;

  public Collection<Foo> getByName(String name) throws DaoException;

  public void save(Collection<Foo> foos) throws DaoException;
}
公共接口FooDao { 公共集合getAll()引发异常; public Foo getByIdentity(字符串id)抛出异常; 公共集合getByName(字符串名称)引发异常; 公共作废保存(集合foos)抛出异常; } 该接口可能有一系列get方法或公开某种基于条件的机制,以允许您构造更复杂的查询(我不久前编写的一些代码就是这样做的),但重要的是,您的代码使用的都是这个接口。然后,您可以随心所欲地实现这个接口(如果您的对象模型很简单,则使用直接JDBC;如果您需要更高级的东西,则使用Hibernate),或者在单元测试中模拟它

当您引入一个
Bar
类时,您将重复定义
BarDao
并根据需要再次实现的模式。

您的方法违反了and-基本上一个类不应该既是域类,也不应该访问数据库

每个成员变量都独立初始化,并且初始化涉及数据库调用的方法更糟糕,而且也不起作用,而且违反了前面提到的规则,根本无法执行

最常用的处理方法是通过一个类,在该类中,您可以执行数据库访问并将结果集映射到域类的新实例

在您的情况下,这意味着您最终会得到如下界面:

public interface FooDao
{
  public Collection<Foo> getAll() throws DaoException;

  public Foo getByIdentity(String id) throws DaoException;

  public Collection<Foo> getByName(String name) throws DaoException;

  public void save(Collection<Foo> foos) throws DaoException;
}
公共接口FooDao { 公共集合getAll()引发异常; public Foo getByIdentity(字符串id)抛出异常; 公共集合getByName(字符串名称)引发异常; 公共作废保存(集合foos)抛出异常; } 该接口可能有一系列get方法或公开某种基于条件的机制,以允许您构造更复杂的查询(我不久前编写的一些代码就是这样做的),但重要的是,您的代码使用的都是这个接口。然后,您可以随心所欲地实现这个接口(如果您的对象模型很简单,则使用直接JDBC;如果您需要更高级的东西,则使用Hibernate),或者在单元测试中模拟它


当你引入一个
Bar
类时,你会重复定义
BarDao
的模式,并根据需要再次实现。

你已经将你的问题标记为“三层”,这是真的:你必须将数据库访问放在一个专用层。你已经将你的问题标记为“三层”,这是真的:你必须把数据库访问放在一个专门的层中。非常感谢你的回答。我应该从数据库访问层一次实例化整个类吗。我有很多领域类。我应该在数据库层中创建单独的函数来初始化每个函数吗classes@Jaz-我的回答会更详细谢谢。我已决定更改代码的模式。现在我知道什么是刀了。我看到了一些例子。再次感谢你的精彩回答。我应该从数据库访问层一次实例化整个类吗。我有很多领域类。我应该在数据库层中创建单独的函数来初始化每个函数吗classes@Jaz-我的回答会更详细谢谢。我已决定更改代码的模式。现在我知道什么是刀了。我看到了一些例子。再次感谢