项目开发中,多对多关系也是非常常见的关系

在数据库中创建表的脚本

table.sql

 CREATE TABLE tb_user(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(18),
loginname VARCHAR(18),
PASSWORD VARCHAR(18),
phone VARCHAR(18),
address VARCHAR(18)
); INSERT INTO tb_user(username,loginname,PASSWORD,phone,address)
VALUES('杰克','jack','123456','13920001616','广州'); CREATE TABLE tb_article(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
price DOUBLE,
remark VARCHAR(18)
); INSERT INTO tb_article(NAME,price,remark)
VALUES('疯狂Java讲义',108.9,'李刚老师经典著作');
INSERT INTO tb_article(NAME,price,remark)
VALUES('疯狂Android讲义',99.9,'李刚老师经典著作');
INSERT INTO tb_article(NAME,price,remark)
VALUES('疯狂iOS讲义',89.9,'李刚老师经典著作');
INSERT INTO tb_article(NAME,price,remark)
VALUES('SpringMVC+MyBatis企业开发',69.9,'肖文吉老师经典著作'); CREATE TABLE tb_order(
id INT PRIMARY KEY AUTO_INCREMENT,
CODE VARCHAR(32),
total DOUBLE,
user_id INT,
FOREIGN KEY (user_id) REFERENCES tb_user(id)
); INSERT INTO tb_order(CODE,total,user_id)
VALUES('6aa3fa359ff14619b77fab5990940a2d',388.6,1); INSERT INTO tb_order(CODE,total,user_id)
VALUES('6aa3fa359ff14619b77fab5990940b3c',217.8,1); CREATE TABLE tb_item(
order_id INT,
article_id INT,
amount INT,
PRIMARY KEY(order_id,article_id),
FOREIGN KEY (order_id) REFERENCES tb_order(id),
FOREIGN KEY (article_id) REFERENCES tb_article(id)
); INSERT INTO tb_item(order_id,article_id,amount)
VALUES(1,1,1);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(1,2,1);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(1,3,2); INSERT INTO tb_item(order_id,article_id,amount)
VALUES(2,4,2);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(2,1,1);

接下来创建一个User类,Article和一个Order类来映射数据库中的表

用户和订单是一对多的关系,即一个用户可以有多个订单,在User类中定义一个orders属性,该属性是一个List集合,用来映射一对多的关联关系

订单与用户是多对一的关系,一个订单只是属于一个用户,在Order类中定义一个user属性,用来映射多对一的关联关系

商品和订单是多对多的关系,即一种商品可以出现在多个订单中,在Article类中定义一个orders属性,该属性是一个List集合,用来映射多对多的关联关系,表示该商品关联的多个订单

Article.java

public class Article implements Serializable {

	private Integer id;		// 商品id,主键
private String name; // 商品名称
private Double price; // 商品价格
private String remark; // 商品描述 // 商品和订单是多对多的关系,即一种商品可以包含在多个订单中
private List<Order> orders;
}

Order.java

public class Order implements Serializable {

	private Integer id;  // 订单id,主键
private String code; // 订单编号
private Double total; // 订单总金额 // 订单和用户是多对一的关系,即一个订单只属于一个用户
private User user; // 订单和商品是多对多的关系,即一个订单可以包含多种商品
private List<Article> articles;
}

User.java

public class User implements Serializable{

	private Integer id;  // 用户id,主键
private String username; // 用户名
private String loginname; // 登录名
private String password; // 密码
private String phone; // 联系电话
private String address; // 收货地址 // 用户和订单是一对多的关系,即一个用户可以有多个订单
private List<Order> orders;

xml文件配置

ArticleMapper.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">
<!-- namespace指用户自定义的命名空间。 -->
<mapper namespace="com.rookie.bigdata.mapper.ArticleMapper"> <select id="selectArticleByOrderId" parameterType="int"
resultType="com.rookie.bigdata.domain.Article">
SELECT * FROM tb_article WHERE id IN (
SELECT article_id FROM tb_item WHERE order_id = #{id}
)
</select> </mapper>

OrderMapper.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">
<!-- namespace指用户自定义的命名空间。 -->
<mapper namespace="com.rookie.bigdata.mapper.OrderMapper"> <resultMap type="com.rookie.bigdata.domain.Order" id="orderResultMap">
<id property="id" column="oid"/>
<result property="code" column="code"/>
<result property="total" column="total"/>
<!-- 多对一关联映射:association -->
<association property="user" javaType="com.rookie.bigdata.domain.User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="loginname" column="loginname"/>
<result property="password" column="password"/>
<result property="phone" column="phone"/>
<result property="address" column="address"/>
</association>
<!-- 多对多映射的关键:collection -->
<collection property="articles" javaType="ArrayList"
column="oid" ofType="com.rookie.bigdata.domain.Article"
select="com.rookie.bigdata.mapper.ArticleMapper.selectArticleByOrderId"
fetchType="lazy">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="price" column="price"/>
<result property="remark" column="remark"/>
</collection>
</resultMap> <!-- 注意,如果查询出来的列同名,例如tb_user表的id和tb_order表的id都是id,同名,需要使用别名区分 -->
<select id="selectOrderById" parameterType="int" resultMap="orderResultMap">
SELECT u.*,o.id AS oid,CODE,total,user_id
FROM tb_user u,tb_order o
WHERE u.id = o.user_id
AND o.id = #{id}
</select> <!-- 根据userid查询订单 -->
<select id="selectOrderByUserId" parameterType="int" resultType="com.rookie.bigdata.domain.Order">
SELECT * FROM tb_order WHERE user_id = #{id}
</select> </mapper>

UserMapper.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">
<!-- namespace指用户自定义的命名空间。 -->
<mapper namespace="com.rookie.bigdata.mapper.UserMapper"> <resultMap type="com.rookie.bigdata.domain.User" id="userResultMap">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="loginname" column="loginname"/>
<result property="password" column="password"/>
<result property="phone" column="phone"/>
<result property="address" column="address"/>
<!-- 一对多关联映射:collection -->
<collection property="orders" javaType="ArrayList"
column="id" ofType="com.rookie.bigdata.domain.User"
select="com.rookie.bigdata.mapper.OrderMapper.selectOrderByUserId"
fetchType="lazy">
<id property="id" column="id"/>
<result property="code" column="code"/>
<result property="total" column="total"/>
</collection>
</resultMap> <select id="selectUserById" parameterType="int" resultMap="userResultMap">
SELECT * FROM tb_user WHERE id = #{id}
</select> </mapper>

测试代码

package com.rookie.bigdata.test;

import java.io.InputStream;
import java.util.List; import com.rookie.bigdata.domain.Article;
import com.rookie.bigdata.domain.Order;
import com.rookie.bigdata.domain.User;
import com.rookie.bigdata.mapper.OrderMapper;
import com.rookie.bigdata.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class ManyToManyTest { public static void main(String[] args) throws Exception {
// 读取mybatis-config.xml文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 初始化mybatis,创建SqlSessionFactory类的实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
// 创建Session实例
SqlSession session = sqlSessionFactory.openSession(); ManyToManyTest t = new ManyToManyTest(); // 根据用户id查询用户,测试一对多
// t.testSelectUserById(session);
// 根据订单id查询订单,测试多对多
t.testSelectOrderById(session); // 提交事务
session.commit();
// 关闭Session
session.close();
} // 测试一对多,查询班级User(一)的时候级联查询订单Order(多)
public void testSelectUserById(SqlSession session){
// 获得UserMapper接口的代理对象
UserMapper um = session.getMapper(UserMapper.class);
// 调用selectUserById方法
User user = um.selectUserById(1);
// 查看查询到的user对象信息
System.out.println(user.getId() + " " + user.getUsername());
// 查看user对象关联的订单信息
List<Order> orders = user.getOrders();
for(Order order : orders){
System.out.println(order);
}
} // 测试多对多,查询订单Order(多)的时候级联查询订单的商品Article(多)
public void testSelectOrderById(SqlSession session){
// 获得OrderMapper接口的代理对象
OrderMapper om = session.getMapper(OrderMapper.class);
// 调用selectOrderById方法
Order order = om.selectOrderById(2);
// 查看查询到的order对象信息
System.out.println(order.getId() + " " + order.getCode() + " " + order.getTotal());
// 查看order对象关联的用户信息
User user = order.getUser();
System.out.println(user);
// 查看order对象关联的商品信息
List<Article> articles = order.getArticles();
for(Article article : articles){
System.out.println(article);
}
} }

多对多关系测试代码

mybatis关联映射多对多的更多相关文章

  1. 0051 MyBatis关联映射--多对多关系

    用户与订单时一对多关系,再加上商品信息的话,订单与商品之间就是多对多关系了 DROP DATABASE IF EXISTS testdb; USE testdb; /*用户表,记录用户信息:用户与订单 ...

  2. MyBatis学习(七)MyBatis关联映射之多对多映射

    对于数据库中的多对多关系建议使用一个中间表来维护关系. 1.创建四张表,分别为用户表,商品表,订单表,中间表. DROP TABLE IF EXISTS `t_user`; CREATE TABLE ...

  3. spring boot(9)-mybatis关联映射

    一对多 查询type表的某一条数据,并且要同时查出所有typeid与之配置的user,最终要得到一个以下类型的Type对象 public class Type { String id; String ...

  4. 0049 MyBatis关联映射--一对一关系

    世上的事务总不是孤立存在的,表现在Java类里面,则是类与类之间的关系,比如继承is-a.依赖use-a.关联has-a,反映在数据库中,则是表与表之间的关系,比如外键 关联关系存在着以下几种类型:一 ...

  5. Spring Boot (11) mybatis 关联映射

    一对多 查询category中的某一条数据,同时查询该分类下的所有Product. Category.java public class Category { private Integer id; ...

  6. mybatis关联映射一对多

    实际项目中也存在很多的一对多的情况,下面看看这个简单的例子 table.sql CREATE TABLE tb_clazz( id INT PRIMARY KEY AUTO_INCREMENT, CO ...

  7. mybatis关联映射一对一

    在项目开发中,会存在一对一的关系,比如一个人只有一个身份证,一个身份证只能给一个人使用,这就是一对一关系.一对一关系使用主外键关联. table.sql,在数据库中创建如下两个表并插入数据 CREAT ...

  8. MyBatis(五):mybatis关联映射

    Mybatis中表与表之间的关系分为一下4类: 1)一对一 2)一对多 3)多对一 4)多对多 创建数据Demo表 数据库表: 用户表user:记录了购买商品的用户信息. 订单表orders:记录了用 ...

  9. MyBatis学习(六)MyBatis关联映射之一对多映射

    数据库中一对多通常使用主外键关联,外键应该在多方,即多方维护关系. 下面举一个简单实例来看看MyBatis怎么处理一对多的关系. 1.创建一个项目,导入所需jar包,导入db.properties配置 ...

随机推荐

  1. 微信公众平台iPhone版内测开始了

    5月9日晚些时候自媒体人收到了微信公众平台iPhone版的内测邀请,微信公众平台iPhone版可在手机上写图文,快速查看并回复粉丝消息.留言和赞赏,新建群发.查看群发历史和今日数据,这些功能很实用了, ...

  2. USACO Cow Frisbee Team

    洛谷 P2946 [USACO09MAR]牛飞盘队Cow Frisbee Team 洛谷传送门 JDOJ 2632: USACO 2009 Mar Silver 2.Cow Frisbee Team ...

  3. USACO Slowing down

    洛谷 P2982 [USACO10FEB]慢下来Slowing down 洛谷传送门 JDOJ 2684: USACO 2010 Feb Gold 3.Slowing down JDOJ传送门 Des ...

  4. Linux中的帮助文件

  5. MVC Core 使用TagHelper扩展几个插件

    未完待续... 案例1:按钮权限校验,无权限不显示,利用TagHelper控制元素是否输出 [HtmlTargetElement("tc-permission", TagStruc ...

  6. java spring框架的定时任务

    由于测试的原因,最近有接触java spring  @Scheduled的定时任务,当时还以为配置起来表达式和crontab是完全一样的,没想到还有些许不一样. 在spring中,一个cron表达式至 ...

  7. Candy Treasure Box

    This is an interesting puzzle game. In the game, you need to use your brain, think carefully, operat ...

  8. Vue Echarts 饼图设置默认选中一个

    Vue Echarts 饼图设置默认选中一个 myChart.setOption(data) // data伟echarts所需要传入的参数,就是配置参数最多的那个玩意 myChart.dispatc ...

  9. win +R

    一.电脑设置免登录密码及修改密码 1.win+R 2.输入control userpasswords2 3.勾选免密码账号登陆,修改密码 二.打开性能监视器 1.win+R 2.输入perfmon.e ...

  10. Python——IO多路复用之select模块poll方法

    Python——IO多路复用之select模块poll方法 使用poll方法实现IO多路复用 .├── poll_client.py├── poll_server.py└── settings.py ...