Mybatis之ResultMap一个简短的引论,关联对象
基础部分能够查看我的还有一篇博客http://blog.csdn.net/elim168/article/details/40622491
MyBatis中在查询进行select映射的时候。返回类型能够用resultType,也能够用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,可是resultType跟resultMap不能同一时候存在。在MyBatis进行查询映射的时候,事实上查询出来的每个属性都是放在一个相应的Map里面的,当中键是属性名,值则是其相应的值。
当提供的返回类型属性是resultType的时候,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象相应的属性。所以事实上MyBatis的每个查询映射的返回类型都是ResultMap,仅仅是当我们提供的返回类型属性是resultType的时候,MyBatis对自己主动的给我们把相应的值赋给resultType所指定对象的属性。而当我们提供的返回类型是resultMap的时候。由于Map不能非常好表示领域模型,我们就须要自己再进一步的把它转化为相应的对象,这经常在复杂查询中非常有作用。
有这样一个Blog.java文件
- import java.util.List;
- public class Blog {
- private int id;
- private String title;
- private String content;
- private String owner;
- private List<Comment> comments;
- 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;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- public String getOwner() {
- return owner;
- }
- public void setOwner(String owner) {
- this.owner = owner;
- }
- public List<Comment> getComments() {
- return comments;
- }
- public void setComments(List<Comment> comments) {
- this.comments = comments;
- }
- @Override
- public String toString() {
- return " ----------------博客-----------------\n id: " + id + "\n title: " + title + "\n content: " + content
- + "\n owner: " + owner;
- }
- }
其所相应的数据库表中存储有id,title。Content,Owner属性,那么当我们进行以下这样一个查询映射的时候
- <typeAlias alias="Blog" type="com.tiantian.mybatis.model.Blog"/><!--来自MyBatis的配置文件mybatis_config.xml-->
- <select id="selectBlog" parameterType="int" resultType="Blog">
- select * from t_blog where id = #{id}
- </select><!--来自SQL映射文件BlogMapper.xml-->
MyBatis会自己主动创建一个ResultMap对象,然后基于查找出来的属性名进行键值对封装,然后再看到返回类型是Blog对象,再从ResultMap中取出与Blog对象相应的键值对进行赋值。
当返回类型直接是一个ResultMap的时候也是很实用的,这主要用在进行复杂联合查询上,由于进行简单查询是没有什么必要的。
我们先看看一个返回类型为ResultMap的简单查询。再看看复杂查询的使用方法。
简单查询的写法
- <resultMap type="Blog" id="BlogResult">
- <id column="id" property="id"/>
- <result column="title" property="title"/>
- <result column="content" property="content"/>
- <result column="owner" property="owner"/>
- </resultMap>
- <select id="selectBlog" parameterType="int" resultMap="BlogResult">
- select * from t_blog where id = #{id}
- </select>
select映射中resultMap的值是一个外部resultMap的id。表示返回结果映射到哪一个resultMap上。外部resultMap的type属性表示该resultMap的结果是一个什么样的类型。这里是Blog类型,那么MyBatis就会把它当作一个Blog对象取出。resultMap节点的子节点id是用于标识该对象的id的。而result子节点则是用于标识一些简单属性的,当中的Column属性表示从数据库中查询的属性,Property则表示查询出来的属性相应的值赋给实体对象的哪个属性。
简单查询的resultMap的写法就是这种。
接下来看一个复杂一点的查询。
有一个Comment类,当中有一个Blog的引用,表示是对哪个Blog的Comment,那么我们在查询Comment的时候把其相应的Blog也要查出来赋给其blog属性。
- import java.util.Date;
- public class Comment {
- private int id;
- private String content;
- private Date commentDate = new Date();
- private Blog blog;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- public Date getCommentDate() {
- return commentDate;
- }
- public void setCommentDate(Date commentDate) {
- this.commentDate = commentDate;
- }
- public Blog getBlog() {
- return blog;
- }
- public void setBlog(Blog blog) {
- this.blog = blog;
- }
- public String toString() {
- return blog + "\n ----------------评论-----------------\n id: " + id + "\n content: " + content + "\n commentDate: " + commentDate;
- }
- }
其写法是这种
- <!--来自CommentMapper.xml文件 -->
- <resultMap type="Comment" id="CommentResult">
- <association property="blog" select="selectBlog" column="blog" javaType="Blog"/>
- </resultMap>
- <select id="selectComment" parameterType="int" resultMap="CommentResult">
- select * from t_Comment where id = #{id}
- </select>
- <select id="selectBlog" parameterType="int" resultType="Blog">
- select * from t_Blog where id = #{id}
- </select>
其訪问情况是这种,先是请求id为selectComment的select映射,然后得到一个id为CommentResult的ResultMap对象,我们能够看到在相应的resultMap的返回类型是一个Comment对象。当中仅仅有一个association节点,而没有像前面说的简单查询所相应的id,result子节点,可是其仍会把相应的id等属性赋给Comment对象。这就是前面所说的MyBatis拥有自己主动封装功能。仅仅要你提供了返回类型。MyBatis会依据自己的推断来利用查询结果封装相应的对象,所曾经面的简单查询中。假设你不在resultMap中明白的指出id相应哪个字段,title相应哪个字段,MyBatis也会依据自身的推断来帮你封装,MyBatis的自身推断是把查询的field或其相应的别名与返回对象的属性进行比較,假设相匹配且类型也相匹配,MyBatis则会对其进行赋值。在上面相应的resultMap中关联了一个blog属性,其相应的JAVA类型为Blog,在上述的写法中,关联对象是通过子查询来进行关联的,当然也能够直接通过关联查询来进行关联。上面的association子节点中,Property属性表示是resultMap返回类型的哪个关联属性,对于上面的样例就是Comment管理的blog属性;select表示进行哪个select映射来映射相应的关联属性,即会去请求id为select所相应的值的select映射
来查询出其所关联的属性对象;Column表示当前关联对象在id为CommentResult的resultMap中所相应的键值对。该键值对将作为对关联对象子查询的參数,即将把在selectComment中查询出来的blog属性的值作为參数传给进行关联对象blog的子查询selectBlog的參数。javaType表示当前关联对象在JAVA中是什么类型。
上述介绍的是一对一或一对多的情况下。对一的一方的关联的查询。在实际应用中另一个用的比較多的应用是通过一的一方查出相应的多的一方。在拿出多的一方的时候也相同要把一的一方关联上,即在上述样例中,在拿出Blog对象的时候,就把其相应的Comment所有拿出来,在拿出Comment的时候也还是须要把其相应的Blog拿出来。这是在JAVA中通过一次请求就拿出来的。写法例如以下:
- <!-- 来自BlogMapper.xml文件 -->
- <resultMap type="Blog" id="BlogResult">
- <id column="id" property="id"/>
- <collection property="comments" select="selectCommentsByBlog" column="id" ofType="Comment"></collection>
- </resultMap>
- <resultMap type="Comment" id="CommentResult">
- <association property="blog" javaType="Blog" column="blog" select="selectBlog"/>
- </resultMap>
- <select id="selectBlog" parameterType="int" resultMap="BlogResult">
- select * from t_blog where id = #{id}
- </select>
- <!-- 通过Blog来查找Comment -->
- <select id="selectCommentsByBlog" parameterType="int" resultMap="CommentResult">
- select * from t_Comment where blog = #{blogId}
- </select>
上述请求的入口是id为selectBlog的select映射。返回结果为id为BlogResult的resultMap。id为BlogResult的类型为Blog,当中指定了id的属性和字段,指定id将对MyBatis内部的构造作用非常大。当中关联了一个comments对象,由于一个Blog能够有非常多Comment,该comments为一个集合。所以用集合collection进行映射,当中的select还是表示进行哪个子查询来查询相应的comments。column表示把上述查出来的哪个字段值当作參数传给子查询,ofType也是表示返回类型,这里的返回类型是集合内部的类型,之所以用ofType而不是用type是MyBatis内部为了和关联association进行差别。
測试代码:
- @Test
- public void selectCommentsByBlogTest() {
- SqlSession session = Util.getSqlSessionFactory().openSession();
- CommentMapper commentMapper = session.getMapper(CommentMapper.class);
- );
- for (Comment comment : comments)
- System.out.println(comment);
- session.close();
- }
- /**
- * 查询单条记录
- */
- @Test
- public void testSelectOne() {
- SqlSession session = Util.getSqlSessionFactory().openSession();
- BlogMapper blogMapper = session.getMapper(BlogMapper.class);
- );
- List<Comment> comments = blog.getComments();
- if (comments != null) {
- System.out.println("--------------Comments Size------------" + comments.size());
- for (Comment comment : comments)
- System.out.println(comment);
- }
- session.close();
- }
版权声明:本文博主原创文章,博客,未经同意不得转载。
Mybatis之ResultMap一个简短的引论,关联对象的更多相关文章
- Saiku一个简短的引论
一个简短的引论 Saiku成立于2008年,通过Tom Barber和Paul Stoellberger研究. 最初叫Pentaho分析工具.最初是基于OLAP4J图书馆的使用GWT采用前端分析工具包 ...
- Cache基础知识OR1200在ICache一个简短的引论
以下摘录<步骤吓得核心--软-core处理器的室内设计与分析>一本书 12.1 Cache基本知识 12.1.1 Cache的作用 处理器的设计者通常会声称其设计的处理器一秒钟能做多少次乘 ...
- Hibernate一个简短的引论
我们从几个方面进行阐述Hibernate When? What ? How? When? Hibernate由来是因为当时EJBBean1.1在处理entittBean架构时,花费的时间要比业务逻辑很 ...
- Jsoup一个简短的引论——采用Java抓取网页数据
转载请注明出处:http://blog.csdn.net/allen315410/article/details/40115479 概述 jsoup 是一款Java 的HTML解析器,可直接解析某个U ...
- Spark第一个研究笔记1一片 - Spark一个简短的引论
该公司推出的在线项目Spark拥有近1随着时间的推移.有效,Spark事实上,优秀的分布式计算平台,以提高生产力. 开始本篇笔记.此前的研究会Spark研究报告共享出来(由于篇幅的限制,它将被划分成制 ...
- HTML5分析实战WebSockets一个简短的引论
HTML5 WebSockets规范定义了API,同意web页面使用WebSockets与远程主机协议的双向通信. 介绍WebSocket接口,并限定了全双工通信信道,通过套接字网络. HTML5 W ...
- Oracle 指数 一个简短的引论
1 索引创建语法: CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> ON <schema>.< ...
- PL/SQL一个简短的引论
前言 文本 PL/SQL (Procedure Language,程序语言)SQL 1999主要的数据库供应商提供结构化的共同语言 PL/SQL只有支持Oracle数据库 基本的语法 多行凝视 ...
- HSQL一个简短的引论
前言 在对dao层写測试类的时候,我们须要一个測试数据库,一般我们会是专门建立一个真实的測试数据库,可是有了HSQLDB事情就变得简单了起来. 正题 一.简单介绍: hsql数据库是一款纯Ja ...
随机推荐
- java设计模式_单例
public class Singleton { public static void main(String[] args) throws Exception { System.out.printl ...
- TCP/IP协议栈源码图解分析系列10:linux内核协议栈中对于socket相关API的实现
题记:本系列文章的目的是抛开书本从Linux内核源代码的角度详细分析TCP/IP协议栈内核相关技术 轻松搞定TCP/IP协议栈,原创文章欢迎交流, byhankswang@gmail.com linu ...
- win7下硬盘安装win7+linuxUbuntu双系统方法
Linux安装大致介绍: win7下硬盘安装win7+linuxUbuntu双系统方法 原则: 所有的看完在装,请仔细看 一 条件: 1. 系统选择 linux unbuntu12.04.2-desk ...
- uvalive 2088 - Entropy(huffman编码)
题目连接:2088 - Entropy 题目大意:给出一个字符串, 包括A~Z和_, 现在要根据字符出现的频率为他们进行编码,要求编码后字节最小, 然后输出字符均为8字节表示时的总字节数, 以及最小的 ...
- EJB通过ANT提高EJB应用程序的开发效率、无状态发展本地接口bean、开发状态bean
该jboss集成到eclipse 关掉Jboss控制台新闻Ctrl+c,在MyEclipse→Servers→Jboss可配置JBoss. 通过ANT提高EJB应用的开发效率 在HelloWorld ...
- Codeforces Round#297 div2
B: 题意:给定一个字符串,然后给定m个数字 对于每个数字ai的含义是,将ai到n-ai+1的字符串给翻转一遍. 要求输出m次翻转之后的字符串. 想法就是判断第i个位置的字符是翻转了奇数次,还是偶数次 ...
- oracle迁移mysql数据库注意(转)
oracle转mysql修改: 1. substr() substr( string , 0, 10) 这里测试 必须从 第一位获取 既是 substr(string , 1 , 10)2. to_c ...
- mysql重装后出现乱码解决办法
查看当前连接系统参数:SHOW VARIABLES LIKE '%char%'; mysql> show variables like 'char%'; +------------------- ...
- 更改CPU厂商信息
更改所检测到第三方手机CPU制造商型号,于kernel\arch\arm\mach-msm以下适当Board-*.c更改文件.例如我们8226的CPU.必要的Board-8226.c在里面DT_MAC ...
- 浏览器被劫持到http://hao.169x.cn/?v=108的解决办法
不管什么浏览器打开都是 http://hao.169x.cn/?v=108 1.下载wmi tool,(微软官网下载,我的下载地址是: http://120.52.73.52/download.mi ...