代码之家  ›  专栏  ›  技术社区  ›  Derick Schoonbee

按工作单位自动递增

  •  1
  • Derick Schoonbee  · 技术社区  · 16 年前

    我正在构建一个持久层来抽象我需要的不同类型的数据库。在关系方面,我有mySQL、Oracle和PostgreSQL。

    CREATE TABLE Contact (
      ID varchar(15),
      NAME varchar(30)
    );
    
    CREATE TABLE Address (
      ID varchar(15),
      CONTACT_ID varchar(15),
      NAME varchar(50)
    );
    

    在本例中,我使用代码生成适合15个字符的系统特定的字母数字唯一ID。因此,如果我插入一个带有地址的联系人记录,在提交之前,我会生成Contact.ID和Address.Contact\u ID。

    我创造了一个 Unit of Work (除其他外)根据 Martin Fowler's patterns

    当我有一个不在我控制下的数据库,并且ID字段是自动递增的(或者在Oracle序列中)时,问题场景就出现了。在这种情况下,我事先没有db生成的Contact.ID,因此当我创建地址时,我没有Address.Contact\u ID的值。事务没有在db会话上启动,因为所有内容都保存在内存中的标识映射中。

    问题: 解决这个问题的好方法是什么(避免不必要的db往返)

    一些想法:

    SELECT Auto_increment FROM information_schema.tables WHERE table_name='Contact'; 
    

    但这是特定于MySQL的,可能对其他数据库也可以做类似的事情。如果执行此操作,则需要执行第一次插入,获取ID,然后更新当前事务上下文中的所有子项(Address.CONTACT\ ID)。

    1 回复  |  直到 16 年前
        1
  •  1
  •   pilcrow    16 年前

    避免显式引用 CONTACT_ID 完全是。假设 Contact.NAME 联系人ID REFERENCES Contact(ID)

    INSERT INTO Contact (NAME) VALUES ('Joe Bloggs'); -- Contact.ID auto-generated
    INSERT INTO Address (CONTACT_ID, NAME)
         VALUES ((SELECT ID FROM Contact WHERE NAME = 'Joe Bloggs'),
                 '123 Apple Lane');
    

    现在 Address.CONTACT_ID 在代码不知道键的值甚至其类型的情况下是正确的。

    推荐文章