1. 程式人生 > >Mybatis 錯誤筆記

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 語句)中出現< 和 >而報出的錯誤。

  1. 用轉義字元把">“和”<"替換掉。

    &lt;     	<   	小於號   
    &gt;     	>   	大於號   
    
    <if test="time!= null ">
        AND  lastLogin &lt;= #{time,jdbcType=DATE}>
    </if>
    
  2. 使用<![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,方法名稱等能否對應上。

  1. 檢查配置檔案中package名稱是否和Mapper介面的全限定型別一致
  2. 檢查對映檔案中mapper的namespace屬性是否和Mapper介面的全限定類名一致
  3. 檢查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 (子查詢語句 | 表名)。比較推薦這樣方式。