Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.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 DAO模式多表原子事务_Java_Database_Jdbc_Dao - Fatal编程技术网

Java DAO模式多表原子事务

Java DAO模式多表原子事务,java,database,jdbc,dao,Java,Database,Jdbc,Dao,我试图使用DAO模式插入到两个具有一对一关系的表中。我有客户和地址表格。每个customer都有一个address\u id字段,该字段引用address表的id 我要做的是将客户地址插入地址表,并获取生成的地址\u id,然后使用该id将客户插入客户表。如果其中任何一项任务失败,数据库将保持不变 我没有使用spring或hibernate之类的框架,只是使用带有DAO模式的普通JDBC 这是代码。在Application.java中,首先插入地址,然后插入客户。如果客户插入失败,则地址仍保留在

我试图使用DAO模式插入到两个具有一对一关系的表中。我有
客户
地址
表格。每个
customer
都有一个
address\u id
字段,该字段引用
address
表的id

我要做的是将客户地址插入
地址
表,并获取生成的
地址\u id
,然后使用该id将客户插入
客户
表。如果其中任何一项任务失败,数据库将保持不变

我没有使用spring或hibernate之类的框架,只是使用带有DAO模式的普通JDBC

这是代码。在
Application.java
中,首先插入地址,然后插入客户。如果客户插入失败,则地址仍保留在数据库中

我可以关闭数据库连接的自动提交,并将地址和客户插入合并到一个数据库连接中,但这是否符合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);
        }
    }
}
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);
        }
    }
}
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.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);
        }
    }
}
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("john.doe@mail.com");
        customer.setAddress(address);

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

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

由于这是一种一对一的关系,并且假设您不会自己创建地址,我只会将地址的创建放在CustomerDAOImpl中。以后,如果有必要,您可以在AddressDAO中公开地址对象的检索。对地址的更新也可以通过相同的CustomerDAOImpl类处理


从长远来看,如果将来要过渡到JPA/Hibernate,框架将显示相同的行为,那么这种方法将工作得更好。此外,这还可以避免您必须在DAO类之间进行自己的事务/连接管理。

如果您希望事务以原子方式执行,那么您需要使用事务,如果“与DAO模式相对应”是一个意见问题的话。模式是指导,而不是法律。