重构:使用 MyBatis-Flex 迁移应用 ORM

将应用自管表的 JdbcClient 数据访问迁移为实体、Mapper、构造器查询和必要的显式 SQL。

保留 AgentScope 自管表及原有业务语义,并补充事务、查询与数据库集成测试。
This commit is contained in:
Zhu Junhao
2026-08-31 12:13:06 +08:00
parent c13302c0cb
commit e968a8ddc1
54 changed files with 3702 additions and 698 deletions

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.easyflow.manuagent.mapper.AgentEventMapper">
<!-- 显式结果映射避免 payload 列与实体 payloadJson 属性名称不同而丢失事件负载。 -->
<resultMap id="agentEventResultMap" type="tech.easyflow.manuagent.entity.AgentEventEntity">
<id property="id" column="id"/>
<result property="projectId" column="project_id"
typeHandler="tech.easyflow.manuagent.typehandler.UuidTypeHandler"/>
<result property="runId" column="run_id"
typeHandler="tech.easyflow.manuagent.typehandler.UuidTypeHandler"/>
<result property="eventType" column="event_type"/>
<result property="eventId" column="event_id"/>
<result property="payloadJson" column="payload"
typeHandler="tech.easyflow.manuagent.typehandler.JsonbStringTypeHandler"/>
<result property="createdAt" column="created_at"/>
</resultMap>
<!--
PostgreSQL INSERT ... RETURNING 同时完成写入和序号读取,不使用“先插入、再查最大值”
这种在并发场景下会取错事件的实现。affectData 保留正确的事务与缓存语义。
-->
<select id="insertReturning" resultMap="agentEventResultMap" affectData="true" flushCache="true">
INSERT INTO app.agent_event(project_id, run_id, event_type, event_id, payload)
VALUES (
#{event.projectId, typeHandler=tech.easyflow.manuagent.typehandler.UuidTypeHandler},
#{event.runId, typeHandler=tech.easyflow.manuagent.typehandler.UuidTypeHandler},
#{event.eventType},
#{event.eventId},
#{event.payloadJson, jdbcType=OTHER,
typeHandler=tech.easyflow.manuagent.typehandler.JsonbStringTypeHandler})
<!-- 与迁移前 JDBC 返回字段一致event_id 已完成持久化,但无需再次回传给业务层。 -->
RETURNING id, project_id, run_id, event_type, payload, created_at
</select>
<!-- PostgreSQL JSONB 运算仅封装在数据库适配层,业务服务不感知方言细节。 -->
<select id="selectLatestStartedPhase" resultType="string">
SELECT payload -&gt;&gt; 'phase'
FROM app.agent_event
WHERE run_id = #{runId, typeHandler=tech.easyflow.manuagent.typehandler.UuidTypeHandler}
AND event_type = 'RUN_STARTED'
ORDER BY id DESC
LIMIT 1
</select>
<select id="selectLatestMaterialResponseJson" resultType="string">
SELECT payload::text
FROM app.agent_event
WHERE project_id = #{projectId, typeHandler=tech.easyflow.manuagent.typehandler.UuidTypeHandler}
AND event_type = 'ASK_RESPONDED'
AND jsonb_typeof(payload -&gt; 'decisions') = 'array'
ORDER BY id DESC
LIMIT 1
</select>
</mapper>