sql中<![CDATA[]]>的具體使用詳解
在這篇文章中,通過實(shí)際項(xiàng)目詳述<![CDATA[ ]]>
用法及說明。
1. 文章引言
今天在寫完根據(jù)賬戶名查詢除本身之外的用戶
接口后,在啟動項(xiàng)目時報出如下錯誤:
Caused by: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 50; columnNumber: 21; 元素內(nèi)容必須由格式正確的字符數(shù)據(jù)或標(biāo)記組成。 at org.apache.ibatis.parsing.XPathParser.createDocument(XPathParser.java:263) at org.apache.ibatis.parsing.XPathParser.<init>(XPathParser.java:127) at org.apache.ibatis.builder.xml.XMLMapperBuilder.<init>(XMLMapperBuilder.java:81) at com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean.buildSqlSessionFactory(MybatisSqlSessionFactoryBean.java:573) ... 67 common frames omitted Caused by: org.xml.sax.SAXParseException: 元素內(nèi)容必須由格式正確的字符數(shù)據(jù)或標(biāo)記組成。 at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327) at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1472) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.startOfMarkup(XMLDocumentFragmentScannerImpl.java:2635) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2732) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339) at org.apache.ibatis.parsing.XPathParser.createDocument(XPathParser.java:261) ... 70 common frames omitted
即Caused by: org.xml.sax.SAXParseException: 元素內(nèi)容必須由格式正確的字符數(shù)據(jù)或標(biāo)記組成。
正趕上最近ChatGPT
比較火,借助它來分析我的錯誤,如下圖所示:
ChatGPT
說我的XML
文件中存在格式不正確的字符或標(biāo)記導(dǎo)致的,讓我檢查XML
文件的語法是否正確。
如果說xml
文件中的格式不正確,那么,可以確定的是我在userMapper.xml
文件中,寫的sql
語句不符合xml
定義的語法。
于是,前去查看我的sql
語句,如下代碼所示:
<select id="queryByUsernameAndId" resultType="com.test.entity.po.User"> SELECT * FROM `user` <where> username = #{username} AND id <> #{userId} and deleted = 0 and user_status = 1 LIMIT 1 </where> </select>
并沒有看出我的代碼,哪里存在不合理的地方。
通過查閱網(wǎng)上的資料可知,原來在xml
中,不能存在如下的特殊字符:
大于等于符號:
>=
小于等于符號:
<=
不等于符號:
<>
大于符號:
>
小于符號:
<
且符號:
&
英文雙引號符號:
"
英文單引號符號:
'
…
如果xml
中需要寫入特殊符號,則需要添加<![CDATA[]]>
。
2. 概述<![CDATA[ ]]>
上文提到了<![CDATA[]]>
,那么,我就簡要概述它。
被<![CDATA[]]>
這個標(biāo)記,所包含的內(nèi)容將表示為純文本,比如<![CDATA[ < ]]>
表示文本內(nèi)容"<"
。
平時在mybatis
的映射文件寫sql
時,很多時候都需要寫一些特殊的字符。例如:<
字符、>
字符、>=
字符、<=
字符,但是在xml
文件中并不能直接寫上述列舉的字符,否則就會報錯。
因?yàn)樵诮馕?code>xml文件時,我們?nèi)绻麜鴮懥颂厥庾址?,在沒有特殊處理的情況下。
這些字符會被轉(zhuǎn)義,但我們并不希望它被轉(zhuǎn)義,所以我們要使用<![CDATA[ ]]>
來解決。
那為什么要這樣書寫呢?<![CDATA[ ]]>
是XML
語法,在CDATA內(nèi)部的所有內(nèi)容都會被解析器忽略。
所以,當(dāng)我們在xml
文本中包含了很多的<
、<=
和 &
字符,就像程序代碼一樣,那么最好把他們都放到CDATA
部件中。
3. 書寫規(guī)范
需要注意的問題就是,在我們的mybatis
的映射文件中,以下<where>
、<select>
等這些標(biāo)簽都不會被解析,所以,我們只把有特殊字符的語句放在<![CDATA[ ]]>
中,盡量縮小<![CDATA[ ]]>
的范圍。
因而,我在上文的sql
語句中,存在不等于符號(<>
),那么,我可以進(jìn)行如下修改:
<select id="queryByUsernameAndId" resultType="com.test.entity.po.User"> SELECT * FROM `user` <where> username = #{username} AND id <![CDATA[ <> ]]> #{userId} and deleted = 0 and user_status = 1 LIMIT 1 </where> </select>
修改完后,測試該方法,如下代碼所示:
@Resource UserMapper userMapper; @Test public void test() { User user = userMapper.queryByUsernameAndId("zhangsan", 1L); System.out.println(user); }
能夠正常執(zhí)行queryByUsernameAndId
防范,如下圖所示:
4. 文末總結(jié)
不管怎么樣,轉(zhuǎn)義前的字符也好,轉(zhuǎn)義后的字符也好,都會被xml
解析器解析。
為了方便起見,使用<![CDATA[]]>
來包含不被xml
解析器解析的內(nèi)容。
但要注意的是:
此部分不能再包含
]]>
不允許嵌套使用
]]>
這部分不能包含空格或者換行。
最后,說說<![CDATA[]]>
和xml
轉(zhuǎn)移字符的關(guān)系,它們兩個看起來是不是感覺功能重復(fù)了?
是的,它們的功能就是一樣的,只是應(yīng)用場景和需求有些不同:
<![CDATA[]]>
不能適用所有情況,轉(zhuǎn)義字符可以對于短字符串
<![CDATA[]]>
寫起來啰嗦,對于長字符串轉(zhuǎn)義字符寫起來可讀性差;<![CDATA[]]>
表示xml
解析器忽略解析,所以更快。
到此這篇關(guān)于sql中<![CDATA[ ]]>的具體使用詳解的文章就介紹到這了,更多相關(guān)sql <![CDATA[ ]]>內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQLSERVER聚集索引和主鍵(Primary Key)的誤區(qū)認(rèn)識
很多人會把Primary Key和聚集索引搞混起來,或者認(rèn)為這是同一個東西。這個概念是非常錯誤的,本文將帶你理清思路,感興趣的你可不要錯過了哈,或許本文對你有所幫助2013-02-02SQL Server 2012 創(chuàng)建定時作業(yè)(圖文并茂,教你輕松快速創(chuàng)建)
這篇文章主要介紹了SQL Server 2012 創(chuàng)建定時作業(yè),圖文并茂,教你輕松快速創(chuàng)建,需要的朋友可以參考下2015-01-01Sql Server中的系統(tǒng)視圖詳細(xì)介紹
這篇文章主要介紹了Sql Server中的系統(tǒng)視圖詳細(xì)介紹,本文講解了系統(tǒng)視圖是干什么呢、都定義在哪呢、一些使用例子等內(nèi)容,需要的朋友可以參考下2015-02-02SQLSERVER 表分區(qū)操作和設(shè)計(jì)方法
SQLSERVER 表分區(qū)操作和設(shè)計(jì)方法,需要的朋友可以參考下。2010-09-09SQLite3數(shù)據(jù)庫的介紹和使用教程(面向業(yè)務(wù)編程-數(shù)據(jù)庫)
這篇文章主要介紹了SQLite3數(shù)據(jù)庫的介紹和使用(面向業(yè)務(wù)編程-數(shù)據(jù)庫),本文從SQLite3的庫的獲取、工程管理、SQL語句介紹、C語言編程四個角度闡述了SQLite3數(shù)據(jù)庫的實(shí)際應(yīng)用,需要的朋友可以參考下2023-05-05SQL中函數(shù) replace 的參數(shù)1的數(shù)據(jù)類型ntext無效的解決方法
SQL中函數(shù) replace 的參數(shù) 1 的數(shù)據(jù)類型 ntext 無效。找了半天找到了解決辦法2010-06-06SQL Server 事務(wù),異常和游標(biāo)詳解
這篇文章主要為大家介紹了SQLServer事務(wù),異常和游標(biāo),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01