一 建表,提供初始数据。
表说明:t_customer为客户信息表;t_orders为订单表。一个客户可以有多个订单,一个订单只属于一个客户。多方使用外键(t_orders表的customer_id)来约束。这里并没有建立强制的外键约束,做更新,删除操作时会很麻烦。
- CREATE TABLE `t_customer` (
- `id` int(10) NOT NULL AUTO_INCREMENT,
- `name` varchar(30) NOT NULL,
- `cell_phone` varchar(30) NOT NULL,
- PRIMARY KEY (`id`)
- );
- INSERT INTO `t_customer` VALUES ('1', 'bing', '652346543');
- INSERT INTO `t_customer` VALUES ('2', 'jade', '76345');
- CREATE TABLE `t_orders` (
- `id` int(10) NOT NULL AUTO_INCREMENT,
- `number` varchar(40) NOT NULL,
- `address` varchar(40) NOT NULL,
- `customer_id` int(10) NOT NULL,
- PRIMARY KEY (`id`)
- );
- INSERT INTO `t_orders` VALUES ('1', 'GASDF235', '北京朝阳', '1');
- INSERT INTO `t_orders` VALUES ('2', 'JHGFVSD34', '河南郑州', '1');
- INSERT INTO `t_orders` VALUES ('3', 'KJHGFDC234', '北京海淀', '2');
表模型如下
二 实体类
Customer
- package com.alex.app.entity;
- import java.util.List;
- /**
- * 客户信息
- * @author leileiyuan
- *
- */
- public class Customer {
- private Integer id;
- private String name;
- private String cellPhone;
- //一对多
- private List<Orders> orders;
- public List<Orders> getOrders() {
- return orders;
- }
- public void setOrders(List<Orders> orders) {
- this.orders = orders;
- }
- // 略 getter setter方法
- @Override
- public String toString() {
- return "Customer [id=" + id + ", name=" + name + ", cellPhone=" + cellPhone + "]";
- }
- }
Orders
- package com.alex.app.entity;
- /**
- * 客户订单信息
- * @author leileiyuan
- *
- */
- public class Orders {
- private Integer id;
- private String number;
- private String address;
- // 多对一
- private Customer customer;
- public Customer getCustomer() {
- return customer;
- }
- public void setCustomer(Customer customer) {
- this.customer = customer;
- }
- // 略 getter setter方法
- @Override
- public String toString() {
- return "Orders [id=" + id + ", number=" + number + ", address=" + address + ", customer="
- + customer + "]";
- }
- }
三 多对一映射
1)问题简单分析
从orders 到 customer 多对一的关联关联。
就是说 我们要查询orders的信息,然后经该orders可以导航到它对应的customer
考虑这个sql
- select o.*, c.* from t_orders o
- join t_customer c
- on o.customer_id = c.id
- where o.id = 2
查询是没有问题的
映射文件配置时可以。
- <select id="selectById" parameterType="int" resultMap="???????">
- select
- c.id cid,
- c.name name,
- c.cell_phone cellPhone,
- o.id oid,
- o.number number,
- o.address address
- from t_orders o
- join t_customer c
- on o.customer_id = c.id
- where o.id = #{id}
- </select>
因为我们查询的结果集中包含的是orders和customer的所有列,所以返回的结果集应该使用resultMap而不是resultType(也可以也写一个VO,来封装结果中的列,那么就可以使用resultType指向那个VO)。
2)映射结果集
我们来写个resultMap 来封装这个复杂结果集
Orders.xml的映射文件如下。t_orders和t_customer的id列,要使用别名来区分
- <?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.alex.app.dao.OrdersDao">
- <resultMap type="Orders" id="OrdersResultMap">
- <id property="id" column="oid"/>
- <result property="number" column="number"/>
- <result property="address" column="address"/>
- </resultMap>
- <select id="selectById" parameterType="int" resultMap="OrdersResultMap">
- select
- c.id cid,
- c.name name,
- c.cell_phone cellPhone,
- o.id oid,
- o.number number,
- o.address address
- from t_orders o
- join t_customer c
- on o.customer_id = c.id
- where o.id = #{id}
- </select>
- </mapper>
定义了一个resultMap,id为OrdersResultMap,查询的结果集指向这个resultMap。
来测试下
- @Test
- public void test() {
- SqlSession session = null;
- try {
- session = MyBatisUtil.openSession();
- OrdersDao ordersDao = session.getMapper(OrdersDao.class);
- Orders orders = ordersDao.selectById(1);
- System.out.println(orders);
- } catch (Exception e) {
- e.printStackTrace();
- session.rollback();
- }finally{
- MyBatisUtil.coloseSession(session);
- }
- }
结果如下
- Orders [id=1, number=GASDF235, address=北京朝阳, customer=null]
customer为null。
3)表达关联关系
我们还需要把orders到customer多对一,这个一方,也表示在resultMap里。使用association 标签。
t_orders和t_customer的id列,要使用别名来区分
- <resultMap type="Orders" id="OrdersResultMap">
- <id property="id" column="oid"/>
- <result property="number" column="number"/>
- <result property="address" column="address"/>
- <association property="customer" javaType="Customer">
- <id property="id" column="cid"/>
- <result property="name" column="name"/>
- <result property="cellPhone" column="cell_phone"/>
- </association>
- </resultMap>
association解释
属性:property,当然是Orders实体中定义的属性名customer;
javaType,是customer所要映射成那个Java对象,这可以使用别名
子标签:
id,表示主键,property是实体类的属性名,column是对应表的字段列名
result,表示普通属性
4)再运行上面的测试代码,得到结果
- Orders [id=1, number=GASDF235, address=北京朝阳, customer=Customer [id=1, name=bing, cellPhone=null, orders=null]]
看到我们已经关联上了,也返回了正确的结果。
5)Orders.xml完整内容。t_orders和t_customer的id列,要使用别名来区分
- <?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.alex.app.dao.OrdersDao">
- <resultMap type="Orders" id="OrdersResultMap">
- <id property="id" column="oid"/>
- <result property="number" column="number"/>
- <result property="address" column="address"/>
- <association property="customer" javaType="Customer">
- <id property="id" column="cid"/>
- <result property="name" column="name"/>
- <result property="cellPhone" column="cell_phone"/>
- </association>
- </resultMap>
- <select id="selectById" parameterType="int" resultMap="OrdersResultMap">
- select
- c.id cid,
- c.name name,
- c.cell_phone cellPhone,
- o.id oid,
- o.number number,
- o.address address
- from t_orders o
- join t_customer c
- on o.customer_id = c.id
- where o.id = #{id}
- </select>
- </mapper>
四 一对多关联映射
从customer到orders一对多的关联关系。一个客户对多个订单信息
1)问题分析
考虑这个sql
- select c.*, o.* from t_customer c
- join t_orders o
- on c.id = o.customer_id
- where c.id = 1
查询结果bing这个客户拥有两个订单
2)映射结果集
映射文件的sql
- <select id="selectById" parameterType="int" resultMap="CustomerResultMap">
- select
- c.id cid,
- c.name name,
- c.cell_phone cellPhone,
- o.id oid,
- o.number number,
- o.address address
- from t_customer c, t_orders o
- where c.id = o.customer_id
- and c.id = #{id}
- </select>
3)一对多关联
上面我们需要提供一个resultMap="CustomerResultMap"。t_orders和t_customer的id列,要使用别名来区分
- <resultMap type="Customer" id="CustomerResultMap">
- <id property="id" column="cid" />
- <result property="name" column="name" />
- <collection property="orders" javaType="ArrayList" ofType="Orders">
- <id property="id" column="oid" />
- <result property="number" column="number" />
- </collection>
- </resultMap>
一对多关联,多的一方使用collection表示
collection 属性 解释:
property,是实体类中的属性orders;
javaType,这里的JavaType代表的是实体类中的属性orders的类型是ArrayList
- //一对多
- private List<Orders> orders;
ofType,是集合中的放置的内容的类型,这里集合放的东西是Orders对象
4)测试下
- @Test
- public void testSelectCustomer() {
- SqlSession session = null;
- try {
- session = MyBatisUtil.openSession();
- CustomerDao customerDao = session.getMapper(CustomerDao.class);
- Customer customer = customerDao.selectById(1);
- System.out.println(customer);
- List<Orders> orders = customer.getOrders();
- System.out.println(orders);
- } catch (Exception e) {
- e.printStackTrace();
- }finally{
- MyBatisUtil.coloseSession(session);
- }
- }
结果
- DEBUG 2015-05-10 08:59:28,640 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Preparing: select c.id cid, c.name name, c.cell_phone cellPhone, o.id oid, o.number number, o.address address from t_customer c, t_orders o where c.id = o.customer_id and c.id = ?
- DEBUG 2015-05-10 08:59:28,687 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 1(Integer)
- DEBUG 2015-05-10 08:59:28,718 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <== Total: 2
- Customer [id=1, name=bing, cellPhone=null, orders=[Orders [id=1, number=GASDF235, address=null, customer=null], Orders [id=2, number=JHGFVSD34, address=null, customer=null]]]
- [Orders [id=1, number=GASDF235, address=null, customer=null], Orders [id=2, number=JHGFVSD34, address=null, customer=null]]
5)Customer.xml完整内容。t_orders和t_customer的id列,要使用别名来区
- <?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.alex.app.dao.CustomerDao">
- <resultMap type="Customer" id="CustomerResultMap">
- <id property="id" column="cid" />
- <result property="name" column="name" />
- <collection property="orders" javaType="ArrayList" ofType="Orders">
- <id property="id" column="oid" />
- <result property="number" column="number" />
- </collection>
- </resultMap>
- <select id="selectById" parameterType="int" resultMap="CustomerResultMap">
- select
- c.id cid,
- c.name name,
- c.cell_phone cellPhone,
- o.id oid,
- o.number number,
- o.address address
- from t_customer c, t_orders o
- where c.id = o.customer_id
- and c.id = #{id}
- </select>
- </mapper>
相关推荐
mybatis一对多的查询方法详解! mybatis一对多的查询方法详解! mybatis一对多的查询方法详解! mybatis一对多的查询方法详解!
本主题将详细探讨在MyBatis中如何实现一对一和一对多的映射。 ### 一对一映射(One-to-One) 一对一关系通常发生在两个实体之间,例如一个用户对应一个唯一地址。在MyBatis中,可以通过`<association>`标签来配置...
在处理复杂的关联关系时,MyBatis的一对多映射机制显得尤为重要。一对多映射指的是一个父类实体对应多个子类实体的关系,例如一个学生可以有多个课程,一个部门可以有多名员工等。 一、一对多映射的基本概念 在...
在MyBatis框架中,"一对多"关系映射是一种常见的数据库关联操作,它表示一个实体(如用户)可以对应多个子实体(如订单)。在实际的业务场景中,例如,一个用户可能有多个订单,这就是一对一到多的关系。本教程将...
在MyBatis中,一对多关系映射是常见的数据关联方式,它允许我们在查询一个实体对象时,同时加载与之相关联的多个子对象。然而,如果不进行优化,这种关联查询可能会导致性能问题,比如数据量大时的内存消耗、多次...
本主题将深入探讨MyBatis实现一对多关系的代码实践,帮助你理解和掌握如何在实际项目中处理这种常见的关联关系。 首先,我们需要了解一对多关系的概念。在数据库设计中,一对多关系是指一个表(父表)中的一个记录...
在测试中,你可以创建类似 `mybatis0408` 这样的例子,模拟不同的一对一和一对多关系,通过运行 SQL 并观察返回的结果,以加深对这两个标签的理解。 总之,掌握 MyBatis 的 `association` 和 `collection` 使用,...
本例子将通过简单的步骤来展示如何在 MyBatis 中实现一对多的关系映射。 首先,我们需要创建相关的数据库表。假设我们有两个表:`user` 和 `order`,其中 `user` 表代表用户,`order` 表代表订单,每个订单对应一个...
【MyBatis学习笔记六】——MyBatis一对一,一对多,多对一,多对多.zip博客地址:https://blog.csdn.net/weixin_43817709/article/details/117537580
5. **一对一(OneToOne)和一对多(OneToMany)嵌套映射**:在多对多关系中,常常伴随着一对一或一对多的子关系。MyBatis提供`<oneToMany>`和`<oneToOne>`标签,允许我们在映射文件中声明这些关系。 6. **级联操作...
在处理复杂的数据库关联关系时,比如一对一、一对多、多对一、多对多等,Mybatis提供了灵活的映射机制。本篇将详细讲解如何在Mybatis中实现一对多关联映射的查询操作。 首先,我们要明确一对多关联映射的基本概念。...
在实际应用中,我们可能会遇到更复杂的一对一关系,比如多层嵌套或者多个一对一关系。这时,可以使用`association`标签来处理。`association`用于处理复杂类型的关联,例如对象与对象的一对一关系。 ```xml ...
标题 "mybatis xml 一对多" 指的是在MyBatis框架中处理数据库中的一对多关联映射。MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集...
本项目实用Spring + Spring MVC + Mybatis。数据库实用Mysql数据库 项目主要涉及,SSM框架的配置搭建,涉及Mybatis一对多的插入和查询,同时也涉及到一些简单的文件上传和下载.
总结,MyBatis通过灵活的XML映射和Java实体设计,使得处理一对多和多对一关系变得简单。理解这些映射机制并恰当运用,能够帮助我们在开发中更好地管理数据库关联关系,提高代码的可读性和维护性。
举个例子:每个人可以拥有多个银行卡(一对多)、每张银行卡只会对应一个用户(一对一)、每个人可能拥有多个不同的社会角色,每一个不同的社会角色也会对应不同的人(多对多),Mybatis作为大名鼎鼎的SSM的组成部分...
1. **关联映射(Association Mapping)**: 在MyBatis中,我们使用`<association>`标签来处理一对多或一对一的关系。但在这个场景下,我们关注的是多对多关系,通常会通过中间表来实现。 2. **联合映射(Collection ...
MyBatis 提供了一种通过 XML 映射文件来配置一对多关联的方法,让我们可以方便地处理这种复杂的关系。 在 MyBatis 的一对多关联映射中,通常涉及到两个表:一个是一对的“父”表,另一个是多的“子”表。在 XML ...
在MyBatis中,一对多关系映射是一个常见的数据库实体关系映射场景。通常,我们说的一对多是指一个父表记录对应多个子表记录,比如一个学生可以有多个课程,一个部门可以有多名员工。然而,"mybatis 一对多反过来"这...
SpringBoot 中 MyBatis 表关联映射关系(一对多嵌套:结果方式) 在 SpringBoot 中,MyBatis 是一个非常流行的持久层框架,它提供了强大的持久化功能,能够将 Java 对象与数据库表进行映射。在实际开发中,我们经常...