Exception in thread "Thread-22" org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.baomidou.mybatisplus.core.mapper.SqlRunner.SelectList ### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.baomidou.mybatisplus.core.mapper.SqlRunner.SelectList
时间: 2023-12-04 20:04:48 浏览: 353
这个异常通常表示 MyBatis-Plus 在执行 SQL 语句时出现了问题。它可能是由于以下原因之一导致的:
1. SQL 语句中的参数类型不正确或参数数量不正确。请检查你的 SQL 语句和参数是否正确。
2. 数据库连接超时或数据库连接被关闭。请检查你的数据库连接是否正常。
3. MyBatis-Plus 配置文件中的错误。请检查你的 MyBatis-Plus 配置文件是否正确。
4. MyBatis-Plus 的版本问题。请检查你使用的 MyBatis-Plus 版本是否与你的项目兼容。
你需要根据具体情况来确定问题的原因并进行相应的处理。你可以检查一下你的 SQL 语句是否正确,检查一下 MyBatis-Plus 的配置文件是否正确,或者尝试升级 MyBatis-Plus 版本。
相关问题
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: YEAR
### MyBatis 查询数据库时出现 `IllegalArgumentException` 的原因分析
当使用 MyBatis 进行 SQL 映射配置时,如果遇到 `MyBatisSystemException` 或者其内部抛出的 `PersistenceException` 和 `IllegalArgumentException`,通常意味着在执行 SQL 语句的过程中出现了参数绑定错误或者语法问题。
#### 参数占位符的选择不当引发异常
SQL 注入预防机制中的 `${}` 和 `#{}` 使用方式不同。`${}` 是直接替换变量值并嵌入到 SQL 字符串中,而 `#{}` 则会通过 JDBC 预处理语句 (PreparedStatement) 来传递参数,从而有效防止 SQL 注入攻击[^1]。如果在应该使用 `#{}` 的地方误用了 `${}`, 可能会导致生成非法的 SQL 语法结构,进而触发上述提到的各种异常情况。
例如,在动态构建表名或列名的情况下确实可以考虑采用 `${}` 方式来实现特定需求,但这增加了潜在的安全风险以及调试难度。对于常规的数据查询操作,则建议始终优先选用更安全可靠的 `#{}` 形式的参数化输入方法。
#### 解决方案
为了修复由不恰当使用的参数占位符所引起的 `IllegalArgumentException`, 应该仔细审查涉及的所有 Mapper 文件内的 SQL 片段:
- 对于所有传入数据项(如字段值),一律改用带有问号标记 (`?`) 的 `#{property}` 表达形式;
- 如果必须利用字符串插值功能来自定义某些部分(比如表名称、排序依据等),则需格外小心验证最终形成的命令文本是否合法合规,并尽可能采取额外措施加以保护,例如白名单过滤策略或是其他业务逻辑层面的校验手段。
另外值得注意的是,除了调整 XML 中的写法外,还应确保实体类属性命名与映射文件里的路径保持一致,避免因大小写敏感等因素造成匹配失败的问题发生。
```xml
<select id="getEmployeeByIdAndLastName" parameterType="map" resultType="com.example.Employee">
SELECT *
FROM tbl_employee
WHERE id = #{id}
AND last_name = #{lastName}
</select>
```
针对类似按年份分表这样的特殊场景,可以通过如下方式进行优化:
```java
@Select("SELECT * FROM ${tableName} WHERE ...") // 不推荐用于一般场合
public List<Employee> getEmployeesByYear(@Param("tableName") String tableName);
// 更好的做法是预先计算好具体的目标表格名称作为常量提供给 mapper 方法调用
```
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: Unable to convert type java.lang.Character of m to type of java.lang.CharSequence
### MyBatis 查询数据库时出现 `Unable to convert type java.lang.Character` 到 `java.lang.CharSequence` 的解决方案
当遇到 `MyBatis` 报错 `IllegalArgumentException: Unable to convert type java.lang.Character to java.lang.CharSequence` 时,通常是因为在映射过程中,数据类型的转换不符合预期。以下是可能的原因以及对应的解决方法:
#### 原因分析
1. **字段类型不匹配**
如果实体类中的字段定义为 `Character` 类型,而数据库中对应列的数据类型是字符串或其他字符序列(如 VARCHAR),那么可能会触发此错误[^3]。
2. **SQL 参数传递问题**
当 SQL 中涉及条件判断或参数绑定时,如果传入的参数是一个单个字符(`Character` 类型),但在实际执行时被当作字符串处理,则可能导致无法完成自动类型转换[^4]。
3. **Mapper 文件配置不当**
在 MyBatis 配置文件中,可能存在未正确指定 JDBC 类型的情况。例如,`jdbcType=CHARACTER` 或其他类似的误配也可能引起该问题[^1]。
---
#### 解决方案
##### 方法一:调整实体类字段类型
将实体类中的字段从 `Character` 修改为更通用的类型,比如 `String` 或者 `CharSequence`。这样可以避免由于类型差异引起的转换失败。
```java
// 将 Character 改为 String
private String fieldName; // 替代 private Character fieldName;
```
##### 方法二:显式指定 JDBC 类型
在 Mapper XML 文件中,通过 `<if>` 标签或者其他动态 SQL 条件语句明确声明参数的 JDBC 类型。例如:
```xml
<if test="fieldName != null">
AND column_name = #{fieldName, jdbcType=VARCHAR}
</if>
```
这里的关键在于确保 `jdbcType` 被正确定义为适合目标数据库列的类型。
##### 方法三:修改 SQL 表达式逻辑
检查并优化 SQL 查询语句本身是否存在潜在的风险操作。例如,在某些情况下尝试比较一个字符与空值 (`''`) 可能会导致意外行为。因此建议移除不必要的默认值判定部分:
```sql
-- 错误示例 (可能导致异常)
WHERE field LIKE CONCAT('%', #{param}, '%') OR field = ''
-- 正确做法
WHERE field LIKE CONCAT('%', #{param}, '%')
```
##### 方法四:自定义 TypeHandler
如果上述方式仍未能解决问题,可以通过实现自定义 `TypeHandler` 来强制控制如何在 Java 对象和数据库记录之间进行双向转化过程。下面展示了一个简单的例子用于演示如何创建针对特定场景下的处理器:
```java
@MappedTypes(Character.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class CharToStringTypeHandler extends BaseTypeHandler<Character> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Character parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, String.valueOf(parameter));
}
@Override
public Character getNullableResult(ResultSet rs, String columnName) throws SQLException {
String result = rs.getString(columnName);
return StringUtils.isEmpty(result)?null:result.charAt(0);
}
...
}
```
之后只需注册这个 handler 即可生效。
---
### 总结
以上四种策略可以根据具体项目需求灵活选用。优先考虑简单易行的方式如更改属性定义或者修正 sql 文本;而对于复杂业务模型则推荐引入定制化 type handlers 实现精准调控。
阅读全文
相关推荐





