SuperAPI AI Directory

ddd4j-mybatis

Security & auditing

View repository

Updated 10-16 05:47

About this skill

DDD4J MyBatis-Plus Persistence-Layer Conventions

Encode the usage rules of MyBatis-Plus in DDD4J projects. The LLM will use standard MyBatis-Plus syntax, but it does not conform to project conventions.

Why this skill is needed

The LLM will use implements Serializable to define entities—DDD4J requires extends BaseEntity<T extends Model<?>>(ActiveRecord mode). The LLM will write #{entity.beginTime}in XML—DDD4J requires #{model.beginTime}(@Param("model")). The LLM does not know these conventions.

Capability Boundaries

✅ Strong Suits

  1. Entity inheritance chain — BaseEntity→Model(ActiveRecord),PaginationEntity→BaseEntity
  2. Audit fields — createBy/createTime (INSERT fill), updateBy/updateTime (INSERT_UPDATE fill)
  3. Logical deletion — @TableLogic marks the isDeleted field
  4. @Param("model") convention — the parameter name of getPagedList is model, not entity
  5. Pagination encapsulation — PaginationEntity (default 15 per page, Oracle-style offset=(pageNo-1)*limit+1)
  6. Type handlers — BooleanEnum (0/1), JSON (two sets), List/Set/Array
  7. BaseMapper built-in methods — getPagedList/setStatus/getCountBy*

❌ Out of Scope

  1. Entity/Controller/Service inheritance hierarchy → ddd4j-core
  2. Jackson JSON configuration → ddd4j-jackson

The most common mistakes made by LLMs

# Error Correct approach
1 implements Serializable extends BaseEntity<T>(extend Model, ActiveRecord)
2 Redeclaring createBy/createTime BaseEntity already declares them; subclasses should not add them again
3 XML writes #{entity.beginTime} write #{model.beginTime}
4 new Page<T>(1, 10) use PaginationEntity<T> encapsulation
5 Logical deletion writes UPDATE SET is_delete=1 Use @TableLogic; MyBatis-Plus handles it automatically
6 Custom Boolean field mapping Use BooleanEnum + CustomBooleanEnumTypeHandler
7 Manual offset calculation (pageNo-1)*limit PaginationEntity.getOffset() is already encapsulated

Core rules quick reference

// ✅ 正确:实体定义
@Data
@TableName("sys_user")
public class SysUser extends BaseEntity<SysUser> {   // Model<T> → ActiveRecord
    // ↓ 已继承,不再声明
    // Long createBy, createTime, updateBy, updateTime
    // Integer isDeleted (@TableLogic)
    // LocalDateTime beginTime, endTime (@TableField(exist=false), @JsonIgnore)
    // String keywords, params (@TableField(exist=false), @JsonIgnore)

    private String username;
    private String status;    // BooleanEnum 映射: 0=否, 1=是
}

// ✅ 分页查询
PaginationEntity<SysUser> entity = new PaginationEntity<>();
entity.setPageNo(1);          // 第1页
entity.setLimit(15);          // 默认15条
entity.setBeginTime(LocalDateTime.now().minusDays(7));
List<SysUser> list = baseService.getPagedList(
    new Page<>(entity.getPageNo(), entity.getLimit()), entity
);

// ✅ Mapper XML(注意参数名 model)
<select id="getPagedList" resultType="SysUser">
    SELECT * FROM sys_user
    WHERE is_deleted = 0
    <if test="model.beginTime != null">
        AND create_time >= #{model.beginTime}
    </if>
</select>

// ✅ 内置方法(BaseServiceImpl 已提供)
baseService.setStatus(id, "1");          // @Transactional
baseService.getCountByName("admin");
baseService.getCountByCode("ADMIN");
baseService.getCountByParent(parentId);
baseService.getValue("some_key");        // 从缓存读取

Gotchas

  1. Entities must extend BaseEntity, not implement Serializable — loses ActiveRecord capability
  2. @Param("model") is a fixed convention — XML references must be #{model.xxx}
  3. PaginationEntity.getOffset() is Oracle-style — ((pageNo−1)*limit+1), not starting from 0
  4. beginTime/endTime are on the Entity, not in a separate QueryDTO — add @TableField(exist=false) and it is fine
  5. BooleanEnum maps to Integer 0/1 — the database does not use the native Boolean type
  6. There are two sets of JSON type handlers — core uses fastjson2 (jdbc package), cmet uses hutool
  7. Logical deletion condition is automatically concatenated — SQL does not need to write is_deleted = 0(but it is recommended to add it for complex queries)
  8. setStatus is @Transactional — subclass overrides must also add the transaction annotation

Data Privacy

This skill does not collect, store, or transmit any user data.