Java 具有依赖项的多个DAO(外键)

Java 具有依赖项的多个DAO(外键),java,database,jdbc,model,dao,Java,Database,Jdbc,Model,Dao,我正在创建一个具有数据库访问权限的应用程序。我不使用JPA、JooQ或其他框架是有原因的(我也不想这样做,这对我的问题也不重要)。所以我使用JDBC并编写简单的sql 我的模型如下所示: public class Contact{ AddressBook addressBok; String name; ... } 我现在创建了两个DAO,一个用于联系人和地址簿。我的联系人表有地址簿表的外键(地址簿id)。 我有一个服务类(例如ContactService),它将使用相应的DAO读

我正在创建一个具有数据库访问权限的应用程序。我不使用JPA、JooQ或其他框架是有原因的(我也不想这样做,这对我的问题也不重要)。所以我使用JDBC并编写简单的sql

我的模型如下所示:

public class Contact{
  AddressBook addressBok;
  String name;
  ...
}
我现在创建了两个DAO,一个用于联系人和地址簿。我的联系人表有地址簿表的外键(地址簿id)。 我有一个服务类(例如ContactService),它将使用相应的DAO读取每个对象,并将其组合到一个联系人

现在的问题是:我在ContactDAO的结果集中有地址簿id。如何将其传递给服务类,然后服务类使用AddressBookDAO读取相应的AddressBook?由于模型是共享的,因此将
字符串addressBookId
放入联系人并不是一个好的解决方案,因为使用此模型的客户端可能对数据库一无所知

我知道这些问题,但如何解决却没有答案:
最佳做法是在每个表中使用POJO域对象,您可以在其中保存关系字段,如
地址\u book\u id
。因此,您将拥有独立于树的类
Contact
Address
AddressBook
和独立的DAO
ContractDAO
AddressDAO
。您的
ContactService
将使用这6个对象来加载、保存和修改相关数据。

您可以使用decorator模式包装要向其添加外键的实体(模型类),如下所示:

如何使用: 例如:保存(插入db)一个联系人(我上次在这里发现问题,所以我用这个解决方案解决了问题)-->问题:如何在不知道fk地址的情况下插入联系人,在save的args中

    public class ContactDAO extends DAO<Contact>{
    // ....
    
    @Override
    public int save(IEntity contact){
        ForeignKeyWrapper ctFk = (ForeignKeyWrapper)contact;
        int address_book_id = ctFk.getFK();
        Contact ct = (Contact)ctFk.getEntity();
        String name = ct.getName();
        // retrieve other fields of contact here
    
        //use some sql to insert the contact in the db, now you have also the fk
        String insertQuery = "INSERT INTO CONTACT(name,..other fields of contact.. , address_book_id) VALUES("+
                     name + "," +
                    /*other fields*/
                    address_book_id + ")";
        //execute it here and fetch the id of the inserted row
    
    }
    
    // ....
    }
    
    public class clientClass{
        //....
            public static void main(String[] args) {
            IEntity contact = new Contact(/* init fields*/);
            IEntity addressBook = new AddressBook(/* init fields*/);
            ForeignKeyWrapper ctFKW = new ForeignKeyWrapper(contact);
            //link contact to addressBook (e.g: when creating a contact to insert it into the db)
            ctFKW.setFK(addressBook.getId());
            ContactDAO ctDAO = new ContactDAO(/*connection*/);
            ctDAO.save(ctFKW);
        }
        //....
    
    }
公共类ContactDAO扩展了DAO{
// ....
@凌驾
公共整数保存(IEntity联系人){
ForeignKeyWrapper ctFk=(ForeignKeyWrapper)联系人;
int address_book_id=ctFk.getFK();
Contact ct=(Contact)ctFk.getEntity();
String name=ct.getName();
//在此处检索其他联系人字段
//使用一些sql在db中插入联系人,现在您也有了fk
String insertQuery=“插入联系人(姓名,…联系人的其他字段..,地址\u book\u id)值(”+
名称+“,”+
/*其他领域*/
地址(地址簿(id+))";
//在这里执行它并获取插入行的id
}
// ....
}
公共类clientClass{
//....
公共静态void main(字符串[]args){
IEntity联系人=新联系人(/*初始字段*/);
IEntity addressBook=新地址簿(/*初始字段*/);
ForeignKeyWrapper ctFKW=新ForeignKeyWrapper(联系人);
//将联系人链接到通讯簿(例如:创建联系人以将其插入数据库时)
ctFKW.setFK(addressBook.getId());
ContactDAO ctDAO=新ContactDAO(/*连接*/);
ctDAO.save(ctFKW);
}
//....
}

您可以添加一个生成器类来构建联系人对象,并将其外键链接到addressBook对象ID,以封装构建逻辑,并简化过程

是的,当然我可以将字段addressbookid添加到联系人类中。但这难道不是糟糕的对象设计吗?我宁愿将AddressBook对象放入contact类中。我不想仅仅因为数据库策略就让我的模型“脏”了?!是的,为什么不呢?您可以使用对addressbook对象的引用,并使用getAddressBookId()通过addressbook对象获取id。参考对象或仅参考id取决于您的需要。如果您想加载所有级联结构,最好绑定整个对象。我没有得到您的答案。我有一个对象联系人,其中包含一个对象通讯簿。现在我有了一个方法,可以读取这两个对象并在contact对象中设置addressbook。此方法使用两个DAO。但是在从contactdao中读取contact之后,我没有任何对addresabookid的引用,因为这个列表不是我的contact类的属性,因为这是一个糟糕的设计。那么,如何将addressbookid从contactdao传递给读取这两个对象的方法呢?