先说一下需求:

  在页面上显示数据库中的所有图书,显示图书的同时,显示出该图书所属的类别(这里一本书可能同时属于多个类别)

创建表:

  笔者这里使用 中间表 连接 图书表 和 图书类别表,图书表中 没有使用外键关联 图书类别表

  而是在中间表中引用了 图书主键 和 类别主键

  通过中间表来 表示 图书 和 图书类别 的关系

建立图书表(图书编号,图书名字)

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中多对多关系的映射和查询的更多相关文章

  1. 关于hibernate中多对多关系

    关于多对多关系 数据库:在使用多对多的关系时,我们能够使用复合主键.也能够不使用,直接引入外键相同能够实现. 在数据库中使用多对多关系时,须要一个中间表. 多对多关系中的数据库结构例如以下: 表:Or ...

  2. Django中多对多关系的orm表设计

    作者的管理 1.设计表结构 出版社 书籍 作者 一个出版社出版多个书籍  1对多 书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写.多对多 1)创建一张表,表中多对多的数据关系.使用 多对多 ...

  3. 如何决解项目中hibernate中多对多关系中对象转换json死循环

    先写一下原因吧!我是写的SSH项目,在项目中我遇到的问题是把分页对象(也就是pageBean对象)转化为json数据,下面为代码: public class PageBean <T>{// ...

  4. hibernate 中多对多关系对象集合的保存

    多对多关系映射和一对多关系映射开发步骤差不多, 例子如下:员工和项目之间的关系,一个员工可以参与多个项目:一个项目可以有多个开发人员参与.因此是多对多的关系. 1 分析数据表 1.1)员工表 CREA ...

  5. XAF中多对多关系 (XPO)

    In this lesson, you will learn how to set relationships between business objects. For this purpose, ...

  6. MyBatis中动态SQL语句完成多条件查询

    一看这标题,我都感觉到是mybatis在动态SQL语句中的多条件查询是多么的强大,不仅让我们用SQL语句完成了对数据库的操作:还通过一些条件选择语句让我们SQL的多条件.动态查询更加容易.简洁.直观. ...

  7. mybatis中xml字段空判断及模糊查询

    由于业务特殊的查询需求,需要下面的这种查询,一直感觉模糊不清,本地测试一下顺便做个总结 贴一段xml代码,如下: <if test="receivedName != null and ...

  8. MyBatis中jdbcType和javaType的映射关系

    JDBC Type Java Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIM ...

  9. (六)mybatis之多对一关系(简单)

    一.需求分析 需求:   查询所有订单信息及订单下的订单明细信息 分析:      一条订单只能由一个消费者下单,但是一条订单有多条订单明细. 二.创建数据库表和实体对象 Customer.java ...

随机推荐

  1. 一道题看懂OC的文件管理:NSFileManager,计算文件包含内存大小

    计算文件夹下所有文件的大小 // 查看错误信息 __autoreleasing NSError *error; // 文件管理对象 NSFileManager *manager = [NSFileMa ...

  2. MySQL查询in操作 查询结果按in集合顺序显示_Mysql_脚本之家

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  3. mysql基础-- 一条请求执行多条SQL语句

    最近做一个数据库初始化工具的时候发现了这个问题,就是在一个Statement中执行一条SQL语句的时候可以正确执行,如果同时执行多条,就会报SQL语法错误,伤透了脑筋. 经过网上查找,发现有两种解决办 ...

  4. CodeForces 622D Optimal Number Permutation

    是一个简单构造题. 请观察公式: 绝对值里面的就是 |di-(n-i)|,即di与(n-i)的差值的绝对值. 事实上,对于任何n,我们都可以构造出来每一个i的di与(n-i)的差值为0. 换句话说,就 ...

  5. iOS HTTP不能正常使用

  6. 6、手把手教你Extjs5(六)继承自定义一个控件

    Extjs的开发都可以遵循OOP的原则,其对类的封装也很完善了.自定义一个控件最简单的办法就是继承一个已有的控件.根据上一节的需要,我做了一个Button的子类.首先根据目录结构,在app目录下建立一 ...

  7. Spring接口编程_设值注入和构造注入

    说明: UserManagerImp是设值注入,UserManagerImp2是构造注入 接口不注入,也就是在Spring配置文件中没有接口的<bean>,但是定义的时候是用接口 priv ...

  8. Apache 代理(Proxy) 转发请求

    代理分为:正向代理(Foward Proxy)和反向代理(Reverse Proxy) 1.正向代理(Foward Proxy) 正向代理(Foward Proxy)用于代理内部网络对Internet ...

  9. struts2默认Action配置

    在项目中,需要在输入错误的url的时候,弹出友好的错误提示页面 在struts2中可以通过配置默认的action达到这个目的 配置方法: <package name="default& ...

  10. React Native 之 搭建开发环境

    现在只能在MAC系统上安装. 1. 首先,HomeBrew 这是一个包管理库,用来下载其它工具. 打开网站:brew.sh 网页有个命令 /usr/bin/ruby -e "$(curl - ...