步骤1:定义多对多关系
步骤2: 表结构
步骤3:导入数据
步骤4:先运行,看到效果,再学习
步骤5:模仿和排错
步骤6:实体类
步骤7:映射文件
步骤8:修改mybatis-config.xml
步骤9:查询操作
步骤10:建立关系
步骤11:删除关系
步骤12:修改关系
步骤13:可运行的项目
步骤14:练习-删除订单时,删除对应的订单项
步骤15:答案-删除订单时,删除对应的订单项
步骤 1 : 定义多对多关系
本知识点是基于多对一的基础上进行。
在学习之前首先要理清楚多对多的关系,这里以订单Order和产品Product为例:
一张订单里 可以包含多种产品
一种产品 可以出现在多张订单里
这就是多对多关系
为了维系多对多关系,必须要一个中间表。 在这里我们使用订单项(OrderItem)表来作为中间表
本知识点讲解如何查询多对多关系,建立多对多关系,删除多对多关系。
步骤 2 : 表结构
create table order_ (
id int(11) NOT NULL AUTO_INCREMENT,
code varchar(32) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
create table order_item_(
id int(11) NOT NULL AUTO_INCREMENT,
oid int ,
pid int ,
number int ,
PRIMARY KEY(id)
)AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
步骤 3 : 导入数据
在一对多关系中准备的数据里已经有Product数据里,这里就只准备订单数据和订单项数据:
1. 插入两个订单
2. 插入6条订单项数据,建立如下关系
2.1 订单1对应产品 1,2,3
2.2 订单2对应产品 2,3,4
INSERT INTO order_ VALUES (1,'code000A');
INSERT INTO order_ VALUES (2,'code000B');
INSERT INTO order_item_ VALUES (null, 1, 1, 100);
INSERT INTO order_item_ VALUES (null, 1, 2, 100);
INSERT INTO order_item_ VALUES (null, 1, 3, 100);
INSERT INTO order_item_ VALUES (null, 2, 2, 100);
INSERT INTO order_item_ VALUES (null, 2, 3, 100);
INSERT INTO order_item_ VALUES (null, 2, 4, 100);
|
步骤 4 : 先运行,看到效果,再学习
老规矩,先下载下载区(点击进入)的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
步骤 5 : 模仿和排错
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。
推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
步骤 6 : 实体类
实体类Order和OrderItem
package com.how2java.pojo;
public class OrderItem {
private int id;
private int number;
private Order order;
private Product product;
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 Order getOrder() {
return order;
}
public void setOrder(Order order) {
this .order = order;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this .product = product;
}
}
|
package com.how2java.pojo;
import java.util.List;
public class Order {
private int id;
private String code;
List<OrderItem> orderItems;
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> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this .orderItems = orderItems;
}
}
|
步骤 7 : 映射文件
关于映射文件的sql语句说明在后续测试的时候会讲解
<? 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.how2java.pojo" >
< resultMap type = "Order" id = "orderBean" >
< id column = "oid" property = "id" />
< result column = "code" property = "code" />
< collection property = "orderItems" 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 = "listOrder" resultMap = "orderBean" >
select o.*,p.*,oi.*, o.id 'oid', p.id 'pid', oi.id 'oiid', p.name 'pname'
from order_ o
left join order_item_ oi on o.id =oi.oid
left join product_ p on p.id = oi.pid
</ select >
< select id = "getOrder" resultMap = "orderBean" >
select o.*,p.*,oi.*, o.id 'oid', p.id 'pid', oi.id 'oiid', p.name 'pname'
from order_ o
left join order_item_ oi on o.id =oi.oid
left join product_ p on p.id = oi.pid
where o.id = #{id}
</ 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 = "com.how2java.pojo" >
< resultMap type = "Product" id = "productBean" >
< id column = "pid" property = "id" />
< result column = "pname" property = "name" />
< result column = "price" property = "price" />
<!-- 多对一的关系 -->
<!-- property: 指的是属性名称, javaType:指的是属性的类型 -->
< association property = "category" javaType = "Category" >
< id column = "cid" property = "id" />
< result column = "cname" property = "name" />
</ association >
</ resultMap >
< select id = "listProduct" resultMap = "productBean" >
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname'
from category_ c
left join product_ p on c.id = p.cid
</ select >
< select id = "getProduct" resultMap = "productBean" >
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname'
from category_ c
left join product_ p on c.id = p.cid
where p.id = #{id}
</ 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 = "com.how2java.pojo" >
< insert id = "addOrderItem" parameterType = "OrderItem" >
insert into order_item_
values(null,#{order.id},#{product.id},#{number})
</ insert >
< insert id = "deleteOrderItem" parameterType = "OrderItem" >
delete from order_item_
where oid = #{order.id} and pid = #{product.id}
</ insert >
</ mapper >
|
步骤 8 : 修改mybatis-config.xml
添加对于Order.xml和OrderItem的映射
<?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>
<typeAliases>
< package name= "com.how2java.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/how2java?characterEncoding=UTF-8" />
<property name= "username" value= "root" />
<property name= "password" value= "admin" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource= "com/how2java/pojo/Category.xml" />
<mapper resource= "com/how2java/pojo/Product.xml" />
<mapper resource= "com/how2java/pojo/Order.xml" />
<mapper resource= "com/how2java/pojo/OrderItem.xml" />
</mappers>
</configuration>
|
步骤 9 : 查询操作
如图所示,查询出所有的订单,然后遍历每个订单下的多条订单项,以及订单项对应的产品名称,价格,购买数量
通过Order.xml的listOrder对应的sql语句进行查询:
<select id= "listOrder" resultMap= "orderBean" >
select o.*,p.*,oi.*, o.id 'oid' , p.id 'pid' , oi.id 'oiid' , p.name 'pname'
from order_ o
left join order_item_ oi on o.id =oi.oid
left join product_ p on p.id = oi.pid
</select>
|
联合order_, order_item_, product_ 三张表进行查询
<resultMap type= "Order" id= "orderBean" >
<id column= "oid" property= "id" />
<result column= "code" property= "code" />
<collection property= "orderItems" 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>
|
查询结果 id和code字段放在Order对象里, 然后通过一对多的<collection>标签把oiid和number放在OrderItem对象里,最后把pid,pname,price放进Product对象里。
package com.how2java;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 com.how2java.pojo.Order;
import com.how2java.pojo.OrderItem;
import com.how2java.pojo.Product;
public class TestMybatis {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml" ;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
listOrder(session);
session.commit();
session.close();
}
private static void listOrder(SqlSession session) {
List<Order> os = session.selectList( "listOrder" );
for (Order o : os) {
System.out.println(o.getCode());
List<OrderItem> ois= o.getOrderItems();
for (OrderItem oi : ois) {
System.out.format( " %s %f %d%n" , oi.getProduct().getName(),oi.getProduct().getPrice(),oi.getNumber());
}
}
}
}
|
步骤 10 : 建立关系
如图所示,建立了让订单000A和产品z建立了关系
首先通过id分别获取Order对象和Product对象,然后创建一个新的OrderItem对象,接着设置Order,设置Product,设置数量,最后调用"addOrderItem" 对应的sql语句插入数据。
Order o1 = session.selectOne( "getOrder" , 1 );
Product p6 = session.selectOne( "getProduct" , 6 );
OrderItem oi = new OrderItem();
oi.setProduct(p6);
oi.setOrder(o1);
oi.setNumber( 200 );
session.insert( "addOrderItem" , oi);
|
addOrderItem调用insert into 语句插入一条OrderItem记录
<insert id= "addOrderItem" parameterType= "OrderItem" >
insert into order_item_
values( null ,#{order.id},#{product.id},#{number})
</insert>
|
package com.how2java;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 com.how2java.pojo.Order;
import com.how2java.pojo.OrderItem;
import com.how2java.pojo.Product;
public class TestMybatis {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml" ;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
addOrderItem(session);
listOrder(session);
session.commit();
session.close();
}
private static void addOrderItem(SqlSession session) {
Order o1 = session.selectOne( "getOrder" , 1 );
Product p6 = session.selectOne( "getProduct" , 6 );
OrderItem oi = new OrderItem();
oi.setProduct(p6);
oi.setOrder(o1);
oi.setNumber( 200 );
session.insert( "addOrderItem" , oi);
}
private static void listOrder(SqlSession session) {
List<Order> os = session.selectList( "listOrder" );
for (Order o : os) {
System.out.println(o.getCode());
List<OrderItem> ois = o.getOrderItems();
for (OrderItem oi : ois) {
System.out.format( " %s %f %d%n" , oi.getProduct().getName(), oi.getProduct().getPrice(),
oi.getNumber());
}
}
}
}
|
步骤 11 : 删除关系
如图所示,删除了订单00A和产品z的关系,再次查询,就看不到产品z了。
删除关系的时候,通过订单id(1)和产品id(6)进行删除。
其实所谓的删除关系,就是删除掉OrderItem记录。
package com.how2java;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 com.how2java.pojo.Order;
import com.how2java.pojo.OrderItem;
import com.how2java.pojo.Product;
public class TestMybatis {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml" ;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
deleteOrderItem(session);
// addOrderItem(session);
listOrder(session);
session.commit();
session.close();
}
private static void deleteOrderItem(SqlSession session) {
Order o1 = session.selectOne( "getOrder" , 1 );
Product p6 = session.selectOne( "getProduct" , 6 );
OrderItem oi = new OrderItem();
oi.setProduct(p6);
oi.setOrder(o1);
session.delete( "deleteOrderItem" , oi);
}
private static void addOrderItem(SqlSession session) {
Order o1 = session.selectOne( "getOrder" , 1 );
Product p6 = session.selectOne( "getProduct" , 6 );
OrderItem oi = new OrderItem();
oi.setProduct(p6);
oi.setOrder(o1);
oi.setNumber( 200 );
session.insert( "addOrderItem" , oi);
}
private static void listOrder(SqlSession session) {
List<Order> os = session.selectList( "listOrder" );
for (Order o : os) {
System.out.println(o.getCode());
List<OrderItem> ois= o.getOrderItems();
for (OrderItem oi : ois) {
System.out.format( " %s %f %d%n" , oi.getProduct().getName(),oi.getProduct().getPrice(),oi.getNumber());
}
}
}
}
|
步骤 12 : 修改关系
多对多不存在修改关系的做法,就是删除旧的,然后新增一条即达到修改的效果。
步骤 13 : 可运行的项目
在下载区(点击进入)有本知识点对应的可运行项目下载
更多内容,点击了解: https://how2j.cn/k/mybatis/mybatis-many-to-many/1091.html