fix(mybatis): avoid param-name collision and pg alias quoting in relation SQL

This commit is contained in:
sol 2026-04-14 15:24:08 +08:00
parent e23c89a843
commit bb56d11077
2 changed files with 69 additions and 67 deletions

View file

@ -0,0 +1,4 @@
package com.bgasol.common.core.base.dto;
public class RelationRow {
}

View file

@ -1,21 +1,33 @@
package com.bgasol.common.core.base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bgasol.common.core.base.dto.RelationRow;
import com.bgasol.common.core.base.entity.BaseEntity;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 通用基础 Mapper
* <p>
* {@link BaseMapper} 的基础上补充了按表名字段名执行通用查询/插入/删除的方法
* 适用于有中间表结构的操作
* </p>
*
* @param <T> 实体类型需继承 {@link BaseEntity}
*/
@Mapper
public interface MyBaseMapper<T extends BaseEntity> extends BaseMapper<T> {
/**
* 获取中间表 被查询主键值 列表
* 根据主字段值查询从字段值列表
*
* @param tableName 中间表名
* @param masterName 查询主键名
* @param masterValue 查询主键值
* @param slaveName 被查询主键名
* @param tableName 目标表名
* @param masterName 主字段名条件字段
* @param masterValue 主字段值等值查询
* @param slaveName 从字段名返回字段
* @return 从字段值列表
*/
@Select("select ${slaveName} from ${tableName} where ${masterName} = #{masterValue}")
List<String> findFromTable(@Param("tableName") String tableName,
@ -24,85 +36,71 @@ public interface MyBaseMapper<T extends BaseEntity> extends BaseMapper<T> {
@Param("slaveName") String slaveName);
/**
* 获取中间表 被查询主键值 列表支持多个 masterValue
* <p>
* 返回值每一行是一个 Map包含 master -> , slave ->
* 批量根据主字段值集合查询键值对
*
* @param tableName 中间表名
* @param masterName 查询主键名
* @param masterValues 查询主键值列表
* @param slaveName 被查询主键名
* @param tableName 目标表名
* @param masterName 主字段名作为 key
* @param masterValues 主字段值集合IN 查询
* @param slaveName 从字段名作为 value
* @return 键值对列表key=主字段值value=从字段值
*/
@Select({
"<script>",
"select ${masterName}, ${slaveName}",
"from ${tableName}",
"where ${masterName} in",
"<foreach collection='masterValues' item='val' open='(' separator=',' close=')'>",
" #{val}",
"</foreach>",
"</script>"
})
List<Map<String, String>> findFromTableBatch(@Param("tableName") String tableName,
@Param("masterName") String masterName,
@Param("masterValues") List<String> masterValues,
@Param("slaveName") String slaveName);
@Select("""
<script>
SELECT
${masterName} AS sourceId,
${slaveName} AS targetId
FROM ${tableName}
WHERE ${masterName} IN
<foreach collection='masterValues' item='val' open='(' separator=',' close=')'>
#{val}
</foreach>
</script>
""")
List<RelationRow> findFromTableBatch(
@Param("tableName") String tableName,
@Param("masterName") String masterName,
@Param("masterValues") Set<String> masterValues,
@Param("slaveName") String slaveName
);
/**
* 插入中间表数据
* 批量插入主从字段键值对
*
* @param tableName 中间表名
* @param masterName 主表主键名
* @param masterValue 主表主键值
* @param slaveName 从表主键名
* @param slaveValue 从表主键值
* @param tableName 目标表名
* @param masterName 主字段名
* @param slaveName 从字段名
* @param pairList 键值对集合key 对应主字段value 对应从字段
*/
@Insert("insert into ${tableName} (${masterName}, ${slaveName}) values (#{masterValue}, #{slaveValue})")
void insertIntoTable(@Param("tableName") String tableName,
@Param("masterName") String masterName,
@Param("masterValue") String masterValue,
@Param("slaveName") String slaveName,
@Param("slaveValue") String slaveValue);
/**
* 批量插入中间表数据
*
* @param tableName 中间表名
* @param masterName 主表主键名
* @param slaveName 从表主键名
* @param values 每个元素是 {masterValue, slaveValue}
*/
@Insert({
"<script>",
"INSERT INTO ${tableName} (${masterName}, ${slaveName})",
"VALUES",
"<foreach collection='values' item='item' separator=','>",
" (#{item.masterValue}, #{item.slaveValue})",
"</foreach>",
"</script>"
})
@Insert("""
<script>
INSERT INTO ${tableName} (${masterName}, ${slaveName}) VALUES
<foreach collection='pairList' item='item' separator=','>
(#{item.sourceId}, #{item.targetId})
</foreach>
</script>
""")
void insertIntoTableBatch(@Param("tableName") String tableName,
@Param("masterName") String masterName,
@Param("slaveName") String slaveName,
@Param("values") List<Map<String, String>> values);
@Param("pairList") List<RelationRow> pairList);
/**
* 删除中间表数据
* 根据主字段值删除记录
*
* @param tableName 中间表名
* @param masterName 主表主键名
* @param id 主表主键值
* @param tableName 目标表名
* @param masterName 主字段名条件字段
* @param masterValue 主字段值等值删除
*/
@Delete("delete from ${tableName} where ${masterName} = #{id}")
@Delete("delete from ${tableName} where ${masterName} = #{masterValue}")
void deleteFromTable(@Param("tableName") String tableName,
@Param("masterName") String masterName,
@Param("id") String id);
@Param("masterValue") String masterValue);
/**
* 清空中间表
* 清空指定表数据TRUNCATE
*
* @param tableName 中间表名
* @param tableName 目标表名
*/
@Delete("TRUNCATE TABLE ${tableName} CASCADE")
void truncateTable(@Param("tableName") String tableName);