2017-02-17 12 views
1

1対1の関係を持つ2つのテーブルにDAOパターンを挿入しようとしています。私はcustomeraddressテーブルを持っています。 customerには、フィールドがあり、addressテーブルのIDを参照します。私が何をしたいかJava DAOパターン複数テーブルアトミックトランザクション

addressテーブルに顧客の住所を挿入し、生成されたaddress_idを取得し、customerテーブルに顧客を挿入するためにそれを使用します。これらのタスクのいずれかが失敗した場合、データベースは変更されません。

私はspringやhibernateのようなフレームワークを使用していません。DAOパターンを持つ単純なJDBCです。

ここにコードがあります。 Application.javaでは、まず住所を挿入してから、顧客を挿入します。顧客の挿入が失敗した場合、アドレスはデータベースに残ります。

データベース接続の自動コミットをオフにして、1つのデータベース接続でアドレスと顧客の挿入をマージできますが、これはDAOパターンに対応していますか?

Customer.java:

package com.example.model; 

public class Customer { 

    private long id; 
    private String firstName; 
    private String lastName; 
    private String email; 
    private byte[] salt; 
    private byte[] digest; 
    private Address address; 

    // getters and setters 
} 

Address.java:

package com.example.model; 

public class Address { 

    private long id; 
    private String address; 
    private String postalCode; 
    private String phone; 

    // getters and setters 
} 

AddressDAO.java:

package com.example.dao; 

import com.example.model.Address; 

public interface AddressDAO { 

    void create(Address address); 
} 

AddressDAOImpl.java:

package com.example.dao; 

import com.example.model.Address; 
import com.example.util.DatabaseUtil; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 

public class AddressDAOImpl implements AddressDAO { 

    private static final Logger LOG = LoggerFactory.getLogger(AddressDAOImpl.class); 

    @Override 
    public void create(Address address) { 
     String sql = "INSERT INTO address (address, postal_code, phone) VALUES (?, ?, ?)"; 
     try (PreparedStatement ps = DatabaseUtil.getConnection() 
       .prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS)) { 
      ps.setString(1, address.getAddress()); 
      ps.setString(2, address.getPostalCode()); 
      ps.setString(3, address.getPhone()); 
      ps.executeUpdate(); 
      try (ResultSet rs = ps.getGeneratedKeys()) { 
       if (rs.next()) { 
        address.setId(rs.getShort(1)); 
       } 
      } 
     } catch (SQLException e) { 
      LOG.error(e.getMessage(), e); 
     } 
    } 
} 

CustomerDAO.java:

package com.example.dao; 

import com.example.model.Customer; 

public interface CustomerDAO { 

    void create(Customer customer); 
} 

CustomerDOAImpl.java:

package com.example.dao; 

import com.example.model.Customer; 
import com.example.util.DatabaseUtil; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 

public class CustomerDAOImpl implements CustomerDAO { 

    private static final Logger LOG = LoggerFactory.getLogger(CustomerDAOImpl.class); 

    @Override 
    public void create(Customer customer) { 
     String sql = "INSERT INTO customer (first_name, last_name, email, address_id, salt, digest) " + 
      "VALUES (?, ?, ?, ?, ?, ?)"; 
     try (PreparedStatement ps = DatabaseUtil.getConnection() 
       .prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS)){ 
      ps.setString(1, customer.getFirstName()); 
      ps.setString(2, customer.getLastName()); 
      ps.setString(3, customer.getEmail()); 
      ps.setLong(4, customer.getAddress().getId()); 
      ps.setBytes(5, customer.getSalt()); 
      ps.setBytes(6, customer.getDigest()); 
      ps.executeUpdate(); 
      try (ResultSet rs = ps.getGeneratedKeys()) { 
       if (rs.next()) { 
        customer.setId(rs.getLong(1)); 
       } 
      } 
     } catch (SQLException e) { 
      LOG.error(e.getMessage(), e); 
     } 
    } 
} 

Application.java:

package com.example; 

import com.example.dao.AddressDAO; 
import com.example.dao.AddressDAOImpl; 
import com.example.dao.CustomerDAO; 
import com.example.dao.CustomerDAOImpl; 
import com.example.model.Address; 
import com.example.model.Customer; 

public class Application { 

    public static void main(String[] args) { 
     Customer customer = new Customer(); 
     Address address = new Address(); 
     CustomerDAO customerDAO = new CustomerDAOImpl(); 
     AddressDAO addressDAO = new AddressDAOImpl(); 

     address.setAddress("Address"); 
     address.setPostalCode("123456789"); 
     address.setPhone("987654321"); 

     customer.setFirstName("John"); 
     customer.setLastName("Doe"); 
     customer.setEmail("[email protected]"); 
     customer.setAddress(address); 

     addressDAO.create(customer.getAddress()); 
     customerDAO.create(customer); 

     System.out.println(customer.getId()); 
    } 
} 
+0

アトミックに実行したい場合は、_ "DAOパターンに対応する" _が意見であれば、トランザクションを使用する必要があります。パターンはガイダンスであり、法律ではありません。 –

答えて

0

これは1対1の関係であり、あなたは「wouldnと仮定しているのでそれ自身でアドレスを作成する場合、私は単にCustomerDAOImpl内にAddressの作成を行います。その後、必要に応じて後でAddressDAOでAddressオブジェクトの取得を公開することができます。アドレスの更新は、同じCustomerDAOImplクラスを介して処理することもできます。

このアプローチは、将来フレームワークで同じ動作が示されるJPA/Hibernateに移行する場合、長期的にはうまくいくでしょう。さらに、これにより、DAOクラス間で独自のトランザクション/接続管理を行う必要がなくなります。

関連する問題