一、Mybatis的多对多映射

  本例讲述使用mybatis开发过程中常见的多对多映射查询案例。只抽取关键代码和mapper文件中的关键sql和配置,详细的工程搭建和Mybatis详细的流程代码可参见《Mybatis入门和简单Demo》和《Mybatis的CRUD案例

  完整的工程代码已上传至https://files.cnblogs.com/files/jiyukai/MyBatis.zip

  案例:查询xx同学所选择的多个不同选修课,查询xx选修课被多少同学选修

  步骤1.建表脚本,分别创建学生表,课程表,以及学生课程表,作为学生关系到课程的中间关联表。

create table students(
sid int(5) primary key,
sname varchar(10)
);
create table courses(
cid int(5) primary key,
cname varchar(10)
);
create table course_stu(
sid int(5),
cid int(5),
primary key(sid,cid)
);
insert into students(sid,sname) values(1,'cat');
insert into students(sid,sname) values(2,'dog');
insert into courses(cid,cname) values(1,'java');
insert into courses(cid,cname) values(2,'net');
insert into course_stu(sid,cid) values(1,1);
insert into course_stu(sid,cid) values(1,2);
insert into course_stu(sid,cid) values(2,1);
insert into course_stu(sid,cid) values(2,2);

  步骤2.编写课程和学生实体类,学生可选择多门课程,课程中有多个学生,因此在各自的实体类中都以集合的形式引入对方

package com.jyk.mybatis.moreTomore;

import java.util.ArrayList;
import java.util.List; public class Course {
private Integer id; //课程id
private String name; //课程名称
private List<Student> studentList = new ArrayList<Student>(); //对应的学生名称
public Course(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
}
package com.jyk.mybatis.moreTomore;

import java.util.ArrayList;
import java.util.List; public class Student {
private Integer id; //学生id
private String name; //学生姓名
private List<Course> courseList = new ArrayList<Course>(); //选修的课程
public Student(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Course> getCourseList() {
return courseList;
}
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
}

  步骤3.编写mapper文件,在CourseMapper.xml中编写课程信息表字段与实体属性的映射关系,在StudentMapper.xml中编写学生实体和表字段的映射关系,并编写好根据学生姓名查询所有选修课程,以及根据选修课名称查询有多少学生的SQL,并将mapper文件和对应实体类的别名加入mybatis.xml(mybatis.xml的描述见Mybatis系列第一篇博客,此处由于配置type时指定了类的全路径,故无需将别名加入至mybatis.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="studentNamespace">
<resultMap type="com.jyk.mybatis.moreTomore.Student" id="studentMap">
<id property="id" column="sid" />
<result property="name" column="sname"/>
</resultMap> <!-- 查询java课程有哪些学生 -->
<select id="findStudentByName" parameterType="string" resultMap="studentMap">
select s.sid,s.sname
from students s,course_stu m,courses c
where s.sid = m.sid
and m.cid = c.cid
and c.cname = #{name}
</select>
</mapper>
<?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="courseNamespace">
<resultMap type="com.jyk.mybatis.moreTomore.Course" id="courseMap">
<id property="id" column="cid" />
<result property="name" column="cname"/>
</resultMap> <!-- 查询cat选学的课程 -->
<select id="findCourseByName" parameterType="string" resultMap="courseMap">
select c.cid,c.cname
from students s,course_stu m,courses c
where s.sid = m.sid
and m.cid = c.cid
and s.sname = #{name}
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 加载类路径下的属性文件 -->
<properties resource="db.properties">
</properties> <!-- 设置类型别名 -->
<typeAliases> </typeAliases> <!-- 设置一个默认的连接环境信息 -->
<environments default="mysql_env">
<!-- 连接环境信息,取一个唯一的编号 -->
<environment id="mysql_env">
<!-- mybatis使用的jdbc事务管理方式 -->
<transactionManager type="jdbc">
</transactionManager> <!-- mybatis使用连接池方式来获取链接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的四个属性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments> <mappers>
<mapper resource="com/jyk/mybatis/moreTomore/CourseMapper.xml"/>
<mapper resource="com/jyk/mybatis/moreTomore/StudentMapper.xml"/>
</mappers> </configuration>

  步骤4.编写Java代码实现该多对多查询,需要注意的是,区分于一对一查询,此处由于查询的结果有多个,是集合的形式返回,故查询的API应使用SqlSession提供的selectList接口而不再是selectOne。

package com.jyk.mybatis.moreTomore;

import java.util.List;
import org.apache.ibatis.session.SqlSession; import com.jyk.mybatis.util.MyBatisUtil; public class StudentCourseDao {
/**
* 查询cat选学的课程
*/
public List<Course> findCourseByName(String name) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MyBatisUtil.getSqlSession();
return sqlSession.selectList("courseNamespace.findCourseByName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MyBatisUtil.closeSqlSession();
}
}
/**
* 查询java课程有哪些学生
*/
public List<Student> findStudentByName(String name) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MyBatisUtil.getSqlSession();
return sqlSession.selectList("studentNamespace.findStudentByName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MyBatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentCourseDao dao = new StudentCourseDao();
List<Course> courseList = dao.findCourseByName("cat");
for(Course c : courseList){
System.out.println(c.getId()+":"+c.getName());
}
/*List<Student> studentList = dao.findStudentByName("java");
for(Student s : studentList){
System.out.println(s.getId()+":"+s.getName());
}*/
}
}

Mybatis的多对多映射的更多相关文章

  1. 【Mybatis高级映射】一对一映射、一对多映射、多对多映射

    前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...

  2. mybatis入门_一对多,多对多映射以及整合spring框架

    一.一对多映射. 1.1 一对多映射之根据多的一方关联查询一的一方 示例:查询出具体的订单信息,同时也查询出来订单的用户信息. 引入的订单表如下所示: 框选出来的为具体的外键. 订单的Pojo类如下所 ...

  3. Mybatis(四) 高级映射,一对一,一对多,多对多映射

    天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种 ...

  4. 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多

    学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...

  5. java web(六):mybatis之一对一、一对多、多对多映射

    前言: 百度百科: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...

  6. Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射

    一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...

  7. MyBatis学习(七)MyBatis关联映射之多对多映射

    对于数据库中的多对多关系建议使用一个中间表来维护关系. 1.创建四张表,分别为用户表,商品表,订单表,中间表. DROP TABLE IF EXISTS `t_user`; CREATE TABLE ...

  8. mybatis标签之——关联映射

    关联关系是面向对象分析.面向对象设计最重要的知识.合理的关联映射将大大简化持久层数据的访问.关联关系大致分为以下三类: 一对一 一对多 多对多 1. 一对一 一对一关系推荐使用唯一主外键关联,即两张表 ...

  9. 转:Mybatis系列之集合映射

    转:Mybatis系列之集合映射 上篇文章我们讲了关联映射,实现了销售与登录用户之间的关联.本文我们接着来讲一讲集合映射,实现销售与客户的多对多关系. 实现销售与客户多对多关系 本文中仍延用<M ...

随机推荐

  1. 【存储过程】用SQL语句获得一个存储过程返回的表

    定义一个存储过程如下: create proc [dbo].[test1] @id int as select 1 as id,'abc' as name union all select @id a ...

  2. 【API设计】RESTful API 设计指南

    RESTful API URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作. 例如 . REST描述的是在网络中client和server的一种交互形式:REST本身不 ...

  3. liunx trac 插件使用之GanttCalendarPlugin

    http://trac-hacks.org/wiki/GanttCalendarPlugin官网上的说明很清楚,处理做几点提示,以做记录. 1.我的Trac版本是1.0.1 我使用了'B' Metho ...

  4. Android Studio 3.1.2 版本包下载

    Android Studio 3.1.2 bug 修复版已发布,本次更新修复了一些错误,并改进了某些场景下 lint 审查的速度.详细的修复内容请查看 Android Studio 3.1.2 的发布 ...

  5. telnet命令的使用方法

    大家都知道,Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成远程主机工作的能力.在终端使用者的电脑上使用telnet程 ...

  6. Nexus网页直接上传jar包

    登陆已经安装好的nexus私有仓库,如图:   点击左边菜单“Repositories”,选择右边列表“3rd party“   点击“3rd party”,选择artifact Upload,如下图 ...

  7. C# 日志系统 log4net 配置及使用

    1.引用Dll 版本是:1.2.10.0,下载Dll 2.Web.config文件配置 <?xml version="1.0" encoding="utf-8&qu ...

  8. Yet another way to manage your NHibernate ISessionFactory

    So here is my current UnitOfWork implementation.  This one makes use of the somewhat new current_ses ...

  9. 【CF865C】Gotta Go Fast 二分+期望DP

    [CF865C]Gotta Go Fast 题意:有n个关卡需要依次通过,第i关有pi的概率要花ai时间通过,有1-pi的概率要花bi时间通过,你的目标是花费不超过m的时间通关,每一关开始时你都可以选 ...

  10. Thinkphp 验证码点击刷新解决办法

    HTML代码如下: <span> <input type="text" name="code" placeholder="验证码&q ...