MyBatis中多对多关系的映射和查询
先说一下需求:
在页面上显示数据库中的所有图书,显示图书的同时,显示出该图书所属的类别(这里一本书可能同时属于多个类别)
创建表:
笔者这里使用 中间表 连接 图书表 和 图书类别表,图书表中 没有使用外键关联 图书类别表
而是在中间表中引用了 图书主键 和 类别主键
通过中间表来 表示 图书 和 图书类别 的关系
建立图书表(图书编号,图书名字)
create table book
(
bid int primary key auto_increment,
bname )
);
建立类别表(类别编号,类别名字)
create table category
(
cid int primary key auto_increment,
cname )
);
建立中间表(图书编号,类别编号)
create table middle
(
m_bid int,
m_cid int,
constraint fk_bid foreign key(m_bid) references book(bid),
constraint fk_cid foreign key(m_cid) references category(cid)
);
插入测试数据
insert into category values (default,'java'); insert into category values (default,'c++'); insert into category values (default,'mysql'); insert into book values (default,'SQL技术'); insert into book values (default,'SSM+MySQL详解'); insert into book values (default,'C++和java对比'); ,); ,); ,); ,); ,);
插入的数据中,第一本书 有一个类别,第二本书和第三本书都有两个类别
到现在为止,数据库的事情就完事了。下面,通过MyBatis-Generator生成实体类、DAO接口、XML映射文件 不会点击这里
为了方便省事,笔者这里通过Java项目演示,将自动生成的文件 放入新建的Java项目中,导入相关的Jar包,项目结构 如下图

现在我们打开生成的 图书实体类 看一下
public class Book {
private Integer bid;
private String bname;
public Integer getBid() {
return bid;
}
public void setBid(Integer bid) {
this.bid = bid;
}
public String getBname() {
return bname;
}
public void setBname(String bname) {
this.bname = bname == null ? null : bname.trim();
}
}
只有图书编号、图书名字 这两个属性,而我们的需求是 得到图书的同时,得到该图书所属的 所有类别, 所以 我们可以考虑 给图书实体类 添加 一个 图书类别的集合
修改后的图书实体类 如下
public class Book {
private Integer bid;
private String bname;
private List<Category> categories;
public Integer getBid() {
return bid;
}
public void setBid(Integer bid) {
this.bid = bid;
}
public String getBname() {
return bname;
}
public void setBname(String bname) {
this.bname = bname == null ? null : bname.trim();
}
public List<Category> getCategories() {
return categories;
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
}
下面 我们开始写SQL语句,他们通过连接查询 查出所有的图书和图书类别
select
*
from
book b
inner join
middle m
on
b.bid=m.m_bid
inner join
category c
on
m.m_cid=c.cid
执行结果如下 完美的显示了所有图书 和 该图书的类别

下面 我们就在XML映射文件中动手脚,使得 这些数据 能按我们所期望的 自动填充到 图书实体类中
这里为突出重点 所以将图书的映射文件和DAO接口 清空,清空后 如下
<?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.dao.BookMapper" >
<select id="queryAll">
</select>
</mapper>
public interface BookMapper {
List<Book> queryAll();
}
清空后 我们开始编写,编写结果如下
<?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.dao.BookMapper" >
<resultMap type="com.mybatis.entity.Book" id="bookMap">
<id property="bid" column="bid" />
<result property="bname" column="bname" />
<collection property="categories" ofType="com.mybatis.entity.Category">
<id property="cid" column="cid" />
<result property="cname" column="cname" />
</collection>
</resultMap>
<select id="queryAll" resultMap="bookMap">
select
*
from
book b
inner join
middle m
on
b.bid=m.m_bid
inner join
category c
on
m.m_cid=c.cid
</select>
</mapper>
最后我们 编写main方法测试
public class MyMain {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = factory.openSession();
BookMapper bookMapper = session.getMapper(BookMapper.class);
for (Book book : bookMapper.queryAll()) {
System.out.print("["+book.getBname()+"]");
for(Category category :book.getCategories()){
System.out.print(category.getCname()+"\t");
}
System.out.println("\n");
}
}
}
测试结果如下图

成功输出了 所有图书 和 对应的图书类别
完整项目下载:点击下载
笔者能力有限,有哪些可以改进或者不对的地方欢迎提出!
MyBatis中多对多关系的映射和查询的更多相关文章
- 关于hibernate中多对多关系
关于多对多关系 数据库:在使用多对多的关系时,我们能够使用复合主键.也能够不使用,直接引入外键相同能够实现. 在数据库中使用多对多关系时,须要一个中间表. 多对多关系中的数据库结构例如以下: 表:Or ...
- Django中多对多关系的orm表设计
作者的管理 1.设计表结构 出版社 书籍 作者 一个出版社出版多个书籍 1对多 书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写.多对多 1)创建一张表,表中多对多的数据关系.使用 多对多 ...
- 如何决解项目中hibernate中多对多关系中对象转换json死循环
先写一下原因吧!我是写的SSH项目,在项目中我遇到的问题是把分页对象(也就是pageBean对象)转化为json数据,下面为代码: public class PageBean <T>{// ...
- hibernate 中多对多关系对象集合的保存
多对多关系映射和一对多关系映射开发步骤差不多, 例子如下:员工和项目之间的关系,一个员工可以参与多个项目:一个项目可以有多个开发人员参与.因此是多对多的关系. 1 分析数据表 1.1)员工表 CREA ...
- XAF中多对多关系 (XPO)
In this lesson, you will learn how to set relationships between business objects. For this purpose, ...
- MyBatis中动态SQL语句完成多条件查询
一看这标题,我都感觉到是mybatis在动态SQL语句中的多条件查询是多么的强大,不仅让我们用SQL语句完成了对数据库的操作:还通过一些条件选择语句让我们SQL的多条件.动态查询更加容易.简洁.直观. ...
- mybatis中xml字段空判断及模糊查询
由于业务特殊的查询需求,需要下面的这种查询,一直感觉模糊不清,本地测试一下顺便做个总结 贴一段xml代码,如下: <if test="receivedName != null and ...
- MyBatis中jdbcType和javaType的映射关系
JDBC Type Java Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIM ...
- (六)mybatis之多对一关系(简单)
一.需求分析 需求: 查询所有订单信息及订单下的订单明细信息 分析: 一条订单只能由一个消费者下单,但是一条订单有多条订单明细. 二.创建数据库表和实体对象 Customer.java ...
随机推荐
- Ubuntu Server 重启 Apache Mysql
a. 重启 apache sudo service apache2 restart b. 重启 MySQL sudo service mysql restart
- windows矢量字体点阵数据的提取(转)
源:windows矢量字体点阵数据的提取 问题参考:windows api 获取字库点阵的问题 1.提取原理 在windows系统当中提取矢量字体的字模有很多方法,下面介绍一种利用GetGlyphOu ...
- HDU 5616 Jam's balance
背包.dp[i]=1表示i这种差值能被组合出来,差值有负数,所以用sum表示0,0表示-sum,2*sum表示sum. 询问X的时候,只需看dp[sum+X]或者dp[sum-X]是否有一个为1,注意 ...
- MediaScanner
http://blog.csdn.net/hellofeiya/article/details/8255898 http://www.cnblogs.com/halzhang/archive/2011 ...
- Cordova3+sencha touch2.x 环境搭建
1.安装 nodejs 2.安装 cordova: npm install -g cordova 3.创建一个工程: cordova create MyApp com.example.MyApp My ...
- 系统管理员必须掌握的20个Linux监控工具
需要监控Linux服务器系统性能吗?尝试下面这些系统内置或附件的工具吧.大多数Linux发行版本都装备了大量的监控工具.这些工具提供了能用 作取得相关信息和系统活动的量度指标.你能使用这些工具发现造成 ...
- Delphi中unicode转汉字函数(转)
源:Delphi中unicode转汉字函数 近期用到这个函数,无奈没有找到 delphi 自带的,网上找了下 有类似的,没有现成的,我需要的是 支持 “\u4f00 ” 这种格式的,即前面带标准的 “ ...
- Cdoefroces #354
A题 题意:给定一些数,然后求一次交换以后最大的数和最小的数之间的最大距离 分析:找到最大数和最小数的位置,然后判断是把位置大的移到最后还是把位置小的移到开始位置即可 #include <ios ...
- USB自定义HID设备实现-STM32
该文档使用USB固件库,在其基础上进行了自己的定制,完成了一个USB-HID设备,首先是usb_desc.c文件,里面存放了usb各种描述符的存在 #include "usb_desc.h& ...
- FZU 1064 教授的测试
递归构造答案. 根据当前整颗树的编号,可以计算左右子树有几个节点以及编号.因此,不断dfs下去就可以了. #include<cstdio> #include<cstring> ...