------------------------------------------------原创不易,如若喜欢,请点一点赞吧!---------------------------------------------
通过前几篇文章的学习,我们已经大致了解了mybatis基础知识,并可以使用基础的sql语句来操作数据库。在关系型数据库中,表与表之间存在着一对一,一对多,多对多这几种映射关系。映射关系是mybatis的核心知识,在以后的工作中,我们会经常遇到以上几种映射关系,因此,我们很有必要学好映射关系。
一、mybatis 一对一映射关系
1.一对一映射关系
- 什么是一对一映射关系?:从数据库的角度出发就是在任意一个表中引入另外一个表的主键作为外键。在本类的定义中定义另外一个类的对象。
- 在mybatis中,我们通过resultMap元素的子元素 association来进行处理。
- association元素具有以下配置属性
属性名称 | 作用 |
---|---|
property | 指定映射到的实体类对象属性,与表字段一一对应 |
column | 指定表中对应的字段 |
select | 指定引入嵌套查询的子SQL 语句,该属性用于关联映射中的嵌套查询。 |
javaType | 指定映射到实体对象属性的类型 |
- 在mybatis中设定了两种查询方式:嵌套查询及嵌套结果查询方式
<!--方式一:嵌套查询--!〉
<association property="card" column="card_id" javaType="com.itheima.po.ldCard"
select="com.itheima.mapper.ldCardMapper.findCodeByld" />
<!--方式二:嵌套结果--!〉
<association property="card" javaType="com.itheima.po.ldCard">
<id property="id" column="card_id" />
<result property="code" column="code" />
</association>
2.【案例分析】
案例描述: 个人和身份证之间是一对一的关系,以个人信息和个人身份证一对一关系为例,查询个人信息,通过一对一映射关系来获取对应身份证信息。
【分析】: 根据mybatis框架我们可知,mybatis关系映射语句都是在Mapper.xml中书写的,在mybatis关系映射中,我们需要用到 resuletMap 元素,该元素的用法在上一篇文章中resultMap映射详解进行过讲解,可自行查阅。StudentMapper.xml 的写法如下
映射文件代码:StudentMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 3-5行是mybatis约束配置 -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.mapper.StudentMapper">
<!-- 嵌套查询
<select id="querystudent" parameterType="int" resultMap="IdS">
select * from student where id=#{id}
</select>
<resultMap type="Student" id="IdS">
<id property="id" column="id"/>
<result property="s_name" column="s_name"/>
<result property="s_age" column="s_age"/>
<result property="s_sex" column="s_sex"/>
<association property="card_id" column="card_id" javaType="Idcard"
select="org.mybatis.mapper.IdcardMapper.queryinfo">
</association>
</resultMap>
-->
<!-- 嵌套结果-->
<select id="querystudent" resultMap="Ids"> <!-- select语句的返回值是resultMap类型-->
<!-- sql查询语句, 当p.card_id = idcard.id时,获取student表中所有数据和idcard表中的code数据-->
select p.*,idcard.code
from student p,idcard idcard
where p.card_id = idcard.id
</select>
<!-- 一对一映射需要使用resultMap元素封装查询到的信息,id值需要与上文select语句中引用的resultMap="Ins"值相同--->
<resultMap type="Student" id="Ids">
<!--映射 Student类中属性与student表的字段一一对应-->
<id property="id" column="id"/>
<result property="s_name" column="s_name"/>
<result property="s_age" column="s_age"/>
<result property="s_sex" column="s_sex"/>
<!--映射 Idcard类中属性与idcard表的字段一一对应,并将数据放入Student类的属性card_id中-->
<association property="card_id" javaType="Idcard">
<id property="id" column="card_id"/>
<result property="code" column="code"/>
</association>
</resultMap>
</mapper>
二、mybatis 一对多映射关系
1.一对多映射关系
-
什么是一对多关系:一对多关系就是表A中一条数据对应表B中的多条数据,例如,用户和订单之间的关系,一个用户可以有多个订单信息。
-
在mybatis中,我们通过resultMap元素的子元素 collection来进行处理。
-
collection元素具有以下配置属性
属性名称 | 作用 |
---|---|
property | 指定映射到的实体类对象属性,与表字段一一对应 |
column | 指定表中对应的字段 |
select | 指定引入嵌套查询的子SQL 语句,该属性用于关联映射中的嵌套查询。 |
javaType | 指定映射到实体对象属性的类型 |
ofType | ofType 属性与javaType 属性对应,它用于指定实体对象中集合类属性所包含的元素类型。 |
- 需要注意的是:在一对多映射和多对多映射中,collection 元素属行中使用的是ofType属性来指定实体对象,而不是使用JavaType属性。
2.【案例分析】
案例描述: 以用户和订单为例,若一个用户有用三个订单,则如何通过查询用户来获取用户对应的订单信息。
【分析】: 一个用户可以有多个订单信息。这就构成了一对多的映射关系。通过mybatis中的一对多映射关系,在mapper.xml文件中写入对应语句后则可完成该需求。
映射文件代码:OrdersMapper.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">
<!--a.一对多嵌套结果 -->
<mapper namespace="org.mybatis.mapper.UserMapper">
<select id="queryorders" parameterType="int" resultMap="Ins"> <!-- select语句的返回值是resultMap类型-->
<!-- sql查询语句, 当u.id = o.user_id, u.id="传入值"时,获取user 表中id="传入值"的数据以及orders 表中的订单数据-->
select u.*,o.id as orders_id,o.number
from user u,orders o
where u.id = o.user_id
and u.id=#{id}
</select>
<!-- 一对多映射需要使用resultMap元素封装查询到的信息,且id值需要与上文select语句中引用的resultMap="Ins"值相同-->
<resultMap type="org.mybatis.beans.User" id="Ins">
<!--映射 User类中属性与user表的字段一一对应-->
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
<!-- a.1对多关联映射: collection
ofType 表示属性集合中元素的类型, List<Orders>属性即 Orders 类-->
<collection property="orderList" ofType="org.mybatis.beans.Orders">
<!--映射 Orders类中属性与orders表的字段一一对应-->
<id property="id" column="orders_id"/>
<result property="number" column="number"/>
</collection>
</resultMap>
</mapper>
三、mybatis 多对多映射关系
1.多对多映射关系
- 什么是多对多关系: 一对多关系就是表A中一条数据对应表B中的多条数据,例如,用户和订单之间的关系,一个用户可以有多个订单信息。
- 在mybatis中,与一对多映射一致,我们通过resultMap元素的子元素 collection来进行处理。这里就不再多collection元素属性与上文一致。
-
- 需要注意的是:在一对多映射和多对多映射中,collection 元素属行中使用的是ofType属性来指定实体对象,而不是使用JavaType属性。
2.【案例分析】
案例描述: 以订单和商品为例,若一个订单有用三个商品,一个商品有五个不同的订单,则如何通过查询订单来获取对应的商品信息,如何通过查询商品来获取对应的订单信息。
【分析】: 一个商品可以有多个订单信息。一个订单可以有多个商品信息。这就构成了多对多的映射关系。一般来说,在多对多的映射中,会通过生成中间表的方式来处理,通过一个中间表保存订单信息和商品信息。但Mapper.xml中的resultMap 元素的写法与一对多基本一致。
映射文件代码:OrdersMapper.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="org.mybatis.mapper.OrdersMapper">
<!-- 多对多嵌套结果 -->
<select id="queryproduct" parameterType="int" resultMap="Ins">
select o.*,p.id as pid,p.name,p.price
from orders o,product p,ordersitem oi
where oi.orders_id=o.id
and oi.product_id=p.id
and o.id=#{id}
</select>
<resultMap type="Orders" id="Ins">
<id property="id" column="id"/>
<result property="number" column="number"/>
<collection property="productList" ofType="Product">
<id property="id" column="pid"/>
<result property="name" column="name"/>
<result property="price" column="price"/>
</collection>
</resultMap>
</mapper>
---------------------------------------------------------------------------------------------------公众号内有更多干货。欢迎关注!