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 ...
随机推荐
- WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心
原文:WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心 流文档是WPF中的一种独特的文档承载格式,它的书写和呈现方式都很像HTML,它也几乎具备了HTML的绝大多数优势,并提供了更 ...
- 解决Android Device Chooser 找不到设备问题
第一种情况: 已经启动了官方的模拟器也进入了Android手机界面,可是在Android Device Chooser 看不到设备,怎么办? 例如以下图所看到的,使用Reset adb 或者在adb所 ...
- 《循序渐进Oracle》部分笔记
1.不要用户名/密码 直接/as sysdba 是操作系统认证方式,改变安全方式 sqlnet.ora 里SQLNET.AUTHENTICATION_SERVICES=(NTS)表示启动操作系统认证; ...
- Deploy 11.2.0.3 RAC+DG on Windows 2008 R2 Step by Step
环境规划: 节点1: tc1 192.168.56.101 内存:2G 节点2: tc2 192.168.56.102 内存:2G 物理备库:tcdg192.168.56.108内存:1.5G 操作系 ...
- Big Event in HDU(杭电1171)(多重背包)和(母函数)两种解法
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- JavaScript 常见陷阱
JavaScript中的一些特性和通常我们想象的不太一样.这里我总结了一些有悖直觉的语言特性. 1 数组 1.1 数组的遍历 在直接支持for a in b的语言中,比方Python/Ruby里的a的 ...
- Coreseek:部门查询和增量索引代替实时索引
1.行业调查 索引系统需要通过主查询来获取所有的文档信息,一个简单的实现是整个表的数据到内存,但是这可能会导致整个表被锁定,并且使其它操作被阻止(例如:在MyISAM格款式上INSERT操作).同时, ...
- cocos2d触摸事件处理机制(2.x和3.x变化)
2.x的触摸事件的版本号 触摸事件处理有2种子.以下单点触摸的样本.(另一种多点触摸屏). 创建cocos2d 该项目. 1. 重写下面虚函数. bool ccTouchBegan(cocos2d:: ...
- Sandcastle生成帮助文档
http://www.cnblogs.com/net515/p/3311584.html Sandcastle帮助文档生成器使用介绍 一.软件介绍 Sandcastle是一个管理类库的文档 ...
- wpf 模拟3D效果(和手机浏览图片效果相似)(附源码)
原文 wpf 模拟3D效果(和手机浏览图片效果相似)(附源码) pf的3D是一个很有意思的东西,类似于ps的效果,类似于电影动画的效果,因为动画的效果,(对于3D基础的摄像机,光源,之类不介绍,对于依 ...