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

    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仍可以直接表示一对多的关系(比如此例中博客对多篇博文,而每篇博文又对多条评论),这大大地减少了我们写代码的工作量,极为实用!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值