首页 > 解决方案 > 用mybatis实现面向集合的存储库(DDD)

问题描述

我想实现一个基于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 对象的生命周期(换句话说,在提交事务之前触发更新。

标签: spring-bootmybatisddd-repositories

解决方案


为方便起见,您可以通过使用TransactionSynchronizationAdapter实现TransactionSynchronization在提交之前做一些事情:

@Bean
public class TransactionEventsListener extends TransactionSynchronizationAdapter {

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

推荐阅读