EOS Low-Code Platform 8 EOS Low-Code Platform 8
产品简介
学习指南
更新说明
安装与集成
上线指南
初见EOS
低代码开发手册
专业代码开发手册
智能体开发手册
专题场景实战
公共服务框架
应用运行治理
常见问题
  • 命名SQL开发指南
  • 基础规范
  • 基本增删改查示例
  • 新增(INSERT)
  • 查询(SELECT)
  • 更新(UPDATE)
  • 删除(DELETE)
  • 基础条件动态SQL
  • 存储过程调用示例
  • SQL片段复用与复杂条件查询示例
  • 注意事项

# 命名SQL开发指南

# 基础规范

  • 命名SQL的ID全局唯一,且ID中不允许包含英文句点(.);

  • XML文件头部必须保留固定声明,不可修改/删除:

  • 包含特殊字符(如</>/&)的SQL需包裹在<![CDATA[]]>中;

# 基本增删改查示例

# 新增(INSERT)

场景:向产品表(PRODUCT)插入一条数据,入参为实体类 / Map,支持 NULL 值替换。

<!-- 方式1:使用parameterClass + 内联参数(推荐) -->

<insert id="insertProduct" parameterClass="com.primeton.model.data.Product">
  INSERT INTO PRODUCT (
        ID, 
        CODE, 
        DESCRIPTION, 
        SUGGESTED_PRICE
    ) VALUES (
        #id#,
        #code#,
        #description:VARCHAR:NO_ENTRY#,  <!-- NULL值替换:description为NO_ENTRY时存入NULL -->
        #suggestedPrice:DECIMAL#
    )
</insert>

<!-- 方式2:使用parameterMap(兼容场景) -->
<parameterMap id="insertProductParam" class="com.primeton.model.data.Product">
    <parameter property="id"  javaType="int" nullValue="-999999"/>
    <parameter property="code" javaType="string"/>
    <parameter property="description"   javaType="string" nullValue="NO_ENTRY"/>
    <parameter property="suggestedPrice"  javaType="DECIMAL" nullValue="0.00"/>
</parameterMap>
<insert id="insertProductByParamMap" parameterMap="insertProductParam">
  INSERT INTO PRODUCT (ID, CODE, DESCRIPTION, SUGGESTED_PRICE) 
  VALUES (?, ?, ?, ?)
</insert>

# 查询(SELECT)

场景:根据产品 ID 查询单条数据,入参为Integer,结果映射为实体类。

<!-- 结果映射:自定义ResultMap -->
<resultMap id="productResultMap" class="com.primeton.model.data.Product">
    <result property="id" column="ID" jdbcType="NUMERIC" />
    <result property="code" column="CODE" jdbcType="VARCHAR"/>
    <result property="description" column="DESCRIPTION" jdbcType="VARCHAR"/>
    <result property="suggestedPrice" column="SUGGESTED_PRICE" jdbcType="DECIMAL"/>
</resultMap>
<select id="selectProductById" parameterClass="java.lang.Integer" resultMap="productResultMap">
    <![CDATA[
        SELECT ID, CODE, DESCRIPTION, SUGGESTED_PRICE
        FROM PRODUCT
        WHERE ID = #value#
    ]]>
</select>
<!-- 别名简化:int等价于java.lang.Integer -->
<select id="selectProductByIntId" parameterClass="int" resultClass="com.primeton.model.data.Product">
  SELECT ID as id, CODE as code FROM PRODUCT WHERE ID = #value#
</select>

场景:查询产品列表,结果自动映射(resultClass)。

<select id="selectAllProduct" resultClass="com.primeton.model.data.Product">
  SELECT 
    ID as id,  <!-- 别名匹配实体属性名 -->
    CODE as code,
    DESCRIPTION as description,
    SUGGESTED_PRICE as suggestedPrice
  FROM PRODUCT
  ORDER BY ID
</select>

场景:多条件查询产品,入参为HashMap(包含分类ID、产品编码)。

<select id="selectProductByMap" parameterClass="java.util.Map" resultMap="productResultMap">
  <![CDATA[
    SELECT ID, CODE, DESCRIPTION
    FROM PRODUCT
    WHERE CAT_ID = #catId# AND CODE = #code#
  ]]>
</select>

场景:按产品名称模糊查询,入参为Product实体类。

<select id="selectProductByDescription" parameterClass="com.primeton.model.data.Product" resultMap="productResultMap">
  <![CDATA[
    SELECT ID, CODE, DESCRIPTION
    FROM PRODUCT
    WHERE DESCRIPTION LIKE '%$description$%'  <!-- $参数$:直接拼接SQL(适用于like/in) -->
  ]]>
</select>

场景:查询产品总数,结果映射为Integer。

<!-- resultClass自动映射(简化) -->
<select id="selectProductCountSimplify" resultClass="int">
  SELECT COUNT(1) as value FROM PRODUCT
</select>

# 更新(UPDATE)

场景:根据产品 ID 更新名称和价格,入参为 Map。

<update id="updateProduct" parameterClass="java.util.Map">
  <![CDATA[
    UPDATE PRODUCT
    SET CODE = #code#, SUGGESTED_PRICE = #price#
    WHERE ID = #id#
  ]]>
</update>

# 删除(DELETE)

场景:根据产品 ID 删除数据,入参为基本类型。

<delete id="deleteProductById" parameterClass="int">
  DELETE FROM PRODUCT WHERE ID = #value#
</delete>

# 基础条件动态SQL

动态 SQL 通过条件标签(如/)实现 SQL 片段的动态拼接,解决复杂条件查询问题。

场景:多条件查询账户(ACCOUNT),支持姓名、邮箱、ID的动态过滤。

<select id="dynamicSelectAccount" parameterClass="com.primeton.model.data.Account" resultMap="accountResultMap">
  SELECT * FROM ACCOUNT
  <dynamic prepend="WHERE">
    <!-- 姓名非空时:按姓名/ lastName模糊查询 -->
    <isNotNull prepend="AND" property="firstName">
      (ACC_FIRST_NAME = #firstName#
      <isNotNull prepend="OR" property="lastName">
        ACC_LAST_NAME = #lastName#
      </isNotNull>)
    </isNotNull>
    <!-- 邮箱非空时:模糊匹配 -->
    <isNotNull prepend="AND" property="emailAddress">
      ACC_EMAIL LIKE #emailAddress#
    </isNotNull>
    <!-- ID大于0时:精确匹配 -->
    <isGreaterThan prepend="AND" property="id" compareValue="0">
      ACC_ID = #id#
    </isGreaterThan>
  </dynamic>
  ORDER BY ACC_LAST_NAME
</select>

# 存储过程调用示例

场景:调用存储过程swap_email_address,交换两个邮箱地址(INOUT参数)。

<!-- 定义参数映射:Map入参,INOUT模式 -->
<parameterMap id="swapEmailParamMap" class="java.util.Map">
  <parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
  <parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>

<!-- 调用存储过程 -->
<procedure id="callSwapEmail" parameterMap="swapEmailParamMap">
  {call swap_email_address (?, ?)}  <!-- 标准JDBC存储过程语法 -->
</procedure>

# SQL片段复用与复杂条件查询示例

本示例基于PRODUCT表结构,演示SQL片段定义、复用(include标签)、in条件循环(iterate)及多条件动态查询,覆盖常用复杂查询场景。

# 定义ResultMap与SQL片段

先定义通用ResultMap和查询字段片段,供后续查询语句复用,减少重复代码。

<!-- 定义PRODUCT表通用ResultMap -->
<resultMap class="com.primeton.model.data.Product" id="productCommonResultMap">
    <result column="ID" property="id" />
    <result column="CODE" property="code" />
    <result column="DESCRIPTION" property="description" />
    <result column="SUGGESTED_PRICE" property="suggestedPrice" />
    <result column="CREATE_TIME" property="createTime" />
    <result column="UPDATE_TIME" property="updateTime" />
</resultMap>

<!-- 定义PRODUCT表通用查询字段片段,通过id复用 -->
<sql id="selectProductCommonVo">
    select d.ID, d.CODE, d.DESCRIPTION, d.SUGGESTED_PRICE,
           d.CREATE_TIME, d.UPDATE_TIME
    from PRODUCT d
</sql>

# 复用查询

<!-- 根据分类ID查询产品列表,结果自动映射(resultMap) -->
<select id="selectProductById" parameterClass="int" resultMap="productCommonResultMap">
    <include refid="selectProductCommonVo" />
    where d.CAT_ID = #value#
</select>
<!--按实体多条件动态查询-->
<select id="selectProductByEntity" parameterClass="com.primeton.model.data.Product" resultMap="productCommonResultMap">
    <include refid="selectProductCommonVo"/>
    where d.CAT_ID = #catId#
    <isNotEmpty property="code">
        and d.CODE like '%$code$%'  <!-- 产品编码模糊查询 -->
    </isNotEmpty>
   
</select>

<!-- 定义ACCOUNT表通用查询片段 -->
<sql id="selectAccountCommonVo">
    select a.ACC_ID, a.ACC_FIRST_NAME, a.ACC_LAST_NAME, a.ACC_EMAIL
    from ACCOUNT a
</sql>

<!-- 关联查询:查询指定账户关联的产品列表 -->
<select id="selectProductByAccountId" parameterClass="java.lang.Long" resultMap="productCommonResultMap">
    <include refid="selectProductCommonVo"/>
    inner join ACCOUNT a on d.ACC_ID = a.ACC_ID  <!-- PRODUCT表通过ACC_ID关联ACCOUNT表 -->
    <include refid="selectAccountCommonVo"/>
    where a.ACC_ID = #accountId#
</select>

# 注意事项

  1. 参数符号区分:
  • #property#:生成PreparedStatement,参数预编译(推荐,防SQL注入);
  • $property$:直接拼接SQL(仅适用于like、in等场景,需自行处理注入风险)。
  1. NULL值处理:
  • 入参:通过#property:jdbcType:nullValue#或parameterMap的nullValue属性替换NULL;
  • 出参:通过resultMap的nullValue属性将数据库NULL映射为指定值。
  1. 多数据库适配:
  • 方式1:ID后缀匹配(如selectProduct.mysql_5.7);
  • 方式2:动态SQL中使用context.databaseType/context.databaseVersion。
  1. 特殊字符处理:包含</>/&等字符的SQL需包裹在中。

  2. 参数类型映射:

  • 基本类型只能有一个属性,名字必须用"value";
  • 使用Map作为参数时,key值对应SQL中的参数名;
  • 内联参数支持jdbcType和nullValue的指定。
  1. 动态SQL标签:
  • 二元条件元素:isEqual、isNotEqual、isGreaterThan、isGreaterEqual、isLessThan、isLessEqual
  • 一元条件元素:isNull、isNotNull、isNotEmpty

← 命名SQL支持多数据库 开发逻辑流代码的EOS服务 →