Mybaits基础学习(四)——强大的ResultMap

xiaoxiao2021-02-28  25

    ResultMap元素是MyBaits中最重要最强大的元素。它可以让你从90%的JDBCResultSets数据提取代码中解放出来,并在一些情形下允许你做一些JDBC不支持的事情。实际上,在对复杂语句进行联合映射的时候,它很可能可以代替数千行的同等功能的代码。ResultMap的设计思想是——简单的语句不需要明确的结果映射,而复杂一点的语句只需要描述它们的关系就行了。

以常用的javaBean对象为例:

首先,我们基于javaBean规范创建一个类:

public class User { private int id; private String username; private String hashedPassword; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getHashedPassword() { return hashedPassword; } public void setHashedPassword(String hashedPassword) { this.hashedPassword = hashedPassword; } }

该类中的属性名(id,username,hashedPassword)将会对应到select语句中的列名

这样的一个javaBean可以被映射到ResultSet

<select id="selectUsers" resultType="User"> select id, username, hashedPassword from some_table where id = #{id} </select>

注意,resultType需要完全限定名称,例如:com.xxxx.xxxx.User,这里直接写User是因为在全局配置文件中声明了类型别名

在这种情况下,Mybaits会自动创建一个ResultMap,再基于属性名来映射列到JavaBean的属性上,注意一定要有相应属性的get、set方法。如果列名和属性名没有精确匹配,可以在SELECT语句中对列使用别名来匹配标签。比如:

<select id="selectUsers" resultType="User"> select user_id as "id", user_name as "userName", hashed_password as "hashedPassword" from some_table where id = #{id} </select>

以上是隐式的使用方法,适用于一些简单的映射,可是如果我们的查询结果关联到多个表,此时是隐式的ResultMap所无法解决的,需要使用到显示的用法。

例如需要执行下面这条SQL:

<select id="selectBlogDetails" resultMap="detailedBlogResultMap"> 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, A.favourite_section as author_favourite_section, P.id as post_id, P.blog_id as post_blog_id, P.author_id as post_author_id, P.created_on as post_created_on, P.section as post_section, P.subject as post_subject, P.draft as draft, P.body as post_body, C.id as comment_id, C.post_id as comment_post_id, C.name as comment_name, C.comment as comment_text, T.id as tag_id, T.name as tag_name from Blog B left outer join Author A on B.author_id = A.id left outer join Post P on B.id = P.blog_id left outer join Comment C on P.id = C.post_id left outer join Post_Tag PT on PT.post_id = P.id left outer join Tag T on PT.tag_id = T.id where B.id = #{id} </select>

这个对象表示了一个博客,它由某位作者所写,有很多的博文,每篇博文有零或多条的评论和标签。

此时的resultMap如下所示:

<resultMap id="detailedBlogResultMap" type="Blog"> <!--用于在实例化类时,注入结果到构造方法中--> <constructor> <idArg column="blog_id" javaType="int"/> </constructor> <result property="title" column="blog_title"/> <!--一对一的关系,一个博客只有一个作者--> <association property="author" javaType="Author"> <!--一个ID结果,标记作为ID的结果可以帮助提高整体性能--> <id property="id" column="author_id"/> <!--result注入字段或JavaBean属性的普通结果--> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> <result property="favouriteSection" column="author_favourite_section"/> </association> <!--一对多的关系,一个博客有多个文章--> <collection property="posts" ofType="Post"> <id property="id" column="post_id"/> <result property="subject" column="post_subject"/> <!--一对一关系,每篇博文对应一个作者--> <association property="author" javaType="Author"/> <!--一对多关系,每篇博文有零或多条评论--> <collection property="comments" ofType="Comment"> <id property="id" column="comment_id"/> </collection> <!--一对多关系,每篇博文可以有零到多个标签--> <collection property="tags" ofType="Tag" > <id property="id" column="tag_id"/> </collection> <!--使用结果值来决定使用哪个resultMap--> <discriminator javaType="int" column="draft"> <!--一个case也是一个映射它本身的结果,因此可以包含很多相同的元素,或者它可以参照另一个resultMap--> <case value="1" resultType="DraftPost"/> </discriminator> </collection> </resultMap>

注意ResultMap中一对一的关系和一对多的关系写法,对应的是javaBean中属性为另一个bean和另一个bean的集合。

极为方便的是集合中所对应的bean仍可以直接表示一对多的关系(比如此例中博客对多篇博文,而每篇博文又对多条评论),这大大地减少了我们写代码的工作量,极为实用!

转载请注明原文地址: https://www.6miu.com/read-2626022.html

最新回复(0)