【MyBatis】ResultMap
转载:https://www.cnblogs.com/yangchongxing/p/10486854.html
支持的 JDBC 类型
为了未来的参考,MyBatis 通过包含的 jdbcType 枚举型,支持下面的 JDBC 类型。
注意:在指定jdbcType时类型是列出的这些,并且必须是大写
BIT | FLOAT | CHAR | TIMESTAMP | OTHER | UNDEFINED |
TINYINT | REAL | VARCHAR | BINARY | BLOB | NVARCHAR |
SMALLINT | DOUBLE | LONGVARCHAR | VARBINARY | CLOB | NCHAR |
INTEGER | NUMERIC | DATE | LONGVARBINARY | BOOLEAN | NCLOB |
BIGINT | DECIMAL | TIME | NULL | CURSOR | ARRAY |
目录
====================================================================
====================================================================
constructor - 用于在实例化类时,注入结果到构造方法中
idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
arg - 将被注入到构造方法的一个普通结果
id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
result – 注入到字段或 JavaBean 属性的普通结果
association – 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引用一个
collection – 一个复杂类型的集合
嵌套结果映射 – 集合可以指定为一个 resultMap 元素,或者引用一个
discriminator – 使用结果值来决定使用哪个 resultMap
case – 基于某些值的结果映射
嵌套结果映射 – 一个 case 也是一个映射它本身的结果,因此可以包含很多相 同的元素,或者它可以参照一个外部的 resultMap。
属性 property,column,javaType,jdbcType,typeHandler
注意:jdbcType="VARCHAR" 上表列出的类型,必须大写
<id property="id" column="post_id"/> <result property="subject" column="post_subject" jdbcType="VARCHAR"/>
由顺序决定选择那个构造器
构造器,注意:id 不能用 int 而要用 Integer 对象
public Blog(Integer id, String title, String content) { this.id = id; this.title = title; this.content = content; }
映射
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int"/> <arg column = "title" javaType = "String"/> <arg column = "content" javaType = "String"/> </constructor> </resultMap>
由参数名决定选择那个构造器,与顺序无关
方式一、构造器添加 @Param 注解
public Blog(@Param("id") Integer id, @Param("title") String title, @Param("content") String content) { this.id = id; this.title = title; this.content = content; }
映射顺序随意
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "content" javaType = "String" name = "content"/> <arg column = "title" javaType = "String" name = "title"/> </constructor> </resultMap>
方式二、使用 '-parameters' 编译选项并启用 useActualParamName 选项(默认开启)来编译项目
<settings> <setting name="useActualParamName" value="true"/> </settings>
useActualParamName 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的工程必须采用Java 8编译,并且加上-parameters选项。(从3.4.1开始)默认值是true
命令行:javac -parameters 文件
eclipse:Window->Preferences->Java->Compiler 下勾选 Store information about method parameters(usable via reflection)
public Blog(Integer id, String title, String content) { this.id = id; this.title = title; this.content = content; }
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> </resultMap>
用到的实体
public class Blog { private int id; private String title; private String content; protected Author author; } public class Author { protected int id; protected String name; }
①嵌套查询
映射
public interface BlogMapper { public Blog selectBlog(int id); }
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <association property="author" column="author_id" javaType="Author" select="selectAuthor"/> </resultMap> <!-- 下面的参数通过上面 association 的 column 字段指定 --> <select id="selectBlog" resultMap="blogResultMap" > select id,title,content,author_id from blog where id = #{id} </select> <select id="selectAuthor" resultType="Author"> select id,name from author where id = #{id} </select>
嵌套的 select author 参数 是通过 association 的 column 传递进去
②嵌套结果
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <!-- column 不需要 --> <association property="author" javaType="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> </association> </resultMap> <select id="selectBlog" resultMap="blogResultMap" > select b.id, b.title, b.content, b.author_id, a.name as author_name from blog b left outer join author a on b.author_id = a.id where b.id = #{id} </select>
引用外部结果映射
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <!-- 外部结果映射来映射关联 --> <association property="author" javaType="Author" resultMap="authorResultMap"/> </resultMap> <resultMap id="authorResultMap" type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> </resultMap> <select id="selectBlog" resultMap="blogResultMap" > select b.id, b.title, b.content, b.author_id, a.name as author_name from blog b left outer join author a on b.author_id = a.id where b.id = #{id} </select>
使用 columnPrefix 共用外部结果映射
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <!-- 外部结果映射 --> <association property="author" javaType="Author" resultMap="authorResultMap"/> <association property="ycxAuthor" javaType="Author" resultMap="authorResultMap" columnPrefix="ycx_"/> </resultMap> <resultMap id="authorResultMap" type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> </resultMap> <select id="selectBlog" resultMap="blogResultMap" > select b.id, b.title, b.content, b.author_id, a.name as author_name, ycx.id as ycx_author_id, ycx.name as ycx_author_name from blog b left outer join author a on b.author_id = a.id left outer join author ycx on b.author_id = ycx.id where b.id = #{id} </select>
实体
public class Blog { private int id; private String title; private String content; protected Author author; protected List<Post> posts; } public class Author { protected int id; protected String name; } public class Post { protected int id; protected String subject; protected String body; }
①嵌套查询
注意:javaType="ArrayList" 是 Blog 属性的的类型为 ArrayList,新字段 ofType="Post" 是集合 ArrayList 包含类型为 Post。javaType 可以省略 MyBatis 可以推算出来。
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <!-- 嵌套查询 column 是要传入子查询的值 --> <association property="author" javaType="Author" column="author_id" select="selectAuthor"/> <collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPost"/> </resultMap> <resultMap id="authorResultMap" type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> </resultMap> <select id="selectBlog" resultMap="blogResultMap"> select * from blog where id = #{id} </select> <select id="selectAuthor" resultType="Author"> select * from author where id = #{id} </select> <select id="selectPost" resultType="Post"> select * from post where blog_id = #{id} </select>
②嵌套结果
<resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <!-- 嵌套结果 --> <association property="author" javaType="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> </association> <collection property="posts" javaType="ArrayList" ofType="Post"> <id property="id" column="post_id"/> <result property="subject" column="subject"/> <result property="body" column="body"/> </collection> </resultMap> <select id="selectBlog" resultMap="blogResultMap"> select b.id, b.title, b.content, a.id as author_id, a.name as author_name, p.id as post_id, p.subject as post_subject, p.body as post_body from blog b left outer join author a on b.author_id = a.id left outer join post p on p.blog_id = b.id where b.id = #{id} </select>
引用外部结果映射
<resultMap id="authorResultMap" type="Author"> <id property="id" column="author_id"/> <result property="name" column="author_name"/> </resultMap> <resultMap id="postResultMap" type="Post"> <id property="id" column="post_id"/> <result property="subject" column="post_subject"/> <result property="body" column="post_body"/> </resultMap> <resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <!-- 外部结果映射 --> <association property="author" javaType="Author" resultMap="authorResultMap"/> <collection property="posts" javaType="ArrayList" ofType="Post" resultMap="postResultMap"/> </resultMap> <select id="selectBlog" resultMap="blogResultMap"> select b.id, b.title, b.content, a.id as author_id, a.name as author_name, p.id as post_id, p.subject as post_subject, p.body as post_body from blog b left outer join author a on b.author_id = a.id left outer join post p on p.blog_id = b.id where b.id = #{id} </select>
使用 columnPrefix 共用外部结果映射
<resultMap id="authorResultMap" type="Author"> <id property="id" column="id"/> <result property="name" column="name"/> </resultMap> <resultMap id="postResultMap" type="Post"> <id property="id" column="id"/> <result property="subject" column="subject"/> <result property="body" column="body"/> </resultMap> <resultMap id="blogResultMap" type="Blog"> <constructor> <idArg column = "id" javaType = "int" name = "id"/> <arg column = "title" javaType = "String" name = "title"/> <arg column = "content" javaType = "String" name = "content"/> </constructor> <!-- 外部结果映射 --> <association property="author" javaType="Author" resultMap="authorResultMap" columnPrefix="author_"/> <collection property="posts" javaType="ArrayList" ofType="Post" resultMap="postResultMap" columnPrefix="post_"/> </resultMap> <select id="selectBlog" resultMap="blogResultMap"> select b.id, b.title, b.content, a.id as author_id, a.name as author_name, p.id as post_id, p.subject as post_subject, p.body as post_body from blog b left outer join author a on b.author_id = a.id left outer join post p on p.blog_id = b.id where b.id = #{id} </select>
实体
public class Blog { protected int id; protected String title; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @Override public String toString() { return "Blog [id=" + id + ", title=" + title + "]"; } } public class BlogContent extends Blog{ protected String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return super.toString() + " " + "BlogContent [content=" + content + "]"; } } public class BlogImage extends Blog { protected String path; public String getPath() { return path; } public void setPath(String path) { this.path = path; } @Override public String toString() { return super.toString() + " " + "BlogImage [path=" + path + "]"; } }
简洁方式
<resultMap id="blogResultMap" type="Blog"> <id property="id" column="id"/> <result property="title" column="title"/> <discriminator javaType="int" column="type"> <case value="1" resultType="BlogContent"> <result property="content" column="content"/> </case> <case value="2" resultType="BlogImage"> <result property="path" column="path"/> </case> </discriminator> </resultMap> <select id="selectBlog" resultMap="blogResultMap"> select * from blog where id = #{id} </select>
外部结果映射
<resultMap id="blogContentResultMap" type="BlogContent"> <result property="content" column="content"/> </resultMap> <resultMap id="blogImageResultMap" type="BlogImage"> <result property="path" column="path"/> </resultMap> <resultMap id="blogResultMap" type="Blog"> <id property="id" column="id"/> <result property="title" column="title"/> <discriminator javaType="int" column="type"> <case value="1" resultMap="blogContentResultMap"/> <case value="2" resultMap="blogImageResultMap"/> </discriminator> </resultMap> <select id="selectBlog" resultMap="blogResultMap"> select * from blog where id = #{id} </select>