<!-- 根据参数查询--><select id="listByMap" resultMap="ResultMapManage" parameterType="map">select <include refid="Manage_field"/>from manage where 1=1<include refid="Manage_where"/></select>
整体含义
这段代码的目的是:根据一个 Map 对象中提供的键值对作为条件,动态地查询 manage
表中的记录。 查询结果会通过之前定义的 ResultMapManage
映射规则,被转换为 Manage
实体对象的集合。
代码逐层解析
1. <select>
标签
<select id="listByMap" resultMap="ResultMapManage" parameterType="map">
-
id="listByMap"
:这个 SQL 片段的唯一标识符。在对应的 Mapper 接口中,会有一个同名的方法:public interface ManageMapper {List<Manage> listByMap(Map<String, Object> map); }
-
resultMap="ResultMapManage"
:指定查询结果的映射规则。这里引用了一个名为ResultMapManage
的<resultMap>
(在你之前的代码中叫ResultMapMange
,注意拼写可能不同)。它负责将查询到的数据库字段映射到Manage
对象的属性上。 -
parameterType="map"
:这是关键所在。它指定传入参数的类型是 MyBatis 内置的map
别名,对应 Java 中的java.util.Map<String, Object>
接口(通常是HashMap
实现)。这意味着方法接收一个 Map 对象作为查询条件。
2. SQL 主体
select <include refid="Manage_field"/>from manage where 1=1
<include refid="Manage_where"/>
-
select <include refid="Manage_field"/> from manage
:查询manage
表。<include refid="Manage_field"/>
会被替换为之前定义好的字段列表(如id, userName, passWord, realName
),避免了手动书写和保证一致性。 -
where 1=1
:和删除语句中一样,这是一个“万能”的起始条件,目的是为了后面能安全地拼接AND
条件,避免语法错误。 -
<include refid="Manage_where"/>
:这是实现动态查询的核心。它引入了一个动态 SQL 片段。
3. 关键的 Manage_where
动态片段(推测内容)
虽然你没有提供 Manage_where
的具体定义,但根据 MyBatis 的常规用法,它几乎肯定包含了 <if>
标签,并且其 test
属性中的判断条件是基于 Map 的键。
一个典型的、与 parameterType="map"
配合的 Manage_where
片段会是这样:
<sql id="Manage_where"><if test="id != null">AND id = #{id}</if><if test="userName != null">AND user_name = #{userName}</if><if test="realName != null">AND real_name = #{realName}</if><!-- 可以根据需要继续添加其他字段的条件 -->
</sql>
请注意这里的关键变化:
-
当
parameterType
是实体类(如Manage
)时,test
中判断的是实体类的属性:test="userName != null"
(检查manage.getUserName()
)。 -
当
parameterType
是map
时,test
中判断的是 Map 中的 Key:test="userName != null"
(检查map.containsKey("userName") && map.get("userName") != null
)。
工作流程与示例
假设调用:
// 1. 创建一个条件 Map
Map<String, Object> conditionMap = new HashMap<>();
conditionMap.put("userName", "admin"); // 要查询用户名为 'admin' 的记录
conditionMap.put("realName", "张"); // 并且真实姓名包含 '张'// 2. 调用方法
List<Manage> manageList = manageMapper.listByMap(conditionMap);
MyBatis 的处理过程:
-
接收到参数
conditionMap
,里面有两个键值对:{"userName": "admin", "realName": "张"}
。 -
开始构建 SQL:
select id, userName, passWord, realName from manage where 1=1
-
处理
<include refid="Manage_where"/>
:-
test="id != null"
:检查conditionMap
是否有 key 为"id"
且值不为 null 的项。没有,所以忽略。 -
test="userName != null"
:检查conditionMap
是否有 key 为"userName"
且值不为 null 的项。有,值为"admin"
,所以追加AND user_name = #{userName}
。 -
test="realName != null"
:检查conditionMap
是否有 key 为"realName"
且值不为 null 的项。有,值为"张"
,所以追加AND real_name = #{realName}
。
-
-
最终生成的 SQL:
SELECT id, userName, passWord, realName FROM manage WHERE 1=1 AND user_name = ? AND real_name = ?
?
占位符会被替换为"admin"
和"张"
。 -
执行查询,并将结果集通过
ResultMapManage
映射成List<Manage>
返回。
优势与用途
-
极致的灵活性:调用者可以传递任意数量、任意组合的查询条件。你可以根据
id
查,也可以根据userName
和realName
组合查,甚至可以传入完全不同的条件(比如status
),只需在 Map 里放入相应的键值对并在Manage_where
片段中配置好对应的<if>
标签即可。 -
避免编写大量类似方法:如果没有这个通用方法,你可能需要为每一种查询组合都写一个单独的方法(如
listById
,listByUserName
,listByUserNameAndRealName
),非常冗余。 -
适用于高级查询功能:这种模式非常常用于后台管理系统的高级搜索/筛选功能,用户在前端选择不同的字段输入不同的值,后端将这些条件收集到一个 Map 里,然后直接调用这个通用的
listByMap
方法。
总结: 这段代码定义了一个通用的、基于 Map 条件动态查询的方法。它利用 MyBatis 的动态 SQL 能力,根据传入 Map 中包含的键值对,智能地生成带有相应 WHERE 条件的查询语句,是实现灵活查询的经典模式。