java CQRS系统的基本存储库

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java CQRS系统的基本存储库相关的知识,希望对你有一定的参考价值。

@Component
public class TestResultSqliteRepository extends SqliteRepository<UUID, TestResult> implements TestResultRepository {

    @Autowired
    public TestResultSqliteStore(DSLContext dslContext, ObjectMapper jackson) {
        super(dslContext, new TestResultObjectMapper(jackson));
    }

    @Override
    protected Table<Record> tableName() {
        return table("test_result");
    }

    @Override
    protected Map<String, Object> getFields(TestResult testResult) {
        return HashMap.of(
                "type", testResult.type(),
                "timestamp", testResult.timestamp(),
                "duration", testResult.duration(),
                "data", mapper().serialize(testResult.data())
        );
    }

    private static class TestResultObjectMapper extends JooqObjectReflexionMapper<TestResult> {
        public TestResultObjectMapper(ObjectMapper jackson) {
            super(jackson);
        }

        @Override
        protected HashMap<String, Class<?>> mapFieldsToTypes() {
            return HashMap.of(
                    "id", UUID.class,
                    "timestamp", Instant.class,
                    "type", TestCategory.class,
                    "duration", Long.class
            );
        }

        @Override
        protected TestResult newInstance() {
            return new TestResult();
        }
    }
}
public abstract class SqliteStore<ID, ROOT extends AggregateRoot<ID>> implements Store<ID, ROOT> {

    public SqliteStore(DSLContext dslContext, JooqObjectMapper<ROOT> mapper) {
        this.dslContext = dslContext;
        this.mapper = mapper;
    }

    protected abstract Table<Record> tableName();

    protected abstract Map<String, Object> getFields(ROOT entity);

    protected DSLContext dslContext() {
        return dslContext;
    }

    protected JooqObjectMapper<ROOT> mapper() {
        return mapper;
    }

    protected java.util.Map<Field<Object>, Object> transformFields(ROOT entity) {
        return getFields(entity).map((key, value) -> Tuple.of(field(key), value)).toJavaMap();
    }

    @Override
    public ROOT get(ID id) {
        return dslContext
                .selectFrom(tableName())
                .where(field("id").equal(id))
                .fetchOne()
                .map(mapper);
    }

    @Override
    public void add(ROOT root) {
        try {
            if (!exist(root.id())) {
                dslContext.insertInto(tableName())
                        .set(field("id"), root.id())
                        .set(transformFields(root))
                        .execute();
            } else {
                dslContext.update(tableName())
                        .set(transformFields(root))
                        .where(field("id").equal(root.id()))
                        .execute();
            }
        } catch (DataAccessException e) {
            logger.error("Add error", e);
        }
    }

    private boolean exist(ID id) {
        return dslContext.selectFrom(tableName()).where(field("id").equal(id)).fetchOne() != null;
    }

    @Override
    public void delete(ROOT root) {
        dslContext.deleteFrom(tableName()).where(field("id").equal(root.id())).execute();
    }

    @Override
    public List<ROOT> getAll() {
        return List.ofAll(dslContext.selectFrom(tableName()).fetch().map(mapper));
    }

    private final DSLContext dslContext;
    private final JooqObjectMapper<ROOT> mapper;
}
public abstract class JooqObjectReflexionMapper<R> extends JooqObjectMapper<R> {

    public JooqObjectReflexionMapper(ObjectMapper jackson) {
        super(jackson);
    }

    @Override
    public R map(Record record) {
        HashMap<String, Class<?>> types = mapFieldsToTypes();
        R instance = newInstance();
        Reflect on = Reflect.on(instance);
        types.forEach((fieldName, type) -> {
            on.set(fieldName, record.get(fieldName, type));
        });
      
        return instance;
    }

    protected abstract HashMap<String, Class<?>> mapFieldsToTypes();

    protected abstract R newInstance();
}

以上是关于java CQRS系统的基本存储库的主要内容,如果未能解决你的问题,请参考以下文章

CQRS不等同于读写分离

存储库如何适应 CQRS?

NestJS CQRS:(存储库的)依赖注入在处理程序中不起作用

命令和查询责任分离 (CQRS) 模式

通过Java学习与演示CQRS与事件溯源模式

通过Java学习与演示CQRS与事件溯源模式