文档章节

myBatis --关联查询

求是科技
 求是科技
发布于 2015/10/21 10:14
字数 1500
阅读 1449
收藏 2
点赞 0
评论 0

业务需求,需要查询到的结果集如下

结构分析

1.查询出所有的评论,即data[]里面是一个list

2.查出list中每个评论id(即userObjectCmmtId)下面所有的子评论,即一对多的关系。

实现方法如下

1.接口层文件如下


2.实现层文件如下


3.返回第一层bean如下

返回第二层bean

4.xml文件如下(第一层)

   <resultMap type="com.zhiji.caren.VO.CmmtRel" id="cmmtListMap">
        <result column="USER_PERSON_CMMT_ID" property="userObjectCmmtId"
            jdbcType="VARCHAR" />
        <result column="ROOT_USER_ID" property="rootUserId" jdbcType="INTEGER" />
        <result column="ROOT_USER_IMG" property="rootUserImg" jdbcType="VARCHAR" />
        <result column="ROOT_USER_NICKNAME" property="rootUserNickName"
            jdbcType="VARCHAR" />
        <result column="ROOT_CMMT_CONTENT" property="rootCmmtContent"
            jdbcType="VARCHAR" />
        <result column="ROOT_ADD_TIME" property="rootAddTime" jdbcType="VARCHAR" />
        <collection property="cmmtData" javaType="ArrayList"
            column="{rootCmmtId = USER_PERSON_CMMT_ID" select="getSubCmmtInfo" />
    </resultMap>
    
    <select id="selectCmmtList" resultMap="cmmtListMap">
        SELECT
        tupctui.USER_PERSON_CMMT_ID,
        tupctui.ROOT_USER_ID,
        tupctui.ROOT_USER_IMG,
        tupctui.ROOT_USER_NICKNAME,
        tupctui.ROOT_CMMT_CONTENT,
        tupctui.ROOT_ADD_TIME
        from
        (SELECT
        tupc.USER_PERSON_CMMT_ID,
        tupc.USER_ID AS ROOT_USER_ID,
        tui.USER_IMG AS
        ROOT_USER_IMG,
        tui.NICKNAME AS ROOT_USER_NICKNAME,
        tupc.CMMT_CONTENT AS
        ROOT_CMMT_CONTENT,
        tupc.ADD_TIME AS ROOT_ADD_TIME
        FROM
        t_user_person_cmmt tupc,t_user_info tui
        WHERE
        tupc.USER_ID = tui.USER_ID
        AND
        tupc.ROOT_CMMT_ID is NULL
        AND
        PERSON_ID = #{objectId,jdbcType =
        INTEGER}
        <if test="lastTime != null">
            AND
            tupc.ADD_TIME &lt;= #{lastTime}
        </if>
        ORDER BY ROOT_ADD_TIME DESC)
        tupctui
        LIMIT #{pageIndex}
    </select>

xml文件第二层如下

    <resultMap type="com.zhiji.caren.VO.CmmtRelChild" id="subCmmtMap">
        <result column="SUPER_CMMT_ID" property="superCmmtId" jdbcType="VARCHAR" />
        <result column="SUPER_USER_ID" property="superUserId" jdbcType="INTEGER" />
        <result column="SUPER_NICKNAME" property="superNickName"
            jdbcType="VARCHAR" />
        <result column="CHILD_USER_ID" property="childUserId" jdbcType="INTEGER" />
        <result column="CHILD_USER_NICKNAME" property="childUserNickName"
            jdbcType="VARCHAR" />
        <result column="CHILD_CMMT_CONTENT" property="childCmmtContent"
            jdbcType="VARCHAR" />
        <result column="USER_PERSON_CMMT_ID" property="childCmmtId"
            jdbcType="VARCHAR" />
    </resultMap>
    
    <select id="getSubCmmtInfo" resultMap="subCmmtMap">
        SELECT
        tupc.ROOT_CMMT_ID,
        tupc.SUPER_CMMT_ID,
        tupc.SUPER_USER_ID,
        tuii.NICKNAME as SUPER_NICKNAME,
        tupc.USER_ID AS CHILD_USER_ID,
        tui.NICKNAME AS CHILD_USER_NICKNAME,
        tupc.CMMT_CONTENT AS CHILD_CMMT_CONTENT,
        tupc.USER_PERSON_CMMT_ID,
        tupc.ADD_TIME AS CHILD_ADD_TIME
        FROM
        t_user_person_cmmt tupc
        LEFT JOIN
        t_user_info tui on
        tupc.USER_ID = tui.USER_ID
        LEFT JOIN
        t_user_info tuii
        on
        tupc.SUPER_USER_ID = tuii.USER_ID
        WHERE
        tupc.ROOT_CMMT_ID IS NOT NULL
        AND
        ROOT_CMMT_ID = #{rootCmmtId}
        ORDER BY CHILD_ADD_TIME
    </select>

总结:如上例子中用到了mybatis的collection,即

        <collection property="cmmtData" javaType="ArrayList"
            column="{rootCmmtId = USER_PERSON_CMMT_ID" select="getSubCmmtInfo" />

现在就这个点学习下写一篇文章

//参考文章如下链接,真心讲的不错,好东西拿出来大家分享

http://www.cnblogs.com/xdp-gacl/p/4264440.html


一、一对一关联查询

假设A表(班级表,t_class)

c_id       c_name      teacher_id

1            一班           x

2            二班           x

假设B表(教师表,t_teacher)

t_id       t_name

1           张三

2           李四

现在业务需求:根据班级id查询班级信息(查询出该班级的老师信息,假设班级与教师一对一关系)

方法一:嵌套结果--联表查询,一次查询得出结果

<!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
     <id property="id" column="c_id"/>
     <result property="name" column="c_name"/>
     <association property="teacher" javaType="me.gacl.domain.Teacher">
             <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
     </association>    
</resultMap>        
<select id="getClass" parameterType="int" resultMap="ClassResultMap">         
        select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}     
</select>

备注:实际过程中,我可能不会用到association那段,我在 me.gacl.domain.classes中定义属性的时候,直接将班级属性和老师属性定义在一起,这样resultMap就可以改写成如下

<resultMap type="me.gacl.domain.ClassesAndTeacher" id="ClassResultMap">
     <id property="cid" column="c_id"/>
     <result property="name" column="c_name"/>
     <result property="tid" column="t_id"/>
     <result property="name" column="t_name"/>
</resultMap>

最后,仔细考虑下,还是觉得分开要好些,因为班级bean和教师bean是两个基础bean,而我根据这个业务需求还需要重新定义一个混合bean,即浪费了一个bean。按理推之,如果每个业务都需要关联多张表,按照我的做法,即需要新建多个bean,按照第一种方法,则只需要关联基础bean就行。

方法二:嵌套查询--多次查询得出结果      

<select id="getClass2" parameterType="int" resultMap="ClassResultMap">
        select * from class where c_id=#{id}
</select>

<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
     <id property="id" column="c_id"/>
     <result property="name" column="c_name"/>
     <association property="teacher" column="teacher_id" select="getTeacher"/>
 </resultMap>
 
 <select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
     SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
 </select>

备注:很明显这是分两次查询,先用#{id}查询班级信息,再用#{id}查询教师信息。

总结:

MyBatis中使用association标签来解决一对一的关联查询,association标签可用的属性如下:

property:对象属性的名称

javaType:对象属性的类型

column:所对应的外键字段名称

select:使用另一个查询封装的结果


二、一对多关联查询

新的需求:根据班级id查询出班级信息(包括教师,学生)。班级与教师一对一关系,班级与学生一对多关系。

现在需要在如上数据库表的基础上加上学生表

假设C表(学生表,t_student)

s_id       s_name         s_classId

1           小吴               x

2           小李               x

1.返回的结构如下

public class classInfo
{
        //班级id
        private int id;
        //班级名称
        private String name;
        /**
        * class表中有一个teacher_id字段,所以在Classes类中定义一个teacher属性,
        * 用于维护teacher和class之间的一对一关系,通过这个teacher属性就可以知道这个班级是由哪个老师负责的
        **/
        private Teacher teacher;
        //使用一个List<Student>集合属性表示班级拥有的学生
        private List<Student> students;
}

方法一:嵌套结果--联表查询,一次查询得出结果

<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
     <id property="id" column="c_id"/>
     <result property="name" column="c_name"/>
     <association property="teacher" column="teacher_id" javaType="me.gacl.domain.Teacher">
         <id property="id" column="t_id"/>
          <result property="name" column="t_name"/>
     </association> 
     <!-- ofType指定students集合中的对象类型 -->
     <collection property="students" ofType="me.gacl.domain.Student">
          <id property="id" column="s_id"/>
          <result property="name" column="s_name"/>
     </collection>
</resultMap>

<select id="getClass" parameterType="int" resultMap="ClassResultMap">
        select * from class c, teacher t,student s where c.teacher_id=t.t_id and c.C_id=s.class_id and  c.c_id=#{id}
</select>

方法二:嵌套查询

<select id="getClass" parameterType="int" resultMap="ClassResultMap">
        select * from class where c_id=#{id}
</select>        

<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
    <id property="id" column="c_id"/>
    <result property="name" column="c_name"/>
    <association property="teacher" column="teacher_id" javaType="me.gacl.domain.Teacher" select="getTeacher">
    </association>
    <collection property="students" ofType="me.gacl.domain.Student" column="c_id" select="getStudent">
    </collection>
</resultMap>

<select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
        SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}   
</select>
<select id="getStudent" parameterType="int" resultType="me.gacl.domain.Student">
        SELECT s_id id, s_name name FROM student WHERE class_id=#{id}
</select>

备注:

select * from class where c_id=#{id}  //#{id}是是实现层传过来的值

select t_id,t_name from teacher where t_id=#{id}  //#{id}是上一个查询得到的teacher_id

select s_id,s_name from student where s_classId=#{id}  //#{id}是查询到的c_id

总结:MyBatis中使用collection标签来解决一对多的关联查询,ofType属性指定集合中元素的对象类型。

© 著作权归作者所有

共有 人打赏支持
求是科技
粉丝 89
博文 453
码字总数 228281
作品 0
成都
后端工程师
Mybatis关联结果查询分页方法

在Mybatis分页插件的说明中有如下内容 不支持的情况 对于关联结果查询,使用分页得不到正常的结果,因为只有把数据全部查询出来,才能得到最终的结果,对这个结果进行分页才有效。因而如果是...

Liuzh_533 ⋅ 2014/06/05 ⋅ 10

MyBatis 实践 -动态SQL/关联查询

标签: Java与存储 动态SQL 动态SQL提供了对SQL语句的灵活操作,通过表达式进行判断,对SQL进行拼接/组装. if 对查询条件进行判断,如果输入参数不为空才进行查询条件的拼接. mapper 会自动处理...

hanqing280441589 ⋅ 2016/02/28 ⋅ 0

mybatis初步----查询之resultMap和resultType

MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性,而当我们提供的返回...

microb ⋅ 2013/10/12 ⋅ 0

Mybatis--resultType和resultMap

一、概述 MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟...

北京_ ⋅ 2014/08/27 ⋅ 1

MyBatis学习总结(五)——实现关联表查询

一、一对一关联 1.1、提出需求   根据班级id查询班级信息(带老师的信息) 1.2、创建表和数据   创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就...

Carl_ ⋅ 2015/08/12 ⋅ 0

MyBatis学习总结(五)——实现关联表查询

一、一对一关联 1.1、提出需求   根据班级id查询班级信息(带老师的信息) 1.2、创建表和数据   创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就...

Carl_ ⋅ 2015/08/12 ⋅ 0

Java面试----2018年MyBatis常见实用面试题整理

Java面试----2018年MyBatis常见实用面试题整理 1、什么是MyBatis? 答:MyBatis是一个可以自定义SQL、存储过程和高级映射的持久层框架。 2、讲下MyBatis的缓存 答:MyBatis的缓存分为一级缓存...

优惠券活动 ⋅ 04/29 ⋅ 0

Mybatis3.4.x技术内幕(二十三):Mybatis面试问题集锦(大结局)

Mybatis技术内幕系列博客,从原理和源码角度,介绍了其内部实现细节,无论是写的好与不好,我确实是用心写了,由于并不是介绍如何使用Mybatis的文章,所以,一些参数使用细节略掉了,我们的目...

祖大俊 ⋅ 2016/09/17 ⋅ 34

【MyBatis框架】高级映射-延迟加载

延迟加载 1.什么是延迟加载 resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。 需求: 如果查询订单并且关联查...

Mysoft ⋅ 2015/09/18 ⋅ 0

MyBatis多对多关联查询示例——MyBatis学习笔记之十八

MyBatis系列的上一篇博客发表时,笑笑还没有出生。转眼间八个月过去了,他已经是个大宝宝了。这么长时间未更新MyBatis系列的博客,想来真是罪过。不过有了宝宝之后,的确会分散自己很大一部分...

NashMaster2011 ⋅ 2014/04/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

马氏距离与欧氏距离

马氏距离 马氏距离也可以定义为两个服从同一分布并且其协方差矩阵为Σ的随机变量之间的差异程度。 如果协方差矩阵为单位矩阵,那么马氏距离就简化为欧氏距离,如果协方差矩阵为对角阵,则其也...

漫步当下 ⋅ 昨天 ⋅ 0

聊聊spring cloud的RequestRateLimiterGatewayFilter

序 本文主要研究一下spring cloud的RequestRateLimiterGatewayFilter GatewayAutoConfiguration @Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMi......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部