Mybatis 錯誤筆記
將自己遇到的一些錯誤總結一下,方便以後複習回顧。同時也希望能幫助一些人
Mybtais錯誤
1. org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException
1)There is no getter for property named ‘param’ in ‘class java.lang.String’
parameterType=“string”,並判斷了 引數是否為空
<select id="xxxxxx" parameterType ="string" resultType="int">
SELECT
COUNT(*)
FROM VIEW_USER_INFO T
<where>
<if test="param!=null">
T.CORP_ID like #{param}||'%' OR T.CORP_NAME like '%'||#{param}||'%'
</if>
</where>
</select>
使用<if>
的時候,預設情況下,mybatis預設使用OGNL尋找String的param屬性。
解決方案
- 使用 _parameter 替換引數
- 使用mybatis預設的物件名:value 替換引數
<select id="xxxxxx" parameterType="string" resultType="int">
SELECT
COUNT(*)
FROM VIEW_USER_INFO T
<where>
<if test="value!=null">
T.CORP_ID_CUS like #{param}||'%' OR T.CORP_NAME like '%'||#{param}||'%'
</ if>
</where>
</select>
2) Could not set property ‘xxxx’ of ‘class className’ with value ‘xxxx’
主要原因就是<resultMap id='xx' type="className"><column column="" property="xxx">
property屬性名沒有寫正確,這樣就無法在type中指定的類裡中找到相應的的settter方法。
2.Cause: java.sql.SQLException: ORA-00911: 無效字元 ; bad SQL grammar []; nested exception is java.sql.SQLException: ORA-00911: 無效字元
; bad SQL grammar []一般是語法錯誤,檢查一下sql是否可以在資料庫中正常執行。
但是如果在資料中可以執行的話,檢查一下對映檔案是否寫;
解決方法 : 檢查是否在sql語句的末尾有;
,在對映檔案中不需要寫;
此外,一般情況下一條語句對應一個mapper標籤。如果在一個標籤中執行多條語句時,也會報該錯誤。
這與底層的sql驅動程式有關詳情
3.在資料庫中執行sql有值,使用mabatis取出來後卻為null
- 主要的原因就是
實體類屬性和資料庫 欄位無法匹配
,mybatis找不到對應的對映關係,導致為null。 - 如果確定列名稱或者別名 和 Java實體中屬性名一致。那麼檢查一下列欄位是否使用了下劃線_。如果是那麼Java實體屬性需要修改為不帶下劃線的方式。即 USER_ID(資料庫) -> userId(javabean)
原因可能是開啟了下劃線和駝峰標記對映
<setting name="mapUnderscoreToCamelCase" value="true"/>
。
4. The content of elements must consist of well-formed character data or markup.
錯誤的大概意思是 “ 元素內容必須由格式良好的字元資料或者標記組成”,也就是說xml元素中包裹的內容有錯誤。
網上很多都在說元素本身的錯誤。比如 < p>aa </p> <122>as</122>
.。有以下依據
XML 元素必須遵循以下命名規則:
- 名稱可以含字母、數字以及其他的字元
- 名稱不能以數字或者標點符號開始
- 名稱不能以字元 “xml”(或者 XML、Xml)開始
- 名稱不能包含空格
我的問題並不是元素本身的出的問題,而是元素內容(sql 語句)中出現< 和 >
而報出的錯誤。
-
用轉義字元把">“和”<"替換掉。
< < 小於號 > > 大於號
<if test="time!= null "> AND lastLogin <= #{time,jdbcType=DATE}> </if>
-
使用
<![CDATA[ ]]>
符號進行說明,將此類符號不進行解析<if test="time!= null "> AND <![CDATA[ lastLogin <= #{time,jdbcType=DATE} ]]> </if>
5.org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
一般原因是Mapper interface和xml檔案的定義對應不上,需要檢查包名,namespace,方法名稱等能否對應上。
- 檢查配置檔案中package名稱是否和Mapper介面的全限定型別一致
- 檢查對映檔案中mapper的namespace屬性是否和Mapper介面的全限定類名一致
- 檢查Mapper介面中的方法名是否能在對映檔案找到對應的id
6. org . apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause : com.mysql.jdbc .MysqlDataTruncation: Data truncation:Incorrect datetime value :’ 10:20:30’
資料庫欄位和對映檔案中配置的欄位不匹配。資料庫欄位‘datetime’,指定的資料型別‘time’。time和datetime 不相容。
datetime可以相容timestamp和date型別。
ORACLE 錯誤
1. ORA-01013: 使用者請求取消當前的操作
這個Oracle報的錯誤,主要就是請求超時的原因。有可能是當前訪問量特別大導致的;也可能是設定的超時間太短;也可能是出現死鎖。
我遇到的問題就是死鎖,當時在Oracle視覺化工具(sql developer)中執行了更新操作但是並沒有commit
,所以導致事務一直佔用表的寫鎖。從而導致其他的寫操作一直等。 如果是這種原因,commit
提交就可以了
如果是因為請求時間太短導致的問題
#java解決方法
Statement.setQueryTimeout(0);
#修改配置檔案
$ORACLE_HOME/network/admin/sqlnet.ora .
#新增或修改成:
sqlnet.expire_time = 0
這將關閉oracle的連線狀態檢測
2. Error querying database. Cause: java.sql.SQLException: ORA-01745: 無效的主機/繫結變數名
因為需要按照指定欄位排序所以直接在原來的sql中新增Order by #{orderBy} #{order}
,結果就丟擲這個錯誤。
原因大概如下
- 結果集中的欄位含有對應的資料庫產品的關鍵字,
- 在xml檔案中的SQL語句中,兩個填充變數間沒有寫逗號。
- 一次性插入大量資料
很明顯我的錯誤的原因時第二個,佔位符的方式傳遞引數是沒有逗號將SQL語句中order by #{sortName} #{sortOrder} 改寫為<![CDATA[order by ${sortName} ${sortOrder} ]]>
問題就解決了!
我在網上查詢資料的時候其實只提供了前兩個出錯原因。在實際操作的時候因需求需要要插入1000+的資料(大部分資料已經存在其他的資料表裡面),此時就報錯了。使用的連線池是DruidDataSource,當程式還停留在解析sql語句的時候(預編譯sql還有開始賦值),Sql Connection就自動關閉了。當時也查詢了很多資料,感覺最好的解釋就是,連線池會在一定時間後回收連線。根據指示修改了配置removeAbandonedTimeout
,結果也沒有起作用。
後來的解決方案有兩種:
- 分塊插入,一次插入500條,這樣就沒有報錯了。雖然沒有報錯但是速度很慢。
- 將資料插入邏輯放在資料庫端。這樣可能減少mybatis的引數解析工作量,同時減少網路的資料傳輸量。
INSERT INTO tableName( id,name,sex,....) SELECT #{id},name,sex FROM (子查詢語句 | 表名)
。比較推薦這樣方式。