如何在MyBatis中通过两表关联查询生成Map<Integer, String>
嘿,我来帮你解决这个MyBatis返回指定Map<Integer, String>的问题!其实有两种常用的实现方式,取决于你习惯用注解还是XML映射文件,我都给你详细说明:
方法一:使用MyBatis注解实现(无需额外DTO)
如果你偏好注解式SQL,可以通过@MapKey配合简单转换来实现,或者直接在接口里加默认方法一步到位:
import org.apache.ibatis.annotations.MapKey; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Param; import java.util.Map; import java.util.stream.Collectors; public interface YourMapper { @Select("SELECT xyz.id AS id, xyz.relation_with_user AS relationWithUser " + "FROM ABC abc LEFT JOIN XYZ xyz ON abc.id = xyz.pid " + "WHERE abc.code = #{code}") @MapKey("id") // 指定用每条记录的id作为外层Map的键 Map<Integer, Map<String, Object>> getRawRelationMap(@Param("code") String code); // 直接返回目标Map的默认方法(Java 8+支持) default Map<Integer, String> getRelationMapByCode(@Param("code") String code) { return getRawRelationMap(code).entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> (String) entry.getValue().get("relationWithUser") )); } }
方法二:使用XML映射文件实现(更直观严谨)
如果习惯用XML管理SQL,这是最直接的方式,不需要额外转换步骤:
首先在Mapper XML文件中定义查询和结果映射:
<mapper namespace="com.yourpackage.YourMapper"> <!-- 方式A:直接将列名设为key/value,利用MyBatis自动映射 --> <select id="getRelationMapByCode" parameterType="java.lang.String" resultType="java.util.Map"> SELECT xyz.id AS key, xyz.relation_with_user AS value FROM ABC abc LEFT JOIN XYZ xyz ON abc.id = xyz.pid WHERE abc.code = #{code} </select> <!-- 方式B:用resultMap精确指定类型,避免类型转换风险 --> <resultMap id="RelationResultMap" type="java.util.HashMap"> <id column="id" property="key" javaType="java.lang.Integer"/> <result column="relation_with_user" property="value" javaType="java.lang.String"/> </resultMap> <select id="getRelationMapByCodeWithResultMap" parameterType="java.lang.String" resultMap="RelationResultMap"> SELECT xyz.id, xyz.relation_with_user FROM ABC abc LEFT JOIN XYZ xyz ON abc.id = xyz.pid WHERE abc.code = #{code} </select> </mapper>
然后在对应的Mapper接口中定义方法:
import java.util.Map; public interface YourMapper { Map<Integer, String> getRelationMapByCode(String code); Map<Integer, String> getRelationMapByCodeWithResultMap(String code); }
关键注意事项
- 确保XYZ表的
id是唯一主键,否则查询结果中重复的id会覆盖之前的条目 - SQL中的
where code = #{code}建议加上表前缀abc.code,避免多表字段歧义 - 如果用注解方式的默认方法,需要确保项目使用Java 8及以上版本
这样就能轻松得到你想要的Map<Integer, String>——键是XYZ的id,值是对应的relation_with_user啦!
内容的提问来源于stack exchange,提问作者Swapnil Harde




