首页 > 代码库 > MyBatis中多对多关系的映射和查询

MyBatis中多对多关系的映射和查询

先说一下需求:

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

 

创建表:

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

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

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

 

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

create table book(    bid int primary key auto_increment,    bname varchar(20)                                     );

建立类别表(类别编号,类别名字)

create table category(    cid int primary key auto_increment,    cname varchar(20));

建立中间表(图书编号,类别编号)

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对比);insert into middle values (1,3);insert into middle values (2,1);insert into middle values (2,3);insert into middle values (3,2);insert into middle values (3,1);

插入的数据中,第一本书 有一个类别,第二本书和第三本书都有两个类别

到现在为止,数据库的事情就完事了。下面,通过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 binner join      middle mon    b.bid=m.m_bidinner join    category con    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中多对多关系的映射和查询