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 ...
随机推荐
- Thinkphp常用标签
告:在使用下列所说的任何标签库都需要 HTML第一行加入 <tarlib name=”cx,html” /> 如果想单独引入cx标签库就直接写成<tarlib name=”cx” / ...
- DOM解析XML文件实例
XML文件: response: <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www ...
- 使用Visual Studio 创建可视Web Part部件
使用Visual Studio 创建可视Web Part部件 可视Web Part部件是很强大的Web 部件.它提供内置设计器创建你的用户界面. 本文主要解说怎样使用Visual Studio 创建可 ...
- vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式
vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式 #Region "WPF 当浏览器窗体关闭 ...
- PB数据库相关
---------------------------------------------------------------- 数据库画板: 一张表定义了主键或者唯一索引,则能够在Results视窗 ...
- NET的可运行于树莓派
Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器 最近在业余时间玩玩树莓派,刚开始的时候在树莓派里写一些基于wiringPi库的C语言程序来控制树莓派的GPIO引脚,从而控制 ...
- Blink: Chromium的新渲染引擎
编自http://www.chromium.org/blink 关于blink Google Chrome/Chromium 从创始至今一直使用 WebKit(WebCore) 作为 HTML/CSS ...
- 基于j2ee的程序代写MVC架构
人力资源管理系统 完成系统静态页面设计,页面数量不少于10个,页面需用CSS进行美化,并为需要验证的信息利用JavaScript提供客户端验证.要求至少包含部门信息及部门内员工信息的添加.修改.删除和 ...
- ZOJ Problem Set - 3829Known Notation(贪心)
ZOJ Problem Set - 3829Known Notation(贪心) 题目链接 题目大意:给你一个后缀表达式(仅仅有数字和符号),可是这个后缀表达式的空格不幸丢失,如今给你一个这种后缀表达 ...
- 阅读UML类图和时序图
这里不会将UML的各种元素都提到.我仅仅想讲讲类图中各个类之间的关系. 能看懂类图中各个类之间的线条.箭头代表什么意思后,也就足够应对 日常的工作和交流: 同一时候,我们应该能将类图所表达的含义和终于 ...