mybatis 映射 List<String>

本文介绍了一个使用MyBatis框架进行集合属性映射的例子。通过定义实体类User及对应的XML配置文件,展示了如何将数据库查询结果映射到Java对象的集合属性中。具体实现了对User对象中的otherName字段的映射。
实体类
 
public class User {
    private String id;
    private String name;
    private List<String> otherName;
 

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getOtherName() {
        return otherName;
    }

    public void setOtherName(List<String> loginName) {
        this.otherName= otherName;
    }
}
  

resultMap //collectiom只能在最好一条


  <resultMap id="UserMap" type="com.User" extends="BaseResultMap">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    <result column="id" jdbcType="CHAR" property="id"/>
    <collection property="otherName" ofType="java.lang.String" >
      <result column="oName"/>
    </collection>
  </resultMap>



记录如下

      id   name oName

        1   aa  b

       1    aa  c

       2    bb  d



<think> 我们正在讨论MyBatis如何返回List<String>类型的结果。根据引用[1]和引用[2],有两种主要方法: 1. 使用resultMap,并在collection中指定ofType="string"(适用于对象中包含List<String>属性的情况) 2. 直接设置resultType="String"(适用于整个查询结果都是字符串列表的情况) 另外,引用[3]展示了在动态SQL中循环List<String>作为查询条件的例子。 下面具体展开: </think> ### MyBatis 返回 `List<String>` 的实现方法 在 MyBatis 中返回纯字符串集合 `List<String>` 有两种核心场景,每种场景对应不同的实现方案: --- #### 一、**直接返回 `List<String>`(单列查询)** 当 SQL 查询结果仅包含单列字符串时(如 `SELECT name FROM users`): 1. **XML 配置法** 设置 `resultType="String"`(注意不是 `java.util.List`): ```xml <select id="getAllNames" resultType="String"> SELECT user_name FROM users <!-- 返回单列字符串 --> </select> ``` > **原理**:MyBatis 自动将每行结果的单列值封装为 `String`,再组合成 `List<String>`[^2]。 2. **注解配置法** 在接口方法中使用 `@ResultType` 注解: ```java @Select("SELECT DISTINCT department FROM employees") @ResultType(String.class) List<String> getAllDepartments(); ``` --- #### 二、**对象中包含 `List<String>` 属性** 当主对象有一个 `List<String>` 字段时(如 `User` 对象含 `List<String> tags`): 1. **`ResultMap` 配置法** 使用 `<collection>` 标签并指定 `ofType="string"`: ```xml <resultMap id="UserMap" type="User"> <id property="id" column="id"/> <result property="name" column="name"/> <!-- 关键:将子集合声明为字符串列表 --> <collection property="tags" ofType="string"> <result column="tag_name"/> <!-- 列值直接映射为String --> </collection> </resultMap> <select id="getUserWithTags" resultMap="UserMap"> SELECT u.id, u.name, t.tag_name FROM user u LEFT JOIN user_tags t ON u.id = t.user_id </select> ``` > **注意**:`<collection>` 的 `property` 需与 Java 对象的 `List<String>` 字段名一致[^1]。 2. **动态 SQL 关联查询** 若需条件过滤,结合 `<foreach>` 处理: ```xml <select id="getUsersByTags" resultMap="UserMap"> SELECT u.id, u.name, t.tag_name FROM user u LEFT JOIN user_tags t ON u.id = t.user_id WHERE t.tag_name IN <!-- 动态传入字符串列表参数 --> <foreach item="tag" collection="tagList" open="(" separator="," close=")"> #{tag} </foreach> </select> ``` --- ### ✅ 关键注意事项 1. **避免常见错误** - 错误写法:`resultType="java.util.List"`(会导致映射失败) - 正确写法:直接声明元素类型(`resultType="String"` 或 `ofType="string"`)[^2][^5]。 2. **性能优化** - 单列查询时优先使用 `resultType="String"`,减少解析开销 - 关联查询时确保 SQL 使用 `DISTINCT` 或 `GROUP BY` 避免重复数据[^4][^5]。 3. **嵌套对象处理** 若 `List<String>` 是嵌套对象的属性,需通过 `JOIN` 查询 + 两层 `ResultMap` 实现(需自定义结果集处理)。 --- ### 完整示例 **场景:** 查询所有用户的邮箱列表(纯 `List<String>`) ```java // Mapper 接口 public interface UserMapper { List<String> getAllEmails(); } ``` ```xml <!-- XML 配置 --> <select id="getAllEmails" resultType="String"> SELECT email FROM users WHERE email IS NOT NULL </select> ``` 执行结果示例:`["alice@example.com", "bob@example.com", ...]` --- ### 常见问题排查 | 现象 | 原因 | 解决方案 | |-----------------------|-------------------------------|------------------------------| | 返回 `List<null>` | 数据库列名与映射字段不一致 | 检查 SQL 列别名与 `ResultMap` | | 报错 `TypeException` | 遗漏 `ofType="string"` 声明 | 补充 `<collection>` 的类型声明 | | 数据重复 | 关联查询未去重 | SQL 中添加 `DISTINCT` |
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值