简单的结果映射
一般情况下,结果映射我们可以使用默认的resultType="map",不需要去显示的指定结果类型。
<selectid="getOne"resultType="map">select*fromuserwhereid=#{id} </select>
大部分情况下都够用,但是 HashMap 并不是一个很好的领域模型。我们更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为领域模型。
比如建一个实体,然后把字段作为结果映射到实体字段里:
<selectid="getOne"resultType="com.xing.entity.UserEntity">select*fromuserwhereid=#{id} </select>
这个实体我们还可以使用类型别名标签,避免每次使用都用全类名
(类的全限定名):
<typeAliastype="com.xing.entity.UserEntity"alias="User"/><selectid="getOne"resultType="User">select*fromuserwhereid=#{id} </select>
MyBatis 会自动创建一个 ResultMap,再根据属性名来映射列到 JavaBean 的属性上。如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配。比如:
<selectid="selectUsers"resultType="User">selectuser_idas"id", user_nameas"userName", hashed_passwordas"hashedPassword"fromsome_tablewhereid=#{id} </select>
上面的例子没有一个需要显式配置 ResultMap,这就是 ResultMap 的优秀之处:你完全可以不用显式地配置它们,约定大于配置。
如果要将上面的ResultMap显示配置,这么写:
<resultMapid="userResultMap"type="User"><idproperty="id"column="user_id"/><resultproperty="username"column="user_name"/><resultproperty="password"column="hashed_password"/></resultMap>
然后在引用它的语句中设置 resultMap 属性就行了(注意我们去掉了 resultType 属性)。比如:
<selectid="selectUsers"resultMap="userResultMap">selectuser_id, user_name, hashed_passwordfromsome_tablewhereid=#{id} </select>
高级结果映射(比如多表联查)
这玩意在几年前用过后再没用过,懒得看,就是resultMap各种子元素的使用,有兴趣的可以去官网看看。
<resultMapid="detailedBlogResultMap"type="Blog"><constructor><idArgcolumn="blog_id"javaType="int"/></constructor><resultproperty="title"column="blog_title"/><associationproperty="author"javaType="Author"><idproperty="id"column="author_id"/><resultproperty="username"column="author_username"/><resultproperty="password"column="author_password"/><resultproperty="email"column="author_email"/><resultproperty="bio"column="author_bio"/><resultproperty="favouriteSection"column="author_favourite_section"/></association><collectionproperty="posts"ofType="Post"><idproperty="id"column="post_id"/><resultproperty="subject"column="post_subject"/><associationproperty="author"javaType="Author"/><collectionproperty="comments"ofType="Comment"><idproperty="id"column="comment_id"/></collection><collectionproperty="tags"ofType="Tag"><idproperty="id"column="tag_id"/></collection><discriminatorjavaType="int"column="draft"><casevalue="1"resultType="DraftPost"/></discriminator></collection></resultMap>
还有支持的JDBC的类型,这个还是比较常用的。
自动映射
可以通过在结果映射上设置 autoMapping 属性来为指定的结果映射设置启用/禁用自动映射。
<resultMapid="userResultMap"type="User"autoMapping="false">#这里可以不一一手动映射每个字段啦,当然也可以映射个别特殊字段 ... </resultMap>
mybatis判断某个resultMap是否开启自动映射配置的时候,会先查找自身的autoMapping属性,如果这个属性设置值了,就直接用这个属性的值,如果resultMap元素的autoMapping属性没有配置,则走全局配置的自动映射规则。
当自动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略大小写)。这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性。
通常数据库列使用大写字母组成的单词命名,单词间用下划线分隔;而 Java 属性一般遵循驼峰命名法约定。为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase 设置为 true。
mybatis: configuration: map-underscore-to-camel-case: true
甚至在提供了结果映射后,自动映射也能工作。在这种情况下,对于每一个结果映射,在 ResultSet 出现的列,如果没有设置手动映射,将被自动映射。在自动映射处理完毕后,再处理手动映射。在下面的例子中,id 和 userName 列将被自动映射,hashed_password 列将根据配置进行映射。
<selectid="selectUsers"resultMap="userResultMap">selectuser_idas"id", user_nameas"userName", hashed_passwordfromsome_tablewhereid=#{id} </select>
# 全局配置
<resultMapid="userResultMap"type="User"><resultproperty="password"column="hashed_password"/></resultMap>
# 或者
<settings><!--关闭自动映射开关--><settingname="autoMappingBehavior"value="NONE"/></settings>
有三种自动映射等级:
NONE-禁用自动映射。仅对手动映射的属性进行映射。PARTIAL-对除在内部定义了嵌套结果映射(也就是连接的属性)以外的属性进行映射FULL-自动映射所有属性。autoMappingBehavior值来源于枚举:org.apache.ibatis.session.AutoMappingBehavior
全局配置:
<settings><!--关闭自动映射开关--><settingname="autoMappingBehavior"value="NONE"/></settings>
默认值是 PARTIAL,这是有原因的。当对连接查询的结果使用 FULL 时,连接查询会在同一行中获取多个不同实体的数据,因此可能导致非预期的映射。下面的例子将展示这种风险:
<selectid="selectBlog"resultMap="blogResult">selectB.id, B.title, A.username, fromBlogBleftouterjoinAuthorAonB.author_id=A.idwhereB.id=#{id} </select><resultMapid="blogResult"type="Blog"><associationproperty="author"resultMap="authorResult"/></resultMap><resultMapid="authorResult"type="Author"><resultproperty="username"column="author_username"/></resultMap>
在该结果映射中,Blog 和 Author 均将被自动映射。但是注意 Author 有一个 id 属性,在 ResultSet 中也有一个名为 id 的列,所以 Author 的 id 将填入 Blog 的 id,这可不是你期望的行为。所以,要谨慎使用 FULL。
总结:
一般情况下只需要简单映射即可,也可以使用自动映射,然后个别特殊字段手动映射。
建议可以去官网学习下。。。
END