在这篇文章里面主要讲解如何在mybatis里面使用一对一、一对多、多表联合查询(类似视图)操作的例子。

  注:阅读本文前请先大概看一下之前两篇文章。

  一、表结构

  班级表class,学生表student,班级学生关系表ClassStudent。

  这里一个学生只会在一个班级里面,也就是一对一的关系;一个班级有多个学生,也就是一对多的关系。

  结构如下:

CREATE TABLE [dbo].[Class](
[class_id] [int] NOT NULL,
[class_name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Class] PRIMARY KEY CLUSTERED
(
[class_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] CREATE TABLE [dbo].[ClassStudent](
[class_id] [int] NOT NULL,
[student_id] [int] NOT NULL
) ON [PRIMARY] CREATE TABLE [dbo].[Student](
[s_id] [int] NOT NULL,
[s_name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[s_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

    3张表的数据如下:

insert into Class values(1,'三(1)班')
insert into Class values(2,'三(2)班')
insert into Class values(3,'三(3)班')
insert into Class values(4,'三(4)班') insert into Student values(1001,'张三')
insert into Student values(1002,'李四')
insert into Student values(1003,'赵五')
insert into Student values(1004,'王二麻子') insert into ClassStudent values(1,1001)
insert into ClassStudent values(1,1003)
insert into ClassStudent values(4,1002)
insert into ClassStudent values(3,1004)

  

  二、在原项目下新建一个包com.mybatis.sqljoinrelation,在包里面新建一个sqlMapper.xml的映射文件,在项目的mybatis的配置文件conf.xml中对这个sqlMapper.xml进行注册,注册片段如下:

<!-- 注册映射文件 -->
<mappers>
<mapper resource="com/mybatis/sqljoinrelation/sqlMapper.xml" />
</mappers>

  紧接着在原项目下再新建一个包com.mybatis.bean,在里面新建实体类

  学生:

package com.mybatis.bean;

/**
* 学生(临时)
*/
public class StudentTemp {
private int studentid;
private String studentname;
private Class tempClass; public Class getTempClass() {
return tempClass;
}
public void setTempClass(Class tempClass) {
this.tempClass = tempClass;
}
public int getStudentid() {
return studentid;
}
public void setStudentid(int studentid) {
this.studentid = studentid;
}
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
} @Override
public String toString() {
return "StudentTemp [studentid=" + studentid + ", studentname="
+ studentname + ", tempClass=" + tempClass + "]";
} }

  班级:

package com.mybatis.bean;

/**
* 班级
*/
public class Class {
private int classid;
private String classname; public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
} @Override
public String toString() {
return "Class [classid=" + classid + ", classname=" + classname + "]";
}
}

  学生班级视图类:

package com.mybatis.bean;

public class studentclass {
private int s_id;
private String s_name;
private int class_id;
private String class_name;
public int getS_id() {
return s_id;
}
public void setS_id(int s_id) {
this.s_id = s_id;
}
public String getS_name() {
return s_name;
}
public void setS_name(String s_name) {
this.s_name = s_name;
}
public int getClass_id() {
return class_id;
}
public void setClass_id(int class_id) {
this.class_id = class_id;
}
public String getClass_name() {
return class_name;
}
public void setClass_name(String class_name) {
this.class_name = class_name;
}
@Override
public String toString() {
return "studentclass [s_id=" + s_id + ", s_name=" + s_name
+ ", class_id=" + class_id + ", class_name=" + class_name + "]";
} }

  三、查询操作

  1、 一对一,查询学生编号等于1001且他所在班级信息

  2、一对多,查询班级编号等于1且包含所有学生信息

  3、类似视图查询学生编号等于1001且他所在班级信息

  sqlMapper.xml如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.sqljoinrelation.sqlMapper"> <!-- 1、 获取某学生以及该学生所在班级的信息 -->
<!-- 可以显示指出c.class_id,c.class_name,s.s_id,s.s_name列明,
如果用"*"代替,则mybatis会自动匹配resultMap中提供的列名 -->
<select id="getStudentAndClass" parameterType="int" resultMap="studentClassMap">
select c.class_id,c.class_name,s.s_id,s.s_name
from Class c left join ClassStudent cs
on c.class_id = cs.class_id
left join Student s
on cs.student_id = s.s_id
where s.s_id = #{id}
</select> <!-- resultMap中的type表示返回什么类型的对象 -->
<resultMap type="com.mybatis.bean.StudentTemp" id="studentClassMap">
<!-- property 表示com.mybatis.bean.StudentTemp中的属性; column 表示表中的列名 -->
<id property="studentid" column="s_id" />
<result property="studentname" column="s_name" /> <!-- association字面意思关联,这里只专门做一对一关联; property表示是com.mybatis.bean.StudentTemp中的属性名称;
javaType表示该属性是什么类型对象 -->
<association property="tempClass" javaType="com.mybatis.bean.Class">
<!-- property 表示com.mybatis.bean.Class中的属性; column 表示表中的列名 -->
<id property="classid" column="class_id" />
<result property="classname" column="class_name" />
</association>
</resultMap> <!-- 2、获取某学生以及该学生所在班级的信息,类似视图实现方式 -->
<!-- resultType 对应简单类型,也就是实体中的属性名称与数据库表字段名称一模一样;
resultMap 对应复杂类型,属性名称与字段名称不一样可以通过resultMap中property,column进行映射 -->
<select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass">
select c.class_id,c.class_name,s.s_id,s.s_name
from Class c left join ClassStudent cs
on c.class_id = cs.class_id
left join Student s
on cs.student_id = s.s_id
where s.s_id = #{id}
</select> <!-- 3、获取某班级以及班级里面所有学生的信息 -->
<select id="getClassStudents" parameterType="int" resultMap="classStudentsMap">
select *
from Class c left join ClassStudent cs
on c.class_id = cs.class_id
left join Student s
on cs.student_id = s.s_id
where c.class_id = #{id}
</select>
<resultMap type="com.mybatis.bean.ClassTemp" id="classStudentsMap">
<id property="classid" column="class_id"/>
<result property="classname" column="class_name"/> <!-- property表示集合类型属性名称,ofType表示集合中的对象是什么类型 -->
<collection property="students" ofType="com.mybatis.bean.Student">
<id property="studentid" column="s_id"/>
<result property="studentname" column="s_name"/>
</collection>
</resultMap>
</mapper>

  测试代码如下:

  一对一与类似视图查询的代码在一起,如下:

package com.mybatis.sqljoinrelation;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import com.mybatis.util.MybatisUtils; /**
* 一对一
*/
public class testonetoone {
public static void main(String[] args) {
SqlSessionFactory factory = MybatisUtils.getFactory();
SqlSession session = null;
try {
session = factory.openSession(true); //1、StudentTemp
String statement1 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClass";
System.out.println(session.selectOne(statement1, 1001)); //2、用model类型接收数据
String statement2 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClassView";
System.out.println(session.selectOne(statement2, 1001)); } catch (Exception e) {
e.printStackTrace();
}finally{
session.close();
}
}
}

  一对多测试代码如下:

package com.mybatis.sqljoinrelation;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import com.mybatis.util.MybatisUtils; /**
* 一对多
*/
public class testonetomany {
public static void main(String[] args) {
SqlSessionFactory factory = MybatisUtils.getFactory();
SqlSession session = null;
try {
session = factory.openSession(true); //1、StudentTemp
String statement = "com.mybatis.sqljoinrelation.sqlMapper.getClassStudents";
System.out.println(session.selectOne(statement, 1)); } catch (Exception e) {
e.printStackTrace();
}finally{
session.close();
}
}
}

  四、sqlMapper.xml需要说明的问题

  1、一对一:<association property="tempClass" javaType="com.mybatis.bean.Class">

    association字面意思关联,这里只专门做一对一关联; property表示是com.mybatis.bean.StudentTemp中的属性名称; javaType表示该属性是什么类型对象

    2、类似视图查询: <select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass">

    resultType 对应简单类型,也就是实体中的属性名称与数据库表字段名称一模一样;
    resultMap 对应复杂类型,属性名称与字段名称不一样可以通过resultMap中property,column进行映射,其中一对一与一对多都是用resultMap来映射

  3、一对多:<collection property="students" ofType="com.mybatis.bean.Student">

   collection字面意思是集合,这里专门做一对多关联 ,property表示集合类型属性名称,ofType表示集合中的对象是什么类型

  4、<select>select * from ...</student>与<select>select 字段1,字段2,字段3... from ...</student>

   可以显示指出c.class_id,c.class_name,s.s_id,s.s_name列明,如果用"*"代替,则mybatis会自动匹配resultMap或者resultType中提供的列名,

     如果某对象存在列映射的属性,但是在select 后面找不到这个列,则在返回结果中,该列多映射的值为null。

  至此,对于一对一、一对多、视图查询都能很好的解决,主要还是要重点关注第四点说明。

      

MyBatis之三:多表联合查询的更多相关文章

  1. Mybatis oracle多表联合查询分页数据重复的问题

    Mybatis oracle多表联合查询分页数据重复的问题 多表联合查询分页获取数据时出现一个诡异的现象:数据总条数正确,但有些记录多了,有些记录却又少了甚至没了.针对这个问题找了好久,最后发现是由于 ...

  2. mybatis Plus 多表联合查询

    //实体类package com.sk.skkill.entity; import com.baomidou.mybatisplus.annotation.TableField;import com. ...

  3. mybatis实现多表联合查询

    本文转自:http://www.cnblogs.com/xdp-gacl/p/4264440.html#!comments 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) ...

  4. MyBatis 多表联合查询及优化 以及自定义返回结果集

    下面就来说一下 mybatis 是通过什么来实现多表联合查询的.首先看一下表关系,如图: 这 里,我已经搭好了开发的环境,用到的是 SpringMVC + Spring + MyBatis,当然,为了 ...

  5. MyBatis 多表联合查询,字段重复的解决方法

    MyBatis 多表联合查询,两张表中字段重复时,在配置文件中,sql语句联合查询时使用字段别名,resultMap中对应的column属性使用相应的别名: <resultMap type=&q ...

  6. mybatis:开发环境搭建--增删改查--多表联合查询(多对一)

    什么是mybatisMyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或 ...

  7. 一步步学Mybatis-实现多表联合查询(4)

    上一章节中我们已经完成了对单表的CRUD操作,接下来今天这一讲讲述的是关于Mybatis在多表查询时候的应用,毕竟实际业务中也是多表的联合查询比较多嘛~ 还记得最一开始我们新建过一张Website表吗 ...

  8. MyBatis 中两表关联查询MYSQL (14)

    MyBatis 中两表关联查询MYSQL 1.创建数据库表语句 2.插入测试数据 3.pom文件内容 <?xml version="1.0" encoding="U ...

  9. yii 多表联合查询的几种方法

    yii多表联合查询, 第一种,用command,自己拼接sql语句执行查询 第二种,用AR,model需继承下面的ar,执行queryall或queryrow方法 <?php //applica ...

随机推荐

  1. eclipse设置自定义快捷键

    eclipse有很多强大且人性化的功能,而各项功能有时又隐藏得比较深(需要点击数次菜单才能找到),而系统提供的快捷键有时比较难记住甚至根本没有提供快捷键时,就需要自己手动设置快捷键了.设置方法有两种, ...

  2. SharePoint 2010遍历文档库中所有的文件,文件夹

    转:http://hi.baidu.com/sygwin/item/f99600849d51a12b110ef3eb 创建一个可视WebPart,并拖放一个label控件到ascx文件上,用于显示结果 ...

  3. ecshop 二次开发及模板标签

    ecs_account_log // 用户账目日志表   ecs_activity // 活动表(代码,名称,开始,结束,描述)   ecs_ad // 广告表(位置,类型,名称,链接,图片,开始,结 ...

  4. 嵌入式 hi3518c下ramdisk文件系统与文件系统烧写以及uboot中change-the-env

    NULL RAM : mkdir ramdisk_test  临时挂在点 dd if=/dev/zero of=123 bs=1k count=10000 建立空硬盘 losetup /dev/loo ...

  5. QC开发只能修改指派给自己的缺陷,而其他的bug可以查看但是不允许修改

    今天在QC9.0项目中增加了几个项目,然后我的想法是:开发只能修改指派给自己的缺陷,而其他的bug可以查看但是不允许修改 虽说qc我还是比较熟悉的,但是对于这个问题,感觉可能要用到脚本,对于脚本我一窍 ...

  6. new trip

    离开YY已经快一周了,特别感谢以前的老大姚冬和朱云峰,从他俩身上学到了很多.这个决定也经过了很长的纠结,不想再做个犹豫不决的人,所以最后还是坚定了最初的信念,也算是对半年前自己的一个完好交代,以防将来 ...

  7. bzoj 2599 [IOI2011]Race (点分治)

    [题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...

  8. [HIve - LanguageManual] XPathUDF

    Documentation for Built-In User-Defined Functions Related To XPath UDFs xpath, xpath_short, xpath_in ...

  9. Codevs No.1553 互斥的数

    2016-05-31 21:34:15 题目链接: 互斥的数 (Codevs No.1553) 题目大意: 给N个数,如果其中两个数满足一个数是另一个的P倍,则称它俩互斥,求一个不互斥集合的最大容量 ...

  10. 【bz2002】弹飞绵羊

    题意: 给出n个节点 及其父亲 和m个指令1:表示求节点i到根节点(n+1)的距离2:表示将节点i的父亲更换为j 题解: 动态树link.cut.access模板题 貌似没什么难度- - 代码: #i ...