这是一个非常高级且需要谨慎使用的配置。这里的 resultMap="map" 和 parameterType 扮演着完全不同的角色,理解它们的区别至关重要。
核心区别总结
| 特性 | resultMap="map" |
parameterType |
|---|---|---|
| 角色 | 输出(Output) | 输入(Input) |
| 作用阶段 | SQL 执行之后 | SQL 执行之前 |
| 目的 | 指定如何封装查询结果 | 指定传入参数的类型和如何替换SQL中的占位符 |
| 在本例中的含义 | 告诉 MyBatis 将结果集的每一行都封装成一个 Map<String, Object> |
(本例中未显式指定,但参数是存在的) |
详细解释
1. resultMap="map" - 处理查询结果
-
作用:这定义了 MyBatis 应该如何处理从数据库返回的结果集(ResultSet)。
-
map的含义:这里的map是 MyBatis 的一个内置别名,它对应的是java.util.Map<String, Object>。这指示 MyBatis:“不要将结果映射到某个具体的实体类(如
Manage),而是将每一行数据都转换成一个 Map。Map 的 key 是数据库的列名(或别名),Map 的 value 是对应列的值。” -
结果示例:假设你的 SQL 是
SELECT id, user_name FROM manage,查询返回一条记录(1, 'admin')。MyBatis 会为你返回一个这样的Map:{ "id" : 1, "user_name" : "admin" }如果你的查询返回多行,结果就会是一个包含多个 Map 的 List:
List<Map<String, Object>>。 -
为什么在这里使用? 因为方法名是
listBySqlReturnMap,其目的就是执行任意动态 SQL 并返回灵活的 Map 结构,而不是固定的 JavaBean。这提供了极大的灵活性,但牺牲了类型安全。
2. parameterType - 处理传入参数(本例中未显式使用)
-
作用:这定义了传入 SQL 语句的参数的类型。它告诉 MyBatis:“我传给这个方法的参数是什么类型的对象?”,这样 MyBatis 才知道如何从这个参数中获取值去替换 SQL 中的占位符(
#{}或${})。 -
在本例中:你注意到这个
<select>标签没有写parameterType属性。但这不代表它没有参数!-
它的 SQL 语句是
${sql}。这是一个${}占位符,它需要进行变量替换。 -
根据 MyBatis 规则,当方法只有一个参数时,在 XML 中可以直接使用这个参数。所以这里会使用传入的
sql字符串参数来直接替换${sql}。
-
-
假设的 Java 接口:
// 参数是一个 String 类型的 SQL 语句 List<Map<String, Object>> listBySqlReturnMap(String sql);虽然 XML 里没写
parameterType,但 MyBatis 知道参数类型是String。
极其重要的安全警告:${} vs #{}
这是理解这段代码的关键,也是它非常危险的原因:
-
${sql}:-
这叫做 “字符串替换” 或 “不转义插值”。
-
MyBatis 会直接把你传入的
sql字符串原封不动地拼接到最终的 SQL 语句中。 -
危险! 这构成了 SQL 注入攻击的极大风险。如果调用方传入
"1; DROP TABLE manage; --",生成的 SQL 将是select ... 1; DROP TABLE manage; --,会导致灾难性后果。
-
-
#{}:-
这叫做 “参数占位符” 或 “预编译插值”。
-
MyBatis 会将其转换为
?,然后使用PreparedStatement来安全地设置参数。 -
安全! 能有效防止 SQL 注入。但它不能用于替换 SQL 语句本身的部分(如表名、列名、WHERE 关键字等),只能用于替换值。
-
正因为这里使用了 ${sql},所以这个方法可以执行任何传入的 SQL 语句,但同时带来了巨大的安全风险。
总结
| 概念 | 在本例中的作用 | 说明 |
|---|---|---|
resultMap="map" |
定义输出格式 | 要求 MyBatis 将结果集转换为 List<Map<String, Object>>,提供灵活性。 |
parameterType |
(隐式)定义输入类型 | 虽然未写明,但方法参数是 String 类型,用于提供要执行的 SQL 语句。 |
${sql} |
危险的 SQL 拼接 | 将传入的字符串直接拼接到 SQL 中,极其危险,应避免在可控环境外使用。 |
结论: 这段代码是一个高度灵活但极其危险的“万能”SQL执行器。它通常只用于系统内部、高度信任的环境(如后台管理系统工具、数据分析模块),或者必须执行动态复杂 SQL 的特殊场景,绝不应该直接暴露给用户输入。在生产环境中使用此类代码必须进行严格的安全审计和权限控制。
浙公网安备 33010602011771号