基础部分能够查看我的还有一篇博客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文件

  1. import java.util.List;
  2. public class Blog {
  3. private int id;
  4. private String title;
  5. private String content;
  6. private String owner;
  7. private List<Comment> comments;
  8. public int getId() {
  9. return id;
  10. }
  11. public void setId(int id) {
  12. this.id = id;
  13. }
  14. public String getTitle() {
  15. return title;
  16. }
  17. public void setTitle(String title) {
  18. this.title = title;
  19. }
  20. public String getContent() {
  21. return content;
  22. }
  23. public void setContent(String content) {
  24. this.content = content;
  25. }
  26. public String getOwner() {
  27. return owner;
  28. }
  29. public void setOwner(String owner) {
  30. this.owner = owner;
  31. }
  32. public List<Comment> getComments() {
  33. return comments;
  34. }
  35. public void setComments(List<Comment> comments) {
  36. this.comments = comments;
  37. }
  38. @Override
  39. public String toString() {
  40. return " ----------------博客-----------------\n id: " + id + "\n title: " + title + "\n content: " + content
  41. + "\n owner: " + owner;
  42. }
  43. }

其所相应的数据库表中存储有id,title。Content,Owner属性,那么当我们进行以下这样一个查询映射的时候

  1. <typeAlias alias="Blog" type="com.tiantian.mybatis.model.Blog"/><!--来自MyBatis的配置文件mybatis_config.xml-->
  2. <select id="selectBlog" parameterType="int" resultType="Blog">
  3. select * from t_blog where id = #{id}
  4. </select><!--来自SQL映射文件BlogMapper.xml-->

MyBatis会自己主动创建一个ResultMap对象,然后基于查找出来的属性名进行键值对封装,然后再看到返回类型是Blog对象,再从ResultMap中取出与Blog对象相应的键值对进行赋值。

当返回类型直接是一个ResultMap的时候也是很实用的,这主要用在进行复杂联合查询上,由于进行简单查询是没有什么必要的。

我们先看看一个返回类型为ResultMap的简单查询。再看看复杂查询的使用方法。

简单查询的写法

  1. <resultMap type="Blog" id="BlogResult">
  2. <id column="id" property="id"/>
  3. <result column="title" property="title"/>
  4. <result column="content" property="content"/>
  5. <result column="owner" property="owner"/>
  6. </resultMap>
  7. <select id="selectBlog" parameterType="int" resultMap="BlogResult">
  8. select * from t_blog where id = #{id}
  9. </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属性。

  1. import java.util.Date;
  2. public class Comment {
  3. private int id;
  4. private String content;
  5. private Date commentDate = new Date();
  6. private Blog blog;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public String getContent() {
  14. return content;
  15. }
  16. public void setContent(String content) {
  17. this.content = content;
  18. }
  19. public Date getCommentDate() {
  20. return commentDate;
  21. }
  22. public void setCommentDate(Date commentDate) {
  23. this.commentDate = commentDate;
  24. }
  25. public Blog getBlog() {
  26. return blog;
  27. }
  28. public void setBlog(Blog blog) {
  29. this.blog = blog;
  30. }
  31. public String toString() {
  32. return blog + "\n ----------------评论-----------------\n id: " + id + "\n content: " + content + "\n commentDate: " + commentDate;
  33. }
  34. }

其写法是这种

  1. <!--来自CommentMapper.xml文件    -->
  2. <resultMap type="Comment" id="CommentResult">
  3. <association property="blog" select="selectBlog" column="blog" javaType="Blog"/>
  4. </resultMap>
  5. <select id="selectComment" parameterType="int" resultMap="CommentResult">
  6. select * from t_Comment where id = #{id}
  7. </select>
  8. <select id="selectBlog" parameterType="int" resultType="Blog">
  9. select * from t_Blog where id = #{id}
  10. </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中通过一次请求就拿出来的。写法例如以下:

  1. <!-- 来自BlogMapper.xml文件 -->
  2. <resultMap type="Blog" id="BlogResult">
  3. <id column="id" property="id"/>
  4. <collection property="comments" select="selectCommentsByBlog" column="id" ofType="Comment"></collection>
  5. </resultMap>
  6. <resultMap type="Comment" id="CommentResult">
  7. <association property="blog" javaType="Blog" column="blog" select="selectBlog"/>
  8. </resultMap>
  9. <select id="selectBlog" parameterType="int" resultMap="BlogResult">
  10. select * from t_blog where id = #{id}
  11. </select>
  12. <!--  通过Blog来查找Comment   -->
  13. <select id="selectCommentsByBlog" parameterType="int" resultMap="CommentResult">
  14. select * from t_Comment where blog = #{blogId}
  15. </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进行差别。

測试代码:

  1. @Test
  2. public void selectCommentsByBlogTest() {
  3. SqlSession session = Util.getSqlSessionFactory().openSession();
  4. CommentMapper commentMapper = session.getMapper(CommentMapper.class);
  5. );
  6. for (Comment comment : comments)
  7. System.out.println(comment);
  8. session.close();
  9. }
  10. /**
  11. * 查询单条记录
  12. */
  13. @Test
  14. public void testSelectOne() {
  15. SqlSession session = Util.getSqlSessionFactory().openSession();
  16. BlogMapper blogMapper = session.getMapper(BlogMapper.class);
  17. );
  18. List<Comment> comments = blog.getComments();
  19. if (comments != null) {
  20. System.out.println("--------------Comments Size------------" + comments.size());
  21. for (Comment comment : comments)
  22. System.out.println(comment);
  23. }
  24. session.close();
  25. }

版权声明:本文博主原创文章,博客,未经同意不得转载。

Mybatis之ResultMap一个简短的引论,关联对象的更多相关文章

  1. Saiku一个简短的引论

    一个简短的引论 Saiku成立于2008年,通过Tom Barber和Paul Stoellberger研究. 最初叫Pentaho分析工具.最初是基于OLAP4J图书馆的使用GWT采用前端分析工具包 ...

  2. Cache基础知识OR1200在ICache一个简短的引论

    以下摘录<步骤吓得核心--软-core处理器的室内设计与分析>一本书 12.1 Cache基本知识 12.1.1 Cache的作用 处理器的设计者通常会声称其设计的处理器一秒钟能做多少次乘 ...

  3. Hibernate一个简短的引论

    我们从几个方面进行阐述Hibernate When? What ? How? When? Hibernate由来是因为当时EJBBean1.1在处理entittBean架构时,花费的时间要比业务逻辑很 ...

  4. Jsoup一个简短的引论——采用Java抓取网页数据

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/40115479 概述 jsoup 是一款Java 的HTML解析器,可直接解析某个U ...

  5. Spark第一个研究笔记1一片 - Spark一个简短的引论

    该公司推出的在线项目Spark拥有近1随着时间的推移.有效,Spark事实上,优秀的分布式计算平台,以提高生产力. 开始本篇笔记.此前的研究会Spark研究报告共享出来(由于篇幅的限制,它将被划分成制 ...

  6. HTML5分析实战WebSockets一个简短的引论

    HTML5 WebSockets规范定义了API,同意web页面使用WebSockets与远程主机协议的双向通信. 介绍WebSocket接口,并限定了全双工通信信道,通过套接字网络. HTML5 W ...

  7. Oracle 指数 一个简短的引论

    1 索引创建语法: CREATE UNIUQE | BITMAP INDEX <schema>.<index_name>       ON <schema>.< ...

  8. PL/SQL一个简短的引论

    前言 文本 PL/SQL (Procedure Language,程序语言)SQL 1999主要的数据库供应商提供结构化的共同语言  PL/SQL只有支持Oracle数据库 基本的语法 多行凝视   ...

  9. HSQL一个简短的引论

    前言     在对dao层写測试类的时候,我们须要一个測试数据库,一般我们会是专门建立一个真实的測试数据库,可是有了HSQLDB事情就变得简单了起来. 正题 一.简单介绍: hsql数据库是一款纯Ja ...

随机推荐

  1. 利用python 提取log 文件里的关键句子,并进行统计分析

    利用python开发了一个提取sim.log 中的各个关键步骤中的时间并进行统计的程序: #!/usr/bin/python2.6 import re,datetime file_name='/hom ...

  2. javascript UniqueID属性

        在Web页中的每一个HTML元素都一个ID属性,ID作为其标示,在我们的普通理解中它应该是unique的.但是HTML元素的ID属性是可写的,这就造成了我们非常可能人为的使ID的反复.按么假设 ...

  3. 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁

    上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和基本的方法,显示了怎样 ...

  4. HDU 4126 Genghis Khan the Conqueror MST+树形dp

    题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...

  5. boost事件处理

    尽管这个库的名字乍一看好象有点误导,但实际上并不是如此. Boost.Signals 所实现的模式被命名为 '信号至插槽' (signal to slot).它基于下面概念:当相应的信号被发出时.相关 ...

  6. set、env、export差分

    set:显示当前shell变量,用户变量包含当前用户 env:显示用户变量 export:显示当前导出成用户变量的shell变量 举例来说: root@kali:~# aaa=bbb         ...

  7. C#访问MySQL数据库(winform+EF)

    原文:C#访问MySQL数据库(winform+EF) 以前都是C#连接SQLServer,现在MySQL也比较火了,而且是开源跨平台的,这里连接使用一下,主要是体会一下整个流程,这里使用的是winf ...

  8. 【Android进阶】Android面试题目整理与讲解(二)

    1. ArrayList,Vector, LinkedList 的存储性能和特性 ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们 ...

  9. 解决android3.0版本号以上应用接收不到开机广播问题

    如今是2014-07-16 下午15:27. 好久没写过东西,突然间灵感喷发想写点东西(事实上是刚刚弄好了一个棘手的问题,自豪中..呵呵呵呵 我牛掰).废话不多说,进入正题. 不知道你们又没有碰到这问 ...

  10. 【Jqurey EasyUI+Asp.net】---DataGrid增加、删、更改、搜

    在前面写了两,但不知道如何完成,对比刚刚开始学这个,他们摸着石头过河,一步步.在最后两天DataGridCRUD融合在一起.因此份额.我希望像我这样谁是刚刚开始学习一些帮助. 直接主题酒吧. 它是说数 ...