Mybatis (六)数据模型分析思路、一对一、resultMap、一对多、多对多

数据模型分析思路
1.每张表记录的数据内容,分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程。
2.每张表重要的字段设置,非空字段、外键字段
3.数据库基本表与表直接的关系,外键关系
4.表与表直接的业务关系,在分析表与表之间的业务关系时一定要建立在某个业务意义基础上分析。


Mybatis (六)数据模型分析思路、一对一、resultMap、一对多、多对多


resultType实现一对一查询
1.先写sql语句分析
确定查询的主表:订单表
确定查询的关联表:用户表
关联查询使用内链接,还是外链接?由于orders表中有一个外键(user_id),通过外联关系查询用户表只能


查询出一条记录,可以使用内链接。


SELECT orders.*,
user.uusername,
user.usex,
user.uaddress
FROM orders,
user 
WHERE orders.user_id = user.uid


2.pojo
将上面的sql查询结果集映射到pojo中,原始Orders.java不能映射全部字段
Orders.java set和get函数
public class Orders {


private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
创建新的pojo,继承包括查询字段多的,也就是order
OrdersCustom.java set和get函数
public class OrdersCustom extends Orders{


private String uusername;
private String usex;
private String uaddress;


3.mapper.xml
OrdersMapperCustom.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的命名空间,对sql进行分类管理,mapper代理时,特殊作用 -->
<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">
<!-- 查询订单关联查询用户信息 -->

<select id="findOrdersUser" resultType="cn.itcast.mybatis.po.OrdersCustom">
SELECT orders.*,
user.uusername,
user.usex,
user.uaddress
FROM orders,
user 
WHERE orders.user_id = user.uid
</select>

</mapper>


4.mapper.java
OrdersMapperCustom.java
public interface OrdersMapperCustom {


//查询订单关联查询用户
public List<OrdersCustom> findOrdersUser()throws Exception;
}


@Test
public void testFindOrdersUser() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper


(OrdersMapperCustom.class);
List<OrdersCustom> list = ordersMapperCustom.findOrdersUser();
sqlSession.close();
System.out.println(list);

}
===============================================================================
resultMap
1.同上先写sql语句分析
2.使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加user属性,将关联查询出


来的用户信息映射到orders对象中的user属性中。


需要Orders类中添加user属性:
Orders.java set和get函数
public class Orders {


private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
private User user;


3.mapper.xml
OrdersMapperCustom.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的命名空间,对sql进行分类管理,mapper代理时,特殊作用 -->
<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">
<!-- 订单查询关联用户的resultMap -->
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">
<!-- 配置映射的订单信息 ,id:是唯一标识,如果有多个列组成唯一标识,配置多个id
column:是数据库的列,property:是Orders的属性-->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 配置映射的用户信息 
association:用于映射关联查询单个对象的信息
property:要将关联查询的用户信息映射到Orders中那个属性
-->
<association property="user" javaType="cn.itcast.mybatis.po.User">
<!-- id:column:指定唯一标识用户信息的列 
property:映射到user的哪个属性-->
<id column="user_id" property="uid"/>
<result column="uusername" property="uusername"/>
<result column="usex" property="usex"/>
<result column="uaddress" property="uaddress"/>
</association>
</resultMap>
.............
</select>
<!-- 查询订单关联查询用户信息使用resultMap -->
<select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
SELECT orders.*,
user.uusername,
user.usex,
user.uaddress
FROM orders,
user 
WHERE orders.user_id = user.uid
</select>

</mapper>


4.mapper.java


OrdersMapperCustom.java
public interface OrdersMapperCustom {


//查询订单关联查询用户
public List<OrdersCustom> findOrdersUser()throws Exception;
//resultMap
public List<Orders> findOrdersUserResultMap()throws Exception;
}
//resultMap
@Test
public void testfindOrdersUserResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper


(OrdersMapperCustom.class);
List<Orders> list = ordersMapperCustom.findOrdersUserResultMap();
sqlSession.close();
System.out.println(list);

}


resultType:简单,没有查询结果的特殊要求,建议使用。
resultMap:麻烦,需要单独定义resultMap,对查询结果可以完成将关联查询映射pojo的属性中,并可以实


现延迟加载,resultType无法实现。一对多,等复杂类型。


====================================================================================
一对多查询
1.sql语句:
确定主查询表:订单表
确定关联查询表:订单明细表
在一对一查询基础上提那家订单明细表即可。
SELECT 
 orders.*,
 USER.uusername,
 USER.usex,
 USER.uaddress,
 orderdetail.id orderdetail_id,
 orderdetail.items_id,
 orderdetail.items_num,
 orderdetail.orders_id 
FROM
 orders,
 USER,
 orderdetail 
WHERE 
 orders.user_id=user.uid 
 AND orderdetail.orders_id=orders.id


使用resultType将上边的查询结果集映射到pojo中,订单信息会重复。
所以,在orders.java 类中添加List<orderDetail>orderDetails属性。将订单信息映射到orders中,订单所


对应的订单明细映射到orders中的orderDetails属性中。


2.Orderdetail.java set和get函数
public class Orderdetail {


private Integer id;
private Integer ordersId;
private Integer itemsId;
private Integer itemsNum;


3.Orders.java set和get函数
public class Orders {


private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//用户信息
private User user;
//订单明细
private List<Orderdetail> orderdetails;


4.OrdersMapperCustome.xml
<!-- 查询订单关联查询用户信息 resultMap
使用extends继承,不用再配置订单信息和用户信息的映射 -->
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" 


extends="OrdersUserResultMap">
<!-- 订单信息 -->


<!-- 用户信息 -->


<!-- 订单明细信息 
一个订单可以查询多条明细,要使用collection来进行映射
collection:对关联查询到多条记录映射到集合对象中
property:将关联查询到多条记录映射到cn.itcast.mybatis.po.Orders哪个属性
ofType:指定映射到list集合属性中pojo的类型
-->
<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
<!-- id:订单明细的唯一标识 
property:要将订单明细的唯一标识映射到cn.itcast.mybatis.po.Orderdetail的


哪个属性

-->
<id column="orderdetail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itemsNum"/>
<result column="orders_id" property="ordersId"/>

</collection>

</resultMap>
.......
<!-- 查询订单关联查询用户及订单明细,使用resultMap -->
<select id="findOrdersAndOrderDetailResultMap" 


resultMap="OrdersAndOrderDetailResultMap">
SELECT 
  orders.*,
  USER.uusername,
  USER.usex,
  USER.uaddress,
  orderdetail.id orderdetail_id,
  orderdetail.items_id,
  orderdetail.items_num,
  orderdetail.orders_id 
FROM
  orders,
  USER,
  orderdetail 
WHERE 
  orders.user_id=user.uid 
  AND orderdetail.orders_id=orders.id
</select>
5.OrdersMapperCustom.java 接口
public interface OrdersMapperCustom {


//查询订单关联查询用户
public List<OrdersCustom> findOrdersUser()throws Exception;
//resultMap
public List<Orders> findOrdersUserResultMap()throws Exception;
//查询订单(保留关联用户)及订单明细
public List<Orders> findOrdersAndOrderDetailResultMap()throws Exception;


//一对多
@Test
public void testfindOrdersAndOrderDetailResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper


(OrdersMapperCustom.class);
List<Orders> list = ordersMapperCustom.findOrdersAndOrderDetailResultMap();
sqlSession.close();
System.out.println(list);

}


===============================================================================================
多对多
查询主表是:用户表
关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:orders、orderdetail


、items


1.sql语句
SELECT 
 orders.*,
 USER.uusername,
 USER.usex,
 USER.uaddress,
 orderdetail.id orderdetail_id,
 orderdetail.items_id,
 orderdetail.items_num,
 orderdetail.orders_id,
 items.name items_name,
 items.detail items_detial,
 items.price items_price
FROM
 orders,
 USER,
 orderdetail,
 items
WHERE 
 orders.user_id=user.uid 
 AND orderdetail.orders_id=orders.id
 AND orderdetail.items_id=items.id


2.思路:将用户信息映射到user中。
在user类中添加订单列表的属性List<Orders>orderslist。将用户创建的订单映射到orderslist
在Orders中添加订单明细列表属性,List<OrderDetail>orderdetails。将订单的明细映射到orderdetials
在OrderDetail中添加Items属性。将订单明细对应的商品映射到Items


3.mapper.xml
OrdersMapperCustom.xml
.........
</resultMap>
<!-- 查询用户及购买的商品 -->
<resultMap type="cn.itcast.mybatis.po.User" id="UserAndItemsResultMap">
<!-- 用户信息 -->
<id column="user_id" property="uid"/>
<result column="uusername" property="uusername"/>
<result column="usex" property="usex"/>
<result column="uaddress" property="uaddress"/>
<!-- 用户购买的订单信息 
一个用户对应多个订单,使用collection映射
-->
<collection property="ordersList" ofType="cn.itcast.mybatis.po.Orders">
<id column="id" property="id" />
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 订单明细
一个订单包含多个明细
-->
<collection property="orderdetails" 


ofType="cn.itcast.mybatis.po.Orderdetail">
<id column="orderdetail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itemsNum"/>
<result column="orders_id" property="ordersId"/>
<!-- 商品信息
一个订单明细对应一个商品 -->
<association property="items" 


javaType="cn.itcast.mybatis.po.Items">
<id column="items_id" property="id"/>
<result column="items_name" property="name"/>
<result column="items_detail" property="detail"/>
<result column="items_price" property="price"/>
</association>
</collection>
</collection>

</resultMap>


...........................
<!-- 查询用户及购买的商品信息,使用resultMap -->
<select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
SELECT 
  orders.*,
  USER.uusername,
  USER.usex,
  USER.uaddress,
  orderdetail.id orderdetail_id,
  orderdetail.items_id,
  orderdetail.items_num,
  orderdetail.orders_id,
  items.name items_name,
  items.detail items_detial,
  items.price items_price
FROM
  orders,
  USER,
  orderdetail,
  items
WHERE 
  orders.user_id=user.uid 
  AND orderdetail.orders_id=orders.id
  AND orderdetail.items_id=items.id
</select>


4.User.java
public class User {


private int uid;
private String uusername;
private String usex;
private Date ubirthday;
private String uaddress;
//用户创建的订单列表
private List<Orders> ordersList;

5.Orderdetail.java
public class Orderdetail {


private Integer id;
private Integer ordersId;
private Integer itemsId;
private Integer itemsNum;
//添加商品
private Items items;

6.Items.java
public class Items {


private Integer id;
private String name;
private Float price;
private String pic;
private Date createtime;
private String detail;


7.OrdersMapperCustom.java 接口
public interface OrdersMapperCustom {


//查询订单关联查询用户
public List<OrdersCustom> findOrdersUser()throws Exception;
//resultMap
public List<Orders> findOrdersUserResultMap()throws Exception;
//查询订单(保留关联用户)及订单明细
public List<Orders> findOrdersAndOrderDetailResultMap()throws Exception;
//查询用户的商品信息
public List<User> findUserAndItemsResultMap()throws Exception;
}
//多对多 用户对商品信息
@Test
public void testFindUserAndItemsResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper


(OrdersMapperCustom.class);
List<User> list = ordersMapperCustom.findUserAndItemsResultMap();
sqlSession.close();
System.out.println(list);

}


验证xml的好方法就是用ie打开,如果没有提示错误,那么就是没有问题的了
查询用户购买的商品信息明细清单,使用resultType。
查询用户购买的商品信息明细清单加上鼠标上显示明细,使用resultMap。