Реализация коллекционно-ориентированного репозитория (DDD) с mybatis - PullRequest
0 голосов
/ 06 января 2019

Я хочу реализовать хранилище на основе коллекции, основанное на mybatis в качестве основного хранилища сохраняемости. В «Реализации доменного дизайна» (см. Главу 12) указано, что интерфейс репозитория должен имитировать Set:

Например:

interface FlightRepository{
   boolean add(Flight f);
   boolean remove(Flight f);
   // finder methods
   Flight findById(Integer id);
}

Реализация mybatis будет выглядеть следующим образом (при условии реализации весенней загрузки):

@Mapper
interface FlightMapper{
      int createOrUpdate(Flight flight);
      Flight read(int id);
      int delete(Flight flight);
}

@Component
@Transactional
class FlightRepositoryImpl implements FlightRepository {
    @AutoWired FlightMapper mapper;

    boolean add(Flight f){
        int affectedRows = mapper.createOrUpdate(f);
        if(affectedRows == 1) return true 
        else return false;
    }

    boolean remove(Flight f){
        int affectedRows = mapper.delete(f);
        if (affectedRows == 1) return true
        else return false;
    }

    Flight findById(){
        return mapper.read(id);
    }

}

У меня вопрос, как я могу управлять обновлениями репозитория без использования метода saveChanges:

Flight f = flightRepository.findById(1);

f.setDepartureTime(...);
f.setArrivalTime(...);

// flightRepository.saveChanges(); ??

Одним из вариантов реализации было бы сделать так, чтобы хранилище делало копию исходного объекта Flight, прежде чем вернуть его клиенту. Когда придет время сохранять изменения, он будет сравнивать свою внутреннюю копию с объектом полета, возвращенным клиенту. Если внутренняя копия не соответствует объекту, возвращенному клиенту, хранилище постоянных данных будет обновлено версией клиента (с использованием flightMapper.createOrUpdate()).

Однако как я могу запустить эту логику, не вызывая у клиента явный метод saveChanges()? Это означало бы, что мне нужно было бы каким-то образом подключиться к времени жизни объекта Repository с помощью весенней загрузки (другими словами, инициировать обновления до того, как транзакция будет зафиксирована.

1 Ответ

0 голосов
/ 08 января 2019

Вы можете сделать что-то перед фиксацией, применив TransactionSynchronization , используя TransactionSynchronizationAdapter для удобства:

@Bean
public class TransactionEventsListener extends TransactionSynchronizationAdapter {

    @Override
    public void beforeCompletion() {
        // do something before commit
    }
}
...