Я сейчас работаю с JDBC и хочу создать отдельные слои для доступа к данным и бизнес-логики.Я создал несколько DAO для каждой сущности и несколько сервисов для моей бизнес-логики.Но я столкнулся с проблемой с транзакциями.В каждом DAO у меня есть CRUD, где я открываю соединение в каждой операции и после закрываю его.Но если мне нужно использовать несколько операций, как в транзакции, это не сработает.
Итак, я создаю одно соединение для всего DAO, но мне нужно открывать и закрывать соединение для каждой операции вне DAO.
Пример моего DAO
public class UserDAOImpl implements UserDAO {
private Connection connection;
public UserDAO(Connection connection) {
this.connection = connection;
}
// CRUD operations
}
Абстрактная фабрика DAO
public abstract class DAOFactory {
public abstract UserDAO getUserDAO();
public abstract ItemDAO getItemDAO();
public abstract OrderDAO getOrderDAO();
public abstract RoleDAO getRoleDAO();
public static DAOFactory getDAOFactory(Class<? extends DAOFactory> factoryClass) throws IllegalAccessException, InstantiationException {
return factoryClass.newInstance();
}
}
Пример реализации фабрики MySQL DAO
public class MySqlDAOFactory extends DAOFactory {
private UserDAO userDAO;
private ItemDAO itemDAO;
private OrderDAO orderDAO;
private RoleDAO roleDAO;
@Override
public UserDAO getUserDAO() {
if (userDAO == null) {
userDAO = new UserDAOImpl(getConnection());
}
return userDAO;
}
@Override
public ItemDAO getItemDAO() {
if (itemDAO == null) {
itemDAO = new ItemDAOImpl(getConnection());
}
return itemDAO;
}
@Override
public OrderDAO getOrderDAO() {
if (orderDAO == null) {
orderDAO = new OrderDAOImpl(getConnection());
}
return orderDAO;
}
@Override
public RoleDAO getRoleDAO() {
if (roleDAO == null) {
roleDAO = new RoleDAOImpl(getConnection());
}
return roleDAO;
}
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
Connection connection = null;
Context initCtx = null;
try {
initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/mysql");
connection = ds.getConnection();
} catch (NamingException | SQLException e) {
e.printStackTrace();
}
return connection;
}
}
Пример метода DAO
public Optional<User> findById(Long id) {
User user = null;
try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM shop.user WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
statement.setLong(1, id);
ResultSet resultSet = statement.executeQuery();
resultSet.next();
user = userMapper.map(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
return Optional.ofNullable(user);
}