轉載請注明: TheViper http://www.cnblogs.com/TheViper
autoMappingBehavior是一個容易被忽略的屬性
可以看到,默認是PARTIAL,只會自動映射沒有定義嵌套結果集映射的結果集。這句話有點拗口,意思就是映射文件中,對於resultMap標簽,如果沒有顯式定義result標簽,mybatis不會幫你把結果映射到model(pojo)上.
具體的,比如feeling(心情)和feeling_comment(評論)是一對多關系。
<resultMap id="FeelingCommentResult" type="Feeling"> <id property="feeling_id" column="feeling_id" /> <!-- <result property="content" column="content" /> --> <collection property="feelingComments" ofType="FeelingComment"> <id property="feeling_comment_id" column="feeling_comment_id" /> <!-- <result property="commentContent" column="commentContent" /> --> </collection> </resultMap> <select id="selectFeelingComment" parameterType="map" resultMap="FeelingCommentResult"> select * from feeling left outer join feeling_comment on feeling.feeling_id=feeling_comment.feeling_id where feeling.id =#{id} </select>
<resultMap>和<collection>中都沒有定義<result>,這時
List<Feeling> feeling = (List<Feeling>) sqlSessionTemplate.selectList( "user.selectFeelingComment", map); System.out.println(feeling.get(0).getContent()); System.out.println(feeling.get(0).getFeelingComments().get(0).getCommentContent());
取出content和commentcontent都是null,當然,如果只是
System.out.println(feeling);
System.out.println(feeling.get(0).getFeelingComments());
mybatis會初始化model的,因此輸出會有結果的,但里面除了id屬性有具體值外,其余都沒有,因為沒有定義<result>。去掉上面的注釋,再去取content和commentcontent就會有具體的值了。
如果select語句中有很多需要取的字段,autoMappingBehavior就派上用場了。只需要將其設置為FULL,就不用再寫那一大堆<result>了。
<setting name="autoMappingBehavior" value="FULL" />
注意,mybatis的autoMappingBehavior確實很贊,使用很方便,但是前提是開放者需要確保model和數據庫字段是一一對應的,還有相應表的字段名不要重復。
比如,feeling的內容是content,feeling_comment的內容是commentContent,這時數據庫feeling表保存內容的字段名字也應該是content,feeling_comment同理。
另外這里對feeling_comment表保存內容的字段名就不能簡單的設置為content.
至於model那邊,可以有名字相同的屬性,比如feeling類和feeling_comment類都可以有一個content屬性,但必須要用<result>。
<resultMap id="FeelingCommentResult" type="Feeling"> <id property="feeling_id" column="feeling_id" /> <collection property="feelingComments" ofType="FeelingComment"> <id property="feeling_comment_id" column="feeling_comment_id" /> <result property="content" column="commentContent" /> </collection> </resultMap>
可以看出<result>相當於sql里面的as.如果相應表間有重復的字段名,比如這里保存內容的字段名都是content,就算用<result>
<result property="commentContent" column="content" />
也是無能為力,這相當於select content as commentContent,content as content,....
mybatis不會知道是哪個表的content,美中不足!
當然,如果直接就在<select>里面把sql寫好,如select feeling.content,feeling_comment.content as commentContent,。。。上面的內容都可以不看了,沒有用到mybatis的autoMappingBehavior。
最后如果用的是懶加載,比如
<resultMap type="Feeling" id="FeelingResult"> <collection property="feelingComments" select="selectComment" column="feeling_id" ofType="FeelingComment"></collection> </resultMap> <select id="selectComment" parameterType="int" resultType="FeelingComment"> select * from feeling_comment where feeling_comment_id = #{id} </select> <select id="selectFeeling" parameterType="int" resultMap="FeelingResult"> select * from feeling where id = #{id} </select>
雖然有<resultMap>,但由於本質上是多條select語句,所以不用寫<result>仍然取得到具體值。