更新架构标准说明

This commit is contained in:
孙小云 2026-01-17 17:16:42 +08:00
parent dae47dd897
commit 02aca1c35c
1 changed files with 64 additions and 2 deletions

View File

@ -688,7 +688,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where {entity}_id = #{{{entity}Id}} where {entity}_id = #{{{entity}Id}}
</select> </select>
<insert id="insert{Entity}" parameterType="com.ruoyi.{module}.mapper.entity.{Entity}Entity" useGeneratedKeys="true" keyProperty="{entity}Id"> <insert id="insert{Entity}" parameterType="com.ruoyi.{module}.mapper.entity.{Entity}Entity" useGeneratedKeys="true" keyProperty="{entity}Id" keyColumn="{entity}_id">
insert into {module}_{table} insert into {module}_{table}
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="fieldName != null and fieldName != ''">field_name,</if> <if test="fieldName != null and fieldName != ''">field_name,</if>
@ -734,6 +734,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- 使用 `<sql>` 定义可复用的 SQL 片段 - 使用 `<sql>` 定义可复用的 SQL 片段
- 使用动态 SQL 标签:`<if>`, `<trim>`, `<foreach>` - 使用动态 SQL 标签:`<if>`, `<trim>`, `<foreach>`
- 插入操作使用 `useGeneratedKeys="true"` 返回主键 - 插入操作使用 `useGeneratedKeys="true"` 返回主键
- **重要**:插入操作必须同时指定 `keyProperty``keyColumn` 属性
- 时间字段使用 `sysdate()` 函数 - 时间字段使用 `sysdate()` 函数
--- ---
@ -904,7 +905,10 @@ public class {Entity}DomainImpl implements I{Entity}Domain
public int insert{Entity}({Entity} {entity}) public int insert{Entity}({Entity} {entity})
{ {
{Entity}Entity entity = {Entity}DomainConvert.toEntity({entity}); {Entity}Entity entity = {Entity}DomainConvert.toEntity({entity});
return {entity}Mapper.insert{Entity}(entity); int result = {entity}Mapper.insert{Entity}(entity);
// 【重要】MyBatis 会将自增主键回填到 entity 对象,需要同步回 model 对象
{entity}.set{Entity}Id(entity.get{Entity}Id());
return result;
} }
@Override @Override
@ -933,6 +937,64 @@ public class {Entity}DomainImpl implements I{Entity}Domain
- 使用**构造器注入**Constructor Injection - 使用**构造器注入**Constructor Injection
- 字段声明为 `private final` - 字段声明为 `private final`
- 通过 Convert 类进行对象转换 - 通过 Convert 类进行对象转换
- **【关键】insert 方法必须将 Entity 的主键回填到 Model 对象**
**⚠️ MyBatis 主键回填注意事项:**
MyBatis 在执行 INSERT 操作后,会将数据库自动生成的主键值回填到 `Entity` 对象中,但**不会自动同步到传入的 `Model` 对象**。
**错误示例(会导致主键丢失):**
```java
@Override
public int insert{Entity}({Entity} {entity})
{
{Entity}Entity entity = {Entity}DomainConvert.toEntity({entity});
return {entity}Mapper.insert{Entity}(entity);
// ❌ 错误entity 中的主键没有同步回 {entity} 对象
}
```
**正确示例(主键正确回填):**
```java
@Override
public int insert{Entity}({Entity} {entity})
{
{Entity}Entity entity = {Entity}DomainConvert.toEntity({entity});
int result = {entity}Mapper.insert{Entity}(entity);
// ✅ 正确:将 entity 中的主键同步回 {entity} 对象
{entity}.set{Entity}Id(entity.get{Entity}Id());
return result;
}
```
**为什么需要手动同步主键?**
1. **对象转换导致的隔离**`BeanUtils.copyProperties()` 只是属性拷贝,创建了新的 Entity 对象
2. **MyBatis 只回填 Entity**MyBatis 的 `useGeneratedKeys` 只会将主键设置到 Mapper 方法参数Entity
3. **Model 对象不会自动更新**:原始的 Model 对象与 Entity 对象是两个独立的对象,需要手动同步
**不同步主键的后果:**
如果不将主键同步回 Model 对象,会导致:
- Service 层无法获取新插入记录的主键 ID
- 后续依赖主键的业务逻辑会失败(如关联表插入)
- 可能产生重复数据或数据不一致问题
**示例场景:**
```java
// Service 层调用
Device device = new Device();
device.setDeviceName("测试设备");
deviceDomain.insertDevice(device);
// 如果没有主键回填device.getDeviceId() 将返回 null
Long deviceId = device.getDeviceId(); // 期望得到新插入的 ID
// 后续业务逻辑依赖这个 ID
Dock dock = new Dock();
dock.setDeviceId(deviceId); // 如果 deviceId 为 null会导致关联失败
dockDomain.insertDock(dock);
```
### 5.4 Domain Convert 转换类规范 ### 5.4 Domain Convert 转换类规范