Mybatis高级结果映射ResulMap与ResultType,collection与association

本文详细介绍了MyBatis中的高级映射特性,包括ResultMap、ResultType、Association、Collection、Constructor、Discriminator等元素的使用方法。ResultMap用于解决复杂的数据库映射问题,如一对一、一对多关系,通过id、result、association、collection元素进行映射。Association处理一对一关系,Collection处理一对多关系,Constructor则通过构造器注入结果。Discriminator元素用于处理根据某个字段值决定使用哪个ResultMap的情况。此外,还介绍了MyBatis的缓存机制和使用策略。
摘要由CSDN通过智能技术生成

高级结果映射

MyBatis的创建基于这样一个思想:数据库并不是您想怎样就怎样的。虽然我们希望所有的数据库遵守第三范式或BCNF(修正的第三范式),但它们不是。如果有一个数据库能够完美映射到所有应用程序,也将是非常棒的,但也没有。结果集映射就是MyBatis为解决这些问题而提供的解决方案。例如,我们如何映射下面这条语句?

[sql]  view plain  copy
  1. <select id="selectBlogDetails" parameterType="int" resultMap="detailedBlogResultMap">  
  2. select  
  3. B.id as blog_id,  
  4. B.title as blog_title,  
  5. B.author_id as blog_author_id,  
  6. A.id as author_id,  
  7. A.username as author_username,  
  8. A.password as author_password,  
  9. A.email as author_email,  
  10. A.bio as author_bio,  
  11. A.favourite_section as author_favourite_section,  
  12. P.id as post_id,  
  13. P.blog_id as post_blog_id,  
  14. P.author_id as post_author_id,  
  15. P.created_on as post_created_on,  
  16. P.section as post_section,  
  17. P.subject as post_subject,  
  18. P.draft as draft,  
  19. P.body as post_body,  
  20. C.id as comment_id,  
  21. C.post_id as comment_post_id,  
  22. C.name as comment_name,  
  23. C.comment as comment_text,  
  24. T.id as tag_id,  
  25. T.name as tag_name  
  26. from Blog B  
  27. left outer join Author A on B.author_id = A.id  
  28. left outer join Post P on B.id = P.blog_id  
  29. left outer join Comment C on P.id = C.post_id  
  30. left outer join Post_Tag PT on PT.post_id = P.id  
  31. left outer join Tag T on PT.tag_id = T.id  
  32. where B.id = #{id}  
  33. </select>  

您可能想要把它映射到一个智能的对象模型,包括由一个作者写的一个博客,有许多文章( Post ,帖子 ),每个文章由0个或者多个评论和标签。下面是一个复杂ResultMap 的完整例子(假定作者、博客、文章、评论和标签都是别名)。仔细看看这个例子,但是不用太担心,我们会一步步地来分析,一眼看上去可能让人沮丧,但是实际上非常简单的

[html]  view plain  copy
  1. <resultMap id="detailedBlogResultMap" type="Blog">  
  2. <constructor>  
  3. <idArg column="blog_id" javaType="int"/>  
  4. </constructor>  
  5. <result property="title" column="blog_title"/>  
  6. <association property="author" column="blog_author_id" javaType=" Author">  
  7. <id property="id" column="author_id"/>  
  8. <result property="username" column="author_username"/>  
  9. <result property="password" column="author_password"/>  
  10. <result property="email" column="author_email"/>  
  11. <result property="bio" column="author_bio"/>  
  12. <result property="favouriteSection" column="author_favourite_section"/>  
  13. </association>  
  14. <collection property="posts" ofType="Post">  
  15. <id property="id" column="post_id"/>  
  16. <result property="subject" column="post_subject"/>  
  17. <association property="author" column="post_author_id" javaType="Author"/>  
  18. <collection property="comments" column="post_id" ofType=" Comment">  
  19. <id property="id" column="comment_id"/>  
  20. </collection>  
  21. <collection property="tags" column="post_id" ofType=" Tag" >  
  22. <id property="id" column="tag_id"/>  
  23. </collection>  
  24. <discriminator javaType="int" column="draft">  
  25. <case value="1" resultType="DraftPost"/>  
  26. </discriminator>  
  27. </collection>  
  28. </resultMap>  

这个resultMap 的元素的子元素比较多,讨论起来比较宽泛。下面我们从概念上概览一下这个resultMap的元素。

 

resultMap

·constructor实例化的时候通过构造器将结果集注入到类中

oidArg– ID 参数; 将结果集标记为ID,以方便全局调用

oarg注入构造器的结果集

·id结果集ID,将结果集标记为ID,以方便全局调用

·result注入一个字段或者javabean属性的结果

·association复杂类型联合;许多查询结果合成这个类型

o嵌套结果映射– associations能引用自身,或者从其它地方引用

·collection复杂类型集合

o嵌套结果映射– collections能引用自身,或者从其它地方引用

·discriminator使用一个结果值以决定使用哪个resultMap

ocase基于不同值的结果映射

§嵌套结果映射–case也能引用它自身, 所以也能包含这些同样的元素。它也可以从外部引用resultMap

 

è最佳实践:逐步地生成resultMap,单元测试对此非常有帮助。如果您尝试一下子就生成像上面这样巨大的resultMap,可能会出错,并且工作起来非常吃力。从简单地开始,再一步步地扩展,并且进行单元测试。使用框架开发有一个缺点,它们有时像是一个黑合。为了确保达到您所预想的行为,最好的方式就是进行单元测试。这对提交bugs 也非常有用。

 

下一节,我们一步步地查看这些细节。

id, result元素

<id property="id" column="post_id"/>

<result property="subject" column="post_subject"/>

 

这是最基本的结果集映射。id 和result 将列映射到属性或简单的数据类型字段(String, int, double, Date)

这两者唯一不同的是,在比较对象实例时id 作为结果集的标识属性。这有助于提高总体性能,特别是应用缓存和嵌套结果映射的时候。

 

Idresult属性如下:

 

Attribute

Description

property

映射数据库列的字段或属性。如果JavaBean 的属性与给定的名称匹配,就会使用匹配的名字。否则,MyBatis 将搜索给定名称的字段。两种情况下您都可以使用逗点的属性形式。比如,您可以映射到“username”,也可以映射到“address.street.number”

column

数据库的列名或者列标签别名。与传递给resultSet.getString(columnName)的参数名称相同。

javaType

完整java类名或别名(参考上面的内置别名列表)。如果映射到一个JavaBean,那MyBatis 通常会自行检测到。然而,如果映射到一个HashMap,那您应该明确指定javaType 来确保所需行为。

jdbcType

这张表下面支持的JDBC类型列表列出的JDBC类型。这个属性只在insertupdatedelete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果您直接编写JDBC代码,在允许为空值的情况下需要指定这个类型。

typeHandler

我们已经在文档中讨论过默认类型处理器。使用这个属性可以重写默认类型处理器。它的值可以是一个TypeHandler实现的完整类名,也可以是一个类型别名。


支持的JDBC类型

MyBatis支持如下的JDBC类型:

BIT

FLOAT

CHAR

TIMESTAMP

OTHER

UNDEFINED

TINYINT

REAL

VARCHAR

BINARY

BLOB

NVARCHAR

SMALLINT

DOUBLE

LONGVARCHAR

VARBINARY

CLOB

NCHAR

INTEGER

NUMERIC

DATE

LONGVARBINARY

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值