ibatis返回List<String>

本文介绍如何使用MyBatis进行单字段列表查询,并提供了一种有效的解决方案。通过调整resultClass属性并结合使用queryForList()方法,可以实现从数据库中获取电话号码等单一类型字段的列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:返回电话号码列表,之前查询多个字段时用Map作为返回类型,现在单个字段列表用List。

最开始的写法:

<select id="selectCellListByShopId" resultClass="List" parameterClass="java.lang.Long">
select P.TEL_PHONE
  from SHOP_PHONE P
  WHERE P.SHOP_ID =#shopId:BIGINT# 
  and P.IS_DEL = '0' and P.IS_ACTIVE = '1'
</select> 

这样查到的结果是[]列表,后来在老外的一篇文章上找到的解决方案,地址如下:

http://ibatis.10938.n7.nabble.com/return-simple-String-or-List-lt-String-gt-td17133.html

其中重点如下:

Tomas, 

I am assuming that you have not read the developers guide and I just 
giving things a go.  You need to read the guide completely. 

In this case Guy was saying that if your query only returns a string 
then set the resultType to String.  Then use the ibatis queryForList() 
to compile your results into a List<String>. 


Nathan 

按照这个方案修改后的代码如下:

<select id="selectCellListByShopId" resultClass="java.lang.String" parameterClass="java.lang.Long">
select P.TEL_PHONE
  from SHOP_PHONE P
  WHERE P.SHOP_ID =#shopId:BIGINT# 
  and P.IS_DEL = '0' and P.IS_ACTIVE = '1'
</select>


Dao层通过queryForList()方法查询出来即可。


小结:遇到这种问题的常用解决方案

        1.查询ibatis的官方文档.

        2.Google 关键字ibatis resultClass.




使用<resultMap id="eqMapVo" type="EquipmentVo"> <result property="eqId" column="eq_id"/> <result property="companyId" column="company_id"/> <result property="itemName" column="item_name"/> <result property="eqName" column="eq_name"/> <result property="serialNumber" column="serial_number"/> <collection property="maps" javaType="Map"> <result column="mm" javaType="string" property="mm"/> <result column="yy" javaType="string" property="yy"/> <result column="week" javaType="string" property="week"/> <result column="dd" javaType="string" property="dd"/> <result column="hh" javaType="string" property="hh"/> <result column="minit" javaType="string" property="minit"/> <result column="eqName" javaType="string" property="eqName"/> <result column="itemName" javaType="string" property="itemName"/> <result column="rm" javaType="bigDecimal" property="rm"/> </collection> </resultMap>映射public class EquipmentVo extends RegionalEquipment { private List<EquipmentDataVo> equipmentDataVoList; private List<Map> maps; public List<Map> getMaps() { return maps; } public void setMaps(List<Map> maps) { this.maps = maps; } public List<EquipmentDataVo> getEquipmentDataVoList() { return equipmentDataVoList; } public void setEquipmentDataVoList(List<EquipmentDataVo> equipmentDataVoList) { this.equipmentDataVoList = equipmentDataVoList; } },抛出org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Could not set property 'maps' of 'class com.hapstar.regional.domain.vo.EquipmentVo' with value '{hh=2023-05-05 16, eqName=RM/7199, itemName=测试项目, rm=1.46}' Cause: java.lang.IllegalArgumentException: argument type mismatch异常,如何处理
06-03
<think>好的,我现在需要回答用户关于Java实体类中的List<String>类型对应JDBC类型的问题。首先,我得回忆一下JDBC的类型和Java类型之间的映射关系。用户之前问过MySQL的SET类型在Java中的映射,现在转向List<String>和JDBC类型的对应,可能需要更基础的JDBC知识。 首先,JDBC中的类型是通过java.sql.Types来定义的。常见的比如VARCHAR对应字符串,INTEGER对应整数等。但List<String>并不是一个原生的JDBC类型,所以用户可能是在问如何在JDBC中处理这种集合类型,比如在PreparedStatement中设置参数或者从ResultSet中获取结果时如何处理。 接下来,我需要考虑不同的场景。比如,用户可能在用MyBatis这样的框架,其中jdbcType属性用于指定数据库类型。这时候,List<String>可能被映射为不同的方式,比如数组或者通过类型处理器转换。或者用户可能是在问如何将List<String>存储到数据库的某个字段中,例如使用VARCHAR存储逗号分隔的字符串,或者使用更复杂的结构如JSON。 然后,我需要思考可能的解决方案。如果直接使用JDBC,处理List<String>可能需要将其转换为字符串(如用逗号分隔)并存储为VARCHAR,或者在数据库中使用数组类型(如PostgreSQL的数组,但MySQL不支持)。这时候对应的JDBC类型可能是Types.VARCHAR或Types.ARRAY,但ARRAY并不是所有数据库都支持。 另外,如果是MyBatis框架,可能需要使用类型处理器(TypeHandler)来处理List到数据库类型的转换。例如,在MyBatis中,可以自定义一个TypeHandler将List<String>转换为字符串存储,或者使用已有的处理器如ArrayTypeHandler,但同样需要考虑数据库的支持情况。 还要注意不同数据库的差异。比如,Oracle有VARRAY或嵌套表,而MySQL没有原生的数组类型,通常用VARCHAR或JSON格式来存储列表数据。因此,对应的jdbcType可能根据数据库的不同而不同,但大多数情况下可能使用VARCHAR或者通过自定义类型处理。 总结起来,用户可能需要知道在JDBC中如何处理List<String>类型,尤其是在使用ORM框架时如何指定jdbcType。可能的答案是使用VARCHAR并手动转换,或者使用特定数据库支持的数组类型(如PostgreSQL的ARRAY),但需要注意兼容性。此外,自定义类型处理器也是一个常见做法,特别是在MyBatis等框架中。</think>在 Java 实体类中,`List<String>` 类型与 JDBC 类型的对应关系需要结合具体场景处理,因为 **JDBC 规范中并没有直接映射集合类型的原生类型**。以下是常见解决方案: --- ### 1️⃣ **场景一:存储为字符串(逗号分隔)** **JDBC Type**:`Types.VARCHAR` **实现方式**:将集合转换为字符串存储(需手动处理分隔符) ```java // 实体类 public class User { private List<String> tags; // 例如 ["java", "mysql"] } // MyBatis 类型处理器示例(部分代码) public class StringListTypeHandler implements TypeHandler<List<String>> { @Override public void setParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) { ps.setString(i, String.join(",", parameter)); // 存入 VARCHAR } @Override public List<String> getResult(ResultSet rs, String columnName) { return Arrays.asList(rs.getString(columnName).split(",")); } } ``` --- ### 2️⃣ **场景二:使用数据库数组类型(仅限支持数组的数据库)** **JDBC Type**:`Types.ARRAY` **适用数据库**:PostgreSQL、Oracle 等支持数组的数据库 **示例**: ```sql -- PostgreSQL 表定义 CREATE TABLE users ( tags TEXT[] ); ``` ```java // MyBatis 配置(使用 PG 数组类型) @Insert("INSERT INTO users(tags) VALUES(#{tags, typeHandler=org.apache.ibatis.type.ArrayTypeHandler})") void insertUser(User user); ``` --- ### 3️⃣ **场景三:存储为 JSON 格式** **JDBC Type**:`Types.VARCHAR` 或 `Types.CLOB` **实现方式**:通过 JSON 序列化工具(如 Jackson/Gson)转换 ```java // 实体类 public class User { private List<String> tags; } // MyBatis 类型处理器示例(部分代码) public class JsonListTypeHandler implements TypeHandler<List<String>> { private static final ObjectMapper mapper = new ObjectMapper(); @Override public void setParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) { ps.setString(i, mapper.writeValueAsString(parameter)); // 存入 JSON } @Override public List<String> getResult(ResultSet rs, String columnName) { return mapper.readValue(rs.getString(columnName), new TypeReference<List<String>>() {}); } } ``` --- ### 4️⃣ **场景四:关联表存储(关系型数据库规范做法)** **JDBC Type**:**无需直接映射**,通过关联表实现一对多关系 **表结构**: ```sql CREATE TABLE users (id INT PRIMARY KEY); CREATE TABLE user_tags ( user_id INT, tag VARCHAR(50), FOREIGN KEY (user_id) REFERENCES users(id) ); ``` ```java // 实体类 public class User { private Integer id; private List<String> tags; // 通过 SQL JOIN 查询映射 } ``` --- ### 📌 **总结建议** | 场景 | JDBC Type | 特点 | |--------------------------|-------------------|----------------------------------------------------------------------| | 简单字符串存储 | `Types.VARCHAR` | 易实现,但需处理分隔符和长度限制 | | 支持数组的数据库 | `Types.ARRAY` | 直接映射数据库数组类型,但数据库兼容性差 | | 结构化存储 | `Types.VARCHAR` | 用 JSON 保持数据结构,适合复杂场景 | | 规范化设计(推荐) | **无需映射** | 通过关联表实现,符合数据库范式,但需要额外 JOIN 查询 | --- ### ⚠️ **注意事项** 1. **MySQL 不支持原生数组类型**,优先选择字符串或 JSON 格式 2. 使用 `Types.ARRAY` 时需调用 `PreparedStatement#setArray()` 3. 在 MyBatis 中需通过 `@MappedJdbcTypes` 和 `@MappedTypes` 注册类型处理器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值