使用mybatis实施面向集合的存储库(DDD)

时间:2019-01-06 01:19:50

标签: spring-boot mybatis ddd-repositories

我想基于mybatis实现基于集合的存储库作为基础持久性存储。从“实现域驱动的设计”(请参阅​​第12章)中,表明存储库接口应模仿Set

例如:

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

mybatis实现可能类似于以下几行(假设使用spring boot实现):

@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()方法的情况下触发此逻辑?这意味着我将必须能够以某种方式使用spring boot挂钩到Repository对象的生存期(换句话说,在提交事务之前触发更新。

1 个答案:

答案 0 :(得分:1)

为方便起见,您可以通过使用TransactionSynchronization实现TransactionSynchronizationAdapter来做一些事,然后再提交:

@Bean
public class TransactionEventsListener extends TransactionSynchronizationAdapter {

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