myBatis --关联查询

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

结构分析

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属性指定集合中元素的对象类型。

时间: 2024-10-21 13:50:01

myBatis --关联查询的相关文章

mybatis关联查询问题(一对多、多对一)

mybatis 提供了高级的关联查询功能,可以很方便地将数据库获取的结果集映射到定义的Java Bean 中.下面通过一个实例,来展示一下Mybatis对于常见的一对多和多对一关系复杂映射是怎样处理的. 设计一个简单的博客系统,一个用户可以开多个博客,在博客中可以发表文章,允许发表评论,可以为文章加标签.博客系统主要有以下几张表构成: Author表:作者信息表,记录作者的信息,用户名和密码,邮箱等. Blog表   :  博客表,一个作者可以开多个博客,即Author和Blog的关系是一对多.

MyBatis关联查询,一对多关联查询

实体关系图,一个国家对应多个城市 一对多关联查询可用三种方式实现: 单步查询,利用collection标签为级联属性赋值: 分步查询: 利用association标签进行分步查询: 利用collection标签进行分步查询 单步查询 利用collection标签实现一对多单步关联查询: 指定进行关联查询的Java Bean字段,即collection标签的 property 属性: 指定集合中的Java Bean类型,即collection标签的 ofType属性: 实体类 public cla

Mybatis关联查询(嵌套查询)

上一篇文章介绍了基于Mybatis对数据库的增.删.改.查.这一篇介绍下关联查询(join query). 三张表:user article blog 表的存储sql文件: /* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50620 Source Host : localhost:3306 Source Database : mybatis Target Server Type :

7.MyBatis 关联查询(一对一)

1 关联查询映射     1.1 分析数据模型         思路 : 每张表记录的数据内容 每张表重要的字段(主键,外键,非空字段) 表与表之间的关系(外键关系) 表与表之间的业务关系(建立在某个业务意义基础上去分析) 如图:     1.2 一对一查询 有三种实现方法: resultType resultMap中的association嵌套查询 resultMap中的嵌套结果 需求: 进行订单查询,包括用户的姓名和地址信息  SQL语句: SELECT orders.id,orders.u

MyBatis关联查询、多条件查询

1.一对一查询 任务需求; 根据班级的信息查询出教师的相关信息 1.数据库表的设计 班级表: 教师表: 2.实体类的设计 班级表: public class Classes { 9     //定义实体类的属性,与class表中的字段对应 10     private int id;            //id===>c_id 11     private String name;    //name===>c_name 13     /** 14      * class表中有一个tea

MyBatis关联查询 (association) 时遇到的某些问题/mybatis映射

先说下问题产生的背景: 最近在做一个用到MyBatis的项目,其中有个业务涉及到关联查询,我是将两个查询分开来写的,即嵌套查询,个人感觉这样更方便重用: 关联的查询使用到了动态sql,在执行查询时就出现了如下错误:Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.lang.Integer' 因为出现了这个问题,

MyBatis关联查询

首先在数据库bookstore中建立三张表,分别是BSuser,author,reader CREATE TABLE `author` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `realName` varchar(20) COLLATE utf8_bin DEFAULT NULL,   `userID` int(11) DEFAULT NULL,   `IDCard` varchar(20) COLLATE utf8_bin DEFAULT NUL

Mybatis关联查询(转载)

原文地址: http://www.cnblogs.com/xiaolang8762400/p/7399892.html mybatis 提供了高级的关联查询功能,可以很方便地将数据库获取的结果集映射到定义的Java Bean 中.下面通过一个实例,来展示一下Mybatis对于常见的一对多和多对一关系复杂映射是怎样处理的. 设计一个简单的博客系统,一个用户可以开多个博客,在博客中可以发表文章,允许发表评论,可以为文章加标签.博客系统主要有以下几张表构成: Author表:作者信息表,记录作者的信息

Spring+SpringMVC+MyBatis深入学习及搭建(六)——MyBatis关联查询(转发同上)

原地址:http://www.cnblogs.com/shanheyongmu/p/7122520.html 1.商品订单数据模型 1.1数据模型分析思路 (1)每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程. (2)每张表重要的字段设置 非空字段.外键字段 (3)数据库级别表与表之间的关系 外键关系 (4)表与表之间的业务关系 在分析表与表之间的业务关系时,一定要建立在某个业务意义基础上去分析. 1.2属性模型分析 2.一对一查询 2.1需求 查询订