mybatis新手入門常見問題集(持續更新),mybatis新手入門
一、參數為集合
Q:parameterType指的的類型是集合類型還是對象?
A:都可以,甚至不用在xml中指定也可以。第一,mybatis會對傳入的參數進行判斷是不是list或者array,第二,mybatis是根據ONGL運算式,即 【參數.屬性】 這樣的格式,通過反射去擷取和注入屬性值,傳入的參數為集合的時候,不管指定parameterType的那一個,上面說的兩點都能發揮功能。
Q:Parameter '__frch_item_0' not found. Available parameters are [list]
A:首先說明的是frch_item_0這個參數名的來曆,在我的xml檔案中,<foreach>是這樣定義的,
<foreach collection="list" item="item" separator="," open="(" close=")"> #{item.a}</foreach>
‘frch'代表的是在迴圈內部參數的首碼,’item‘則 標籤中指定的item的名字,後面的數字則代表迴圈中的第幾個參數
介面中的方法的定義如下:
List<User> listById( List<User> id);
這裡的item.a等同user.a,但是User類雷根本沒有a這個屬性,所以出現這個問題應該第一時間去查看 訪問的屬性名稱是否正確
Q:Parameter 'list' not found. Available parameters are [0, 1, param1, param2]
A: 首先解釋Available parameters are [0, 1, param1, param2],mybatish會將傳入的參數按照順序設定預設名字,即這裡看到的0,1,param1,param2,通過@Param註解可以修改參數名,當傳入的參數有且僅有一個的時候,可以不使用@Param註解,在定義的sql語句中,#{}裡寫的參數是隨意的!因為傳入的參數只有一個,無論在#{}命名為什麼,mybatis都是將這個唯一參數傳入,但是在使用@Param註解的情況,就必須使用註解指定的名字或者paramX(X指代順序數字),回到本題,在使用List作為唯一參數的時候,在foreach標籤使用的情況下是不會出現上述問題。
List<User> listById( List<String> id);<select id="listById" parameterType="scau.zzf.entity.User" resultType="scau.zzf.entity.User"> SELECT * FROM users WHERE id IN <foreach collection="list" item="item" separator="," open="(" close=")"> #{item} </foreach> </select>
但是在傳入的參數為多個的時候
List<User> listById( List<String> id,String username); //不使用@Param <select id="listById" parameterType="scau.zzf.entity.User" resultType="scau.zzf.entity.User"> SELECT * FROM users WHERE username=#{username} AND id IN <foreach collection="list" item="item" separator="," open="(" close=")"> #{item.id} </foreach></select>
此刻錯誤記錄檔顯示為 Parameter 'list' not found. Available parameters are [0, 1, param1, param2],這個時候我們自然就想到,在多個參數的時候必須用@Param 指定參數名,才能夠使用我們的參數規範,否則就必須依據mybatis的參數規範。
但是對於新手來說,可能還差了一步,foreach標籤中collection的選擇比較多的是list或者array,在傳入的參數只有一個的時候,這是絕對正確的,但在多個的時候,這裡的collection要依照@Param指定的名稱。
可以閱讀這篇部落格深入瞭解mybatis參數 http://blog.csdn.net/isea533/article/details/44002219,涉及的大多數是源碼,新手很可能看不懂,我這裡權當拋磚引玉。
二、模糊查詢怎麼做
新手涉及到使用mybatis做模糊查詢的使用,會首先在xml檔案裡定義sql的時候盡量拼接上%,然後碰壁,怎麼嘗試都不對,最後想到了,在傳入參數之前添加上%,結果問題迎刃而解,但是這個方式還不夠優雅,可以通過bind標籤實現該功能
<select id="findByUsername" resultType="scau.zzf.entity.User"> <bind name="pattern" value="username+'%'"></bind> SELECT * FROM users WHERE username LIKE #{pattern} </select>
三、關聯查詢引用的資料混亂
Q:一對多關聯查詢,多方只返回一條資料,但SQL書寫是正確的
A:這種情況經常是查詢返回的主鍵名字是相同的,從而導致返回結果出錯。兩張表的資料庫欄位相同,是難以避免的,需要結合使用 SQL語句別名和resultMap一起使用即可解決。
四、如何擷取插入對象後該對象的主索引值
insert成功之後,mybatis會將插入的值自動綁定到插入的對象的Id屬性中,以下代碼是能正確列印出ID值的。
<insert id="addUser" > INSERT INTO users (id,username,password,salt) VALUES (#{id},#{username},#{password},#{salt}) </insert>
iUserService.addUser(user);//插入成功 System.out.println(user.getId());//列印ID
如果使用的主鍵名不是ID,可以通過修改insert標籤中的keyProperty或者keyColumn。
五、無法觸發緩衝重新整理
簡單的來說,這種情況發生在關聯查詢的時候,但是更新的卻只是一張表,查卻查的是兩張表,所有當更新一張表的資料的時候,無法觸發重新整理查詢兩張表的快取資料,具體原理可查看 http://blog.csdn.net/isea533/article/details/44566257
總結了一下自己學習和使用過程遇到過問題,後續將在更多的實戰經驗中補充出更多,如有不足地方,歡迎在評論區指出,有更多的其他常見的錯誤情況,也請大家紛紛提出來,這裡強烈建議閱讀http://blog.csdn.net/isea533/article/category/2092001,該博主深入的講解mybatis的原理知識,更有通用Mapper和分頁外掛程式造福人類,我這裡也僅是拋磚引玉。
文章如需轉載請說明原處。