MyBatis xml 文件中 SQL 语句的小于号未转义导致报错

问题现象

在 MyBatis 的 xml 文件中添加了一个 SQL 语句

<select id="countXxx" resultType="int">
        select count(*) from t1 where count < 3
</select>

启动 Spring Boot 应用程序后报错:

Caused by: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 109; columnNumber: 104; 元素内容必须由格式正确的字符数据或标记组成。
	at org.apache.ibatis.parsing.XPathParser.createDocument(XPathParser.java:263) ~[mybatis-3.5.6.jar:3.5.6]
	at org.apache.ibatis.parsing.XPathParser.<init>(XPathParser.java:127) ~[mybatis-3.5.6.jar:3.5.6]
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.<init>(XMLMapperBuilder.java:81) ~[mybatis-3.5.6.jar:3.5.6]
	at com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean.buildSqlSessionFactory(MybatisSqlSessionFactoryBean.java:592) ~[mybatis-plus-extension-3.4.2.jar:3.4.2]
	... 72 common frames omitted
Caused by: org.xml.sax.SAXParseException: 元素内容必须由格式正确的字符数据或标记组成。
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203) ~[na:1.8.0_162]
	at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177) ~[na:1.8.0_162]
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400) ~[na:1.8.0_162]
	at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327) ~[na:1.8.0_162]

IntelliJ IDEA 也提示了:

问题原因

这个问题的原因不符合是 XML 文件的语法,因为小于号 < 和 XML 文件的标签符号是一样的,所以在 XML 文件中使用小于号时要使用转义符号 <

修改方法

<!-- 小于 -->
<select id="countXxx" resultType="int">
        select count(*) from t1 where count &lt; 3
</select>

<!-- 小于等于 -->
<select id="countXxx" resultType="int">
        select count(*) from t1 where count &lt;= 3
</select>

参考

XML 配置文件中编写 SQL 语句时,若需要使用小于号(`<`),应避免直接使用 `<` 符号,因为 XML 解析器会将其误认为是标签的开始。为确保 XML 文件格式正确,小于号应被转义为 `<` [^1]。 例如,在 MyBatis 的 Mapper XML 文件中,如果需要查询某个时间范围内的记录,并且字段类型为 `LocalDateTime`,可以编写如下 SQL 语句: ```xml <select id="findAppointmentsByDate" resultType="Appointment"> SELECT * FROM appointment WHERE created > #{created} AND created < #{created} + INTERVAL 1 DAY </select> ``` 为了避免 XML 解析错误,SQL 中的小于号应该被替换为 `<`,而大于等于号则应使用 `&gt;=` 或者保持原样(部分数据库支持)。因此,正确的写法如下: ```xml <select id="findAppointmentsByDate" resultType="Appointment"> SELECT * FROM appointment WHERE created &gt;= #{created} AND created &lt; #{created} + INTERVAL 1 DAY </select> ``` 此外,在某些情况下,也可以通过 CDATA 区域来避免转义字符的问题。CDATA 区域中的内容不会被 XML 解析器解析,可以直接使用原始字符(如 `<` 和 `>`)[^2]。示例如下: ```xml <select id="findAppointmentsByDate" resultType="Appointment"> <![CDATA[ SELECT * FROM appointment WHERE created >= #{created} AND created < #{created} + INTERVAL 1 DAY ]]> </select> ``` 对于包含动态参数的 SQL 语句,建议结合 `#{}` 占位符与适当的日期处理函数,以确保传入的 `LocalDateTime` 类型参数能够正确地参与比较操作[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值