表关系: 一对一,一对多,多对多
1vs1 丈夫表 --> 妻子表
1 vs n 用户 --> 车辆/房产
n vs n 老师/商品 --> 学生/订单
多表联查的SQL
内连接
select * from 表1 inner join 表2 on 表1.字段 = 表2.字段
select * from 表1, 表2 where 表1.字段 = 表2.字段
外连接
select * from 表1 left join 表2 on 表1.字段 = 表2.字段
子查询
1 OneToOne
需求: 实现一对一查询,查询订单以及对应的用户信息
数据: tb_user表, tb_order表
关系:
用户 ---> 订单 (1 VS N) 一个用户有多个订单 订单 ---> 用户 (1 VS 1) 一个订单只会属于一个人
public class OrderVO extends Order { private User user; // set get }
OrderMapper.java接口文件
public interface OrderMapper { OrderVO findOrderWithUserByOid(int oid); }
OrderMapper.xml映射文件
<resultMap id="orderWithUserResultMap" type="OrderVO"> <!-- 封装查询主体Order: --> <id column="oid" property="oid"/> <result column="order_time" property="orderTime"/> <result column="order_desc" property="orderDesc"/> <result column="uid" property="uid"/> <!-- 一对一映射,需要封装关联的User对象 --> <!-- 一对一映射,需要特殊标签 association--> <!-- property="user" 是OrderVO类中的属性,javaType是user属性的类型 --> <association property="user" javaType="com.qf.model.User"> <!-- 下面正常的列和属性 一一映射 --> <id column="id" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <result column="phone" property="phone"/> <result column="money" property="money"/> <result column="create_time" property="createTime"/> <result column="sex" property="sex"/> </association> </resultMap> <!-- 多表联查,直接返回resultType无法封装关联的那个对象,就需要使用 resultMap手动映射 --> <select id="findOrderWithUserById" resultMap="orderWithUserResultMap"> SELECT o.*, u.* FROM tb_order o, tb_user u WHERE o.uid = u.id AND o.oid = #{oid} </select>
2 OneToMore
需求: 一对多,查询用户关联查询出所有的订单
SELECT * FROM tb_user u LEFT JOIN tb_order o ON u.id = o.uid WHERE u.id = 1
目的查询用户,以及关联多个订单,User类不够展现全部数据,那么就创建扩展类UserVO,UserVO类继承User就可以存储用户信息,还需要再UserVO类中添加Order类来存储信息,但是!!不是一个Order类,因为是一对多,一个用户关联多个订单,所有要设置List<Order>
User扩展实体类
public class UserVO extends User{ private List<Order> orderList; // set get }
UserMapper.java接口
public interface UserMapper { UserVO findUserWithOrdersById(int id); }
UserMapper.xml映射文件
<!-- 一对多 --> <resultMap id="userWithOrdersResultMap" type="UserVO"> <!-- 封装User对象 --> <id column="id" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <result column="phone" property="phone"/> <result column="create_time" property="createTime"/> <result column="money" property="money"/> <result column="sex" property="sex"/> <!-- 一对多关联映射使用collection标签 --> <!-- property是UserVO类中关联的属性 --> <!-- 不是javaType,是ofType,是指定集合中存储的数据类型 --> <collection property="orderList" ofType="com.qf.model.Order"> <id column="oid" property="oid"/> <result column="order_time" property="orderTime"/> <result column="order_desc" property="orderDesc"/> <result column="uid" property="uid"/> </collection> </resultMap> <!-- 多表联查,另外的属性不会自动封装,需要使用resultMap --> <select id="findUserWithOrdersById" resultMap="userWithOrdersResultMap"> SELECT * FROM tb_user u LEFT JOIN tb_order o ON u.id = o.uid WHERE u.id = #{id} </select>
3 关联查询总结
实体类要设置扩展类以用于封装多表的数据
一对一,类中套类
一对多,类中套集合
正常封装使用resultMap
一对一封装使用association
一对多封装使用collection