步骤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,4INSERT 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
- OrderItem.java
- Order.java
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语句说明在后续测试的时候会讲解
- Order.xml
- Product.xml
- OrderItem.xml
<?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 =
newSqlSessionFactoryBuilder().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("t%st%ft%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 =
newSqlSessionFactoryBuilder().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("t%st%ft%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 =
newSqlSessionFactoryBuilder().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("t%st%ft%d%n", oi.getProduct().getName(),oi.getProduct().getPrice(),oi.getNumber());
}
}
}
}
步骤 12 : 修改关系
多对多不存在修改关系的做法,就是删除旧的,然后新增一条即达到修改的效果。步骤 13 : 可运行的项目
在下载区(点击进入)有本知识点对应的可运行项目下载
更多内容,点击了解: https://how2j.cn/k/mybatis/mybatis-many-to-many/1091.html