Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数据库关系建模_Java_Design Patterns_Data Modeling - Fatal编程技术网

Java 数据库关系建模

Java 数据库关系建模,java,design-patterns,data-modeling,Java,Design Patterns,Data Modeling,我认为描述这个问题最好的方法是用一个例子。我将通过删除不必要的实现细节来尽可能地简化它 假设有一家书店。商店使用后端数据库存储所有数据,并使用Java前端将数据呈现给商店经理,以跟踪所有书籍、客户和订单 数据库包含以下关系: 书(id、标题、作者) 客户(身份证、姓名、电话、地址) 订单(id、日期、客户id、bookId) 另一方面,Java接口使用驱动程序连接到数据库并检索数据。该应用程序由以下类别组成: 书籍 BooksDataLoader BooksTableModel BooksVie

我认为描述这个问题最好的方法是用一个例子。我将通过删除不必要的实现细节来尽可能地简化它

假设有一家书店。商店使用后端数据库存储所有数据,并使用Java前端将数据呈现给商店经理,以跟踪所有书籍、客户和订单

数据库包含以下关系:

  • (id、标题、作者)
  • 客户(身份证、姓名、电话、地址)
  • 订单(id、日期、客户id、bookId)
  • 另一方面,Java接口使用驱动程序连接到数据库并检索数据。该应用程序由以下类别组成:

    书籍
    BooksDataLoader
    BooksTableModel
    BooksView

    客户
    CustomerDataLoader
    CustomerTableModel
    CustomerView

    订单
    OrdersDataLoader
    OrdersTalbeModel
    订单视图

    这些类使用各自的设计准则,您可以使用以下源代码作为参考:

    public class Book {
        private String id;
        private String title;
        private String author;
    
        /*
         * Builder pattern is used so constructor should be hidden. Book objects
         * are built in the BooksDataLoader SwingWorker thread.
         */
        private Book() {}
    }
    
    public class BooksDataLoader extends SwingWorker<List<Book>, Book> {
        private final BooksTableModel booksModel;
        private final List<Book> books = new ArrayList<Book>();
    }
    
    public class BooksTableModel extend AbstractTableModel {
        private final String columnNames = { "Book ID", "Book Title", "Book Author" };
        private final List<Book> books = new ArrayList<Book>();
    }
    
    public class BooksView extends JPanel {
        private final JTable booksTable;
        private final BooksTableModel booksModel;
    }
    
    公共课堂教材{
    私有字符串id;
    私有字符串标题;
    私有字符串作者;
    /*
    *使用了生成器模式,因此应该隐藏构造函数
    *内置在BookDataLoader SwingWorker线程中。
    */
    私人书籍(){}
    }
    公共类BooksDataLoader扩展SwingWorker{
    私人最终书桌模型书桌模型;
    私有最终列表书籍=新ArrayList();
    }
    公共类BooksTableModel扩展AbstractTableModel{
    私有最终字符串columnNames={“图书ID”、“图书标题”、“图书作者”};
    私有最终列表书籍=新ArrayList();
    }
    公共类BooksView扩展了JPanel{
    私人最终JTable书桌;
    私人最终书桌模型书桌模型;
    }
    
    我正在使用实现Book、Customer和Order类。这些类的实例是使用SwingWorker线程内的数据库检索的数据构建的,并使用AbstractTableModel发布到视图中。因此,实际上该应用程序由以下视图(JPanel)组成:BookView、CustomerView和OrdersView,每个视图都包含一个JTable,其中的列如下所示:

    BooksView.booksTable:图书ID |书名|图书作者

    CustomerView.CustomerTable:客户ID |客户名称

    OrdersView.ordersTable:订单ID |日期|客户名称|书名|书籍作者

    当我们试图将表示数据库中外键的实例变量解析为它链接的数据时,就会出现问题。例如,OrdersTableModel具有数据库中所有订单对象的列表结构,但是OrdersView表的第3、4和5列不能直接从订单对象访问,因为它只包含书籍和客户的ID,而不包含实际数据。我尝试的一个解决方案是在Book、Customer和Order类中创建一个静态HashMap,以便跟踪所有检索到的对象,但这会导致数据重复,因为我们在每个视图的表模型中已经有了检索到的对象的列表结构

    我正在寻找一个高效、可扩展(面向对象)的设计解决方案/建议


    提前感谢。

    在关系数据库表上映射OO设计时,这是一个典型的问题

    让我们以您的OrdersTableModel为例:

    订单编号|日期|客户名称|书名|书籍作者

    最后三列是数据库外键ID,而不是要显示的值

    要正确管理此问题,您有两种可能的解决方案:

    第一: 像这样设计订单类

     public class Order{
    private String id;
    private Date date;
    private Customer customer;
    private Book book;
    private Author author;
    
    get and set methods
    }
    
    请注意,客户类型为customer,book类型为book

    现在假设您查询数据库以检索订单列表。 从返回的行中,必须按顺序构建对象列表。当然,db会返回客户、书籍和作者的外键ID,因此:

  • 数据库的查询表顺序
  • 对于每个row build和Orders对象,用行的值填充id和日期
  • 获取客户的外键id。在customer db表上构建一个新查询,并根据id获取正确的客户。构建一个新的客户id,用第二次查询的结果填充其值。将客户对象分配给对象订单的“客户”字段
  • 书和作者也一样
  • 将对象顺序添加到列表中
  • 现在您有了一个假设为10个订单的列表

    对其进行迭代并填充显示的订单表。 要显示示例客户字段,您将有

    listOrders[i].getCustomer().getName(). // listOrders[i] is an Order object. getCusotmer returns a customer object. getName is a Customer's method that return the String name.
    
    书和作者也一样

    第二种方法

    设计订单类如下所示:

      public class Order{
    private String id;
    private Date date;
    private int customer;
    private int book;
    private int author;
    
    get and set methods
    }
    
    注意,现在customer等是INT字段。保持从db检索的int引用键

    再次查询表订单

    为每行生成一个Order对象。用数据库的id简单地填写customer等值

    现在,您需要显示订单列表

    在列表上迭代。 显示客户用途时

    listOrders[i].getCustomer().getName().
    
    注:由于customer字段是一个int引用键,因此geCustomer应该

  • 在db customer表上执行e查询,根据id检索正确的客户
  • 构建一个填充其字段的客户对象
  • 返回对象
  • 因此,这两种方法的区别在于:

    首先构建一个完整的订单对象,其中还包含客户对象等。当需要显示某些内容时,您就拥有了所需的所有内容

    第二种方法是构建一个轻量级对象。例如,当需要显示需要查询数据库的客户数据时(这称为延迟加载)

    我建议你考虑使用ORM帮助你在数据库上映射OO设计并帮助你。