一、一对多

1.首先创建数据库和表。两张表的id字段是自动递增的。

给category表录入两条数据,可自行添加记录。
INSERT INTO `category` VALUES (1, '我是分类1');
INSERT INTO `category` VALUES (2, '我是分类2');

INSERT INTO `product` VALUES (1, '我是分类1下的商品1', 999.20, 1);
INSERT INTO `product` VALUES (2, '我是分类1下的第二个商品', 666.30, 1);
INSERT INTO `product` VALUES (3, '我是分类2的第一个商品', 56.30, 2);
INSERT INTO `product` VALUES (4, '我是分类2下的第二个商品', 79.60, 2);

2.使用IDEA创建maven项目。下面一步步创建文件模拟一对多,

项目实现一对多、多以对、多对多最终结构图如下图:

添加依赖和jdk编译版本:

<dependencies><!--数据库连接驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><!--mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.3.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
</dependencies><!--配置编译源代码的jdk版本-->
<build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins>
</build>

3.创建和数据库表对应的pojo。

这个实体中新加了一个数据库没有的字段products,用于存放分类对应的商品集合。public class Category {private int id;private String name;private List<Product> products;public List<Product> getProducts() {return products;}public void setProducts(List<Product> products) {this.products = products;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Category{" +"id=" + id +", name='" + name + '\'' +'}';}
}

这个实体目前还未加新的字段。

public class Product {private int id;private String name;private float price;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public float getPrice() {return price;}public void setPrice(float price) {this.price = price;}@Overridepublic String toString() {return "Product{" +"id=" + id +", name='" + name + '\'' +", price=" + price +'}';}
}

4.创建mybatis的配置文件。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases> <!--设置别名--><package name="com.byh.pojo"/></typeAliases><!--连接数据库--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/dbmybatis?characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="admin"/></dataSource></environment></environments><!--扫描mapper文件--><mappers><mapper resource="mapper/CategoryMapper.xml"/></mappers></configuration>

5.创建CategoryMapper.xml。注意:namespace的值要是对应的mapper接口。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.byh.mapper.CategoryMapper"><resultMap type="Category" id="categoryBean"><id column="cid" property="id" /><result column="cname" property="name" /><!-- 一对多的关系 --><!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 --><collection property="products" ofType="Product"><id column="pid" property="id" /><result column="pname" property="name" /><result column="price" property="price" /></collection></resultMap><!-- 关联查询分类和商品表通过left join关联查询,对Category和Product表进行关联查询。这里不是用的resultType, 而是resultMap,通过resultMap把数据取出来放在对应的对象属性里,通过指定列名映射实体具体的字段赋值。Category的id 字段 和Product的id字段同名,Mybatis不知道谁是谁的,所以需要通过取别名cid,pid来区分。name字段同理。--><select id="list" resultMap="categoryBean">select c.id as 'cid', c.name as 'cname',p.id as 'pid', p.name as 'pname' ,p.pricefromcategory c left join product ponc.id = p.cid</select></mapper>

6.创建CategoryMapper.java接口。

public interface CategoryMapper {List<Category> list();}

7.测试一对多关系。

import com.byh.mapper.CategoryMapper;
import com.byh.pojo.Category;
import com.byh.pojo.Product;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class Demo2 {private SqlSession session;private CategoryMapper categoryMapper;@Beforepublic void bef() throws IOException {//读取mybatis配置文件InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");//构建sqlSession的工厂SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//创建能执行映射文件中sql的sqlSessionsession=sessionFactory.openSession();//获得mappercategoryMapper = session.getMapper(CategoryMapper.class);}@Testpublic void test(){List<Category> list = categoryMapper.list();for(Category c : list){System.out.println(c);List<Product> products = c.getProducts();for(Product product : products){System.out.println("\t"+product);}System.out.println("当前循环结束");}}}

二、多以一

1.接着上面的项目写,在Product.java中添加分类字段:记得都要添加get、set方法。

2.创建ProductMapper.java接口。

package com.byh.mapper;import com.byh.pojo.Product;import java.util.List;public interface ProductMapper {List<Product> productList();
}

3.创建对应的mapper.xml。ProductMapper.xml如下:

注意这里多对一中指定属性类型用的是javaType,跟一对多不一样。namespace中也要指定到对应的mapper接口的完整位置。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byh.mapper.ProductMapper"><resultMap id="productBean" type="Product"><id column="pid" property="id"/><result column="pname" property="name"/><!-- 多以一 --><!-- property: 指的是属性名称, javaType:指的是属性的类型 --><association property="category" javaType="Category"><id column="cid" property="id"/><result column="cname" property="name"/></association></resultMap><select id="productList" resultMap="productBean">select c.id as 'cid', c.name as 'cname',p.id as 'pid', p.name as 'pname' ,p.pricefromcategory c left join product ponc.id = p.cid</select></mapper>

4.测试:在之前的demo中添加ProductMapper。

添加测试方法:

@Test
public void test02(){List<Product> list = productMapper.productList();for(Product p : list){System.out.println(p+"对应的分类:"+p.getCategory());}
}

结果:

三、多对多

1.数据库再新建两张表:

录入模拟多对多的数据:

INSERT INTO `order` VALUES (1, '编号A');
INSERT INTO `order` VALUES (2, '编号B');

INSERT INTO `order_item` VALUES (null, 1, 1, 52);
INSERT INTO `order_item` VALUES (null, 1, 2, 53);
INSERT INTO `order_item` VALUES (null, 1, 3, 54);
INSERT INTO `order_item` VALUES (null, 2, 2, 55);
INSERT INTO `order_item` VALUES (null, 2, 3, 56);
INSERT INTO `order_item` VALUES (null, 2, 4, 57);

2.创建两个实体:Order.java,其中添加了orderItemList字段,表示订单下的订单项。

public class Order {private int id;private String code;//表明订单中有哪些订单项private List<OrderItem> orderItemList;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public List<OrderItem> getOrderItemList() {return orderItemList;}public void setOrderItemList(List<OrderItem> orderItemList) {this.orderItemList = orderItemList;}
}

和OrderItem.java,注意这里跟数据库中有两个字段不一样,这里用的是对应的实体。product、order。

public class OrderItem {private int id;private int number;//这里添加了商品和订单,用于表明一个订单项属于中具体是哪个商品和在哪个订单中private Product product;private Order order;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public Product getProduct() {return product;}public void setProduct(Product product) {this.product = product;}public Order getOrder() {return order;}public void setOrder(Order order) {this.order = order;}
}

3.创建OrderMapper.xml,这里的resultMap我个人觉得绕了一点,但是理清思路也就感觉缺一不可。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byh.mapper.OrderMapper"><!--这里比较绕查询后id和code字段放在Order对象里,然后通过一对多的<collection>标签把oiid和number放在OrderItem对象里,最后把pid,pname,price放进Product对象里--><resultMap id="orderBean" type="Order"><id column="oid" property="id"/><result column="code" property="code"/><!--这里关联订单和所属的订单项的数据 一对多 --><collection property="orderItemList" ofType="OrderItem"><id column="oiid" property="id" /><result column="number" property="number" /><!-- 订单项和商品是多对一 --><association property="product" javaType="Product"><id column="pid" property="id"/><result column="pname" property="name"/><result column="price" property="price"/></association></collection></resultMap><select id="orderList" resultMap="orderBean">select o.id 'oid',o.code, oi.id 'oiid',oi.number, p.name 'pname', p.id 'pid',p.pricefrom `order` oleft join order_item oi on o.id =oi.oidleft join product p on p.id = oi.pid</select></mapper>

4.写对应的order的接口。这里只有一个list的接口。

public interface OrderMapper {List<Order> orderList();}

5.一定要记得把xml文件添加到mybatis的映射文件中,不然会报错。

.

6.测试。在demo2.java中获得ordermapper。并调用orderList方法。

@Test
public void test03(){List<Order> os = orderMapper.orderList();//订单列表for (Order o : os) {System.out.println(o.getCode());//所有订单编号List<OrderItem> ois= o.getOrderItemList();//每个订单下的订单项for (OrderItem oi : ois) {//每个订单项下的商品信息System.out.println("商品:"+oi.getProduct().getName()+"  价格:"+oi.getProduct().getPrice()+"  数量:"+oi.getNumber());}}
}

输出结果:

接下来做添加订单项的准备工作:

1.创建OrderItemMapper.xml,加入增加和删除的查询:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byh.mapper.OrderItemMapper"><insert id="addOrderItem" parameterType="OrderItem">insert into order_item values(null,#{order.id},#{product.id},#{number})</insert><insert id="delOrderItem" parameterType="OrderItem">delete from order_item where oid = #{order.id} and pid = #{product.id}</insert></mapper>

2.创建OrderItemMapper接口。

public interface OrderItemMapper {void addOrderItem(OrderItem orderItem);void delOrderItem(OrderItem orderItem);
}

3.mybatis加入配置文件。

4.OrderMapper.xml加入:

<select id="getOrder" resultMap="orderBean">select o.id 'oid',o.code, oi.id 'oiid',oi.number, p.name 'pname', p.id 'pid',p.pricefrom `order` oleft join order_item oi on o.id =oi.oidleft join product p on p.id = oi.pidwhere o.id=#{id}
</select>
OrderMapper接口中添加方法:

ProductMapper.xml同理:

<select id="getProduct" resultMap="productBean">select c.id as 'cid', c.name as 'cname',p.id as 'pid', p.name as 'pname' ,p.pricefromcategory c left join product ponc.id = p.cidwhere p.id=#{id}
</select>

5.测试添加订单和删除订单:

引入新的mapper:

测试方法:

@Test //添加订单项
public void test04(){order();//调用上面的查询所有订单的方法System.out.println("-----------------------------添加新的订单项后----------------------------:");Product p = productMapper.getProduct(1);Order o = orderMapper.getOrder(2);OrderItem orderItem = new OrderItem();orderItem.setOrder(o);//设置订单项所属订单orderItem.setProduct(p);//订单项所属商品orderItem.setNumber(1001);orderItemMapper.addOrderItem(orderItem);order();//不加这两句 添加的数据是不会应用到数据库的session.commit();session.close();
}@Test
public void del(){order();//调用上面的查询所有订单的方法System.out.println("-----------------------------删除订单项后----------------------------:");Product p = productMapper.getProduct(1);Order o = orderMapper.getOrder(2);OrderItem orderItem = new OrderItem();orderItem.setOrder(o);//设置订单项所属订单orderItem.setProduct(p);//订单项所属商品orderItemMapper.delOrderItem(orderItem);order();session.commit();session.close();
}

最后做一个删除订单就删除对应订单下的订单项的例子:

1.OrderMapper.xml中添加:

<delete id="delOrder" parameterType="int" >delete from order_item where oid = #{id};delete from `order`  where id= #{id};
</delete>

OrderMapper接口中添加:

2.测试方法:

@Test
public void delOrder(){order();//调用上面的查询所有订单的方法orderMapper.delOrder(2);System.out.println("------------删除订单后:订单项也删除了---------------");order();//调用上面的查询所有订单的方法session.commit();session.close();
}

报错:org.apache.ibatis.exceptions.PersistenceException,也就是orderMapper.delOrder(2);这一句调用的时候报错,这是因为这句中我们有两个sql语句。

应该在mybatis的配置文件连接数据库的url属性中加入:&amp;allowMultiQueries=true就可以执行多条sql语句。

再次测试:OK。

Mybatis的一对多、多对一、多对多案例相关推荐

  1. MyBatis→SqlSession、sqlMapConfig.xml、映射XML文件、OGNL、拼接SQL标签、取值查值、批量SQL、一对多多对一多对多

    官网 https://mybatis.org/mybatis-3/ SqlSession sqlMapConfig.xml OGNL XML拼接SQL标签 参数取值 预编译与直接赋值 编码规范 sel ...

  2. MyBatis框架(二):多对一查询、一对多查询、ResultMap、动态SQL

    在mybatis框架下写代码的步骤: 创建实体类 创建对应的接口 写每个接口对应的xml文件 编写测试类 在一对多查询和多对一查询之前,先准备数据库 以老师和学生为例 老师的数据库 CREATE TA ...

  3. MySQL----表的一对多关系和多对多关系

    MySQL----表的一对多关系和多对多关系 1.一对多关系 1.1名词解释: 一对多关系:通过主键外关系,形成一对多关系. 一表:又称之为主表,主表需要提供主键. 多表:又称之为从表,从表需提供外键 ...

  4. Mybatis Plus一对多完整版实战教学!

    Mybatis Plus完整版一对多实战教学! 最近做项目用到了mybatis plus 刚使用确实不是很熟练. 增删改查非常方便,但是然项目中需要用到了一对多的一个查询,我却毫无思路,所以在网上查阅 ...

  5. Mybatis【一对多、多对一、多对多】知识要点

    Mybatis[多表连接] 我们在学习Hibernate的时候,如果表涉及到两张的话,那么我们是在映射文件中使用<set>..<many-to-one>等标签将其的映射属性关联 ...

  6. Mybatis入门---一对多、多对多

    前几天自己配置了Mybatis的高级查询:一对多和多对多,现在记录一下,方便以后用到的时候再回顾,下面是具体的操作步骤 一.首先就是配置Mybatis的xml文件及mapper的xml文件,在这里就不 ...

  7. mybatis的一对多和多对多查询

    一对多和多对多的关系 我是以你平时买东西为例子的,一个用户对应多个订单,一个订单对应多个订单明细,一个订单明细对应一个商品,根据这些关系来进行实例演示. 实例演示 一对多(一个订单对应多个订单明细)  ...

  8. mybatis 一对一、一对多查询、多对多(使用注解)

    1.创建数据库表 职员表: 岗位信息表: 2.创建对应实体类 岗位实体类 package com.hzsh.eomc.common.zhch.nyglgwsb.entity;import java.u ...

  9. mybatis学习5复杂查询之多对一的处理

    前言 众所周知,一个班主任有很多学生,而每个学生只有一个班主任.那么像这种情况出现在数据库里需要怎么处理呢,本文就介绍该如何处理这种复杂查询的情况:这种情况大致分为多对一和一对多两种类型,今天我们就先 ...

最新文章

  1. 全面解析YOLO V4网络结构(附代码讲解)
  2. mysql 配置32g内存_MySQL性能测试 : 新的InnoDB Double Write Buffer
  3. axios取消功能的设计与实现
  4. Python 异步操作文件 aiofiles
  5. jenkins配置ant
  6. android怎么做版本检测,android 实现检测版本,下载apk更新(附源码)
  7. python蓝桥杯跑步训练
  8. 又一个国内知名论坛,突然被全面叫停!
  9. 毕设题目:Matlab通信
  10. 简单控制台项目:电影购票系统
  11. greenplum常用函数
  12. java中榨汁机的代码_《榨汁机食谱大全》(不断更新中)
  13. windows 下vscode coderunner+bash 编程
  14. hl uoj1841 走格子
  15. pe服务器注册表,在PE里如何修改系统注册表?U盘PE下修改本机注册表方法
  16. 原创 | 使用JUnit、AssertJ和Mockito编写单元测试和实践TDD (六)测试哪些内容:Right-BICEP
  17. 小程序报错类—— thirdScriptError sdk uncaught third Error Cannot read property '$mount' of unde
  18. 浅谈因子分析(Factor Analysis)
  19. cocos2d-x 流星划过特效
  20. java手动注册filter,SpringBoot注册Filter的两种实现方式

热门文章

  1. python词云自制壁纸
  2. java swing飞机大战游戏(源码+视频+文档+ppt)
  3. Futter组件整理汇总
  4. “华为杯”研究生数学建模竞赛2020年-【华为杯】A题:ASIC 芯片上的载波恢复 DSP 算法设计与实现(附获奖论文及matlab代码实现)
  5. .NetCore中EFCore for MySql
  6. css实现圆形白底头像框
  7. SAP中工艺路线删除后无法释放组计数器的问题实例
  8. 模糊数学(二):隶属函数的确定
  9. C++OpenCV下绘制灰度直方图
  10. 这些天的生活挺无聊的!