ResultMap之复杂结果映射
快下班了,多么希望能来杯
啊。
昨天下班回去后,看了13集的东北往事,然后又开始了mybatis的探秘。之前也学习过Hibernate,经过这几日对mybatis的了解,感觉它的mapper的确很简洁很容易掌握,比hibernate的学习周期会短。
resultMap是否有必要配置,这要取决于你要映射的结果的复杂程度。
如果是column名称与类型与属性名称与类型能对应上,那么mybatis会自动的寻找到它,也就没有必要配置了。
但是对于复杂类型来说,resultMap是必须配置的,以帮助mybatis完成结果与类对象的映射。
简单内容学习完后,在小test中我也在想‘1对1’、‘1对多’的时候如何mapper呢?怀着这种疑问,开始学习mybatis的高级一些的配置。好了,下面列举一下ResultMap的高级使用,或说非常神奇的地方。官方文档称——“这是个神奇的‘网站’”,呵呵,玩笑而已,不过的却是非常XX。
首先列举一下resultMap中标签:
*constructor – 类在实例化时,用来注入结果到构造方法中
? **idArg – ID 参数;标记结果作为 ID 可以帮助提高整体效能
? **arg – 注入到构造方法的一个普通结果
*id – 一个ID 结果;标记结果作为ID 可以帮助提高整体效能
*result – 注入到字段或JavaBean 属性的普通结果
*association – 一个复杂的类型关联;许多结果将包成这种类型
? **嵌入结果映射 – 结果映射自身的关联,或者参考一个
*collection – 复杂类型的集
? **嵌入结果映射 – 结果映射自身的集,或者参考一个
*iscriminator – 使用结果值来决定使用哪个结果映射
? **case – 基于某些值的结果映射
? ***嵌入结果映射 – 这种情形结果也映射它本身,因此可以包含很多相
同的元素,或者它可以参照一个外部的结果映射。
下面讲一下理解后自我的了解:
constructor对应的是构造方法,可以为构造方法提供参数。需要强调——配置的参数的顺序与类型必须与类的构造方法的参数顺序与类型严格匹配。
idArg是constructor的参数标签,并且这个标签传递的应该是能唯一标识这个类实例的。可以理解为主键。
arg同样也是constructor的参数标签,传递非主键属性的数据。(能有若干个arg)。
id将指定列的数据映射到能唯一标识对应的属性上,可以理解为主键。若constructor中传递了idArg,所以这个id就可以省略了。
result用于映射列与普通类型的属性,若column名称和属性名称匹配的话,这个可以省去的,可以有若干个result。
association解决“有一个”的映射。例如类A的对象中有一个类B对象时,将结果映射到B对象中,利用这个标签就能迎刃而解了。
可以用“关联查询”和“关联结果”两个方式实现。我认为最佳方式是“关联结果”。
下面介绍这两种方式:
1、“关联查询”
例如:
<resultMap id=”blogResult” type=”Blog”> <association property="author" column="blog_author_id" javaType="Author" select=”selectAuthor”/> </resultMap> <select id=”selectBlog” parameterType=”int” resultMap=”blogResult”> SELECT * FROM BLOG WHERE ID = #{id} </select> <select id=”selectAuthor” parameterType=”int” resultType="Author"> SELECT * FROM AUTHOR WHERE ID = #{id} </select> <select id="selectBlog" parameterType="int" resultMap="blogResult"> select B.id as blog_id, B.title as blog_title, B.author_id as blog_author_id, A.id as author_id, A.username as author_username, A.password as author_password, A.email as author_email, A.bio as author_bio From Blog B left outer join Author A on B.author_id = A.id where B.id = #{id} </select> <resultMap id="blogResult" type="Blog"> <id property=”blog_id” column="id" /> <result property="title" column="blog_title"/> <association property="author" column="blog_author_id" javaType="Author" resultMap=”authorResult”/> </resultMap> <resultMap id="authorResult" type="Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> </resultMap>
<association property="author" column="blog_author_id" javaType="Author"><id property="id" column="author_id"/> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> <association/>
<select id="selectBlog" parameterType="int" resultMap="blogResult"> select B.id as blog_id, B.title as blog_title, B.author_id as blog_author_id, P.id as post_id, P.subject as post_subject, P.body as post_body, from Blog B left outer join Post P on B.id = P.blog_id where B.id = #{id} </select><resultMap id="blogResult" type="Blog"> <id property=”id” column="blog_id" /> <result property="title" column="blog_title"/> <collection property="posts" ofType="Post"> <id property="id" column="post_id"/> <result property="subject" column="post_subject"/> <result property="body" column="post_body"/> </collection> </resultMap>
<resultMap id=”blogResult” type=”Blog”> <collection property="posts" javaType=”ArrayList” column="blog_id" ofType="Post" select=”selectPostsForBlog”/> </resultMap> <select id=”selectBlog” parameterType=”int” resultMap=”blogResult”> SELECT * FROM BLOG WHERE ID = #{id} </select> <select id=”selectPostsForBlog” parameterType=”int” resultType="Author"> SELECT * FROM POST WHERE BLOG_ID = #{id} </select>