表介绍和表关系说明
新建以下4张表
tb_user:用户表
tb_order:订单表
tb_item:商品表
tb_orderdetail:订单详情表
【表关系】
1.tb_user和 tb_order表关系
tb_user 《==》 tb_order:一对多, 一个人可以下多个订单
tb_order 《==》 tb_user:一对一,一个订单只能属于一个人
结论:tb_user和tb_order属于一对多的关系,需要将一方tb_user的主键作为多方tb_order的外键维护关系
2.tb_order 和 tb_item 表关系
tb_order 《==》 tb_item :一个订单可以有多个商品
tb_item 《==》 tb_order:一个商品可以在多个订单上
结论:tb_order和tb_item属于多对多的关系,需要创建中间表tb_orderdetail维护两个表的关系,并且将两张表 的主键作为中间表的外键
一对多查询
【目标】查询id为1的用户及其订单信息
【分析】
一个用户可以有多个订单。
一个订单只能属于一个用户。
用户(1)-----订单(n)
【步骤】
第一步:查询SQL分析;
第二步:添加关联关系;
第三步:编写接口方法;
第四步:编写映射文件;
第五步:测试
【实现】
第一步:需求分析
编写SQL实现查询id为1的用户及其订单信息
查询语句及查询结果:
#查询id为1的用户及其订单信息
select * from tb_user where id=1;
select * from tb_order where user_id=1;
#一对多 内连接查询
select * from tb_user tbu inner join tb_order tbo on tbu.id = tbo.user_id where tbu.id=1;
# 封装数据:关联对象,一个用户关联多个订单 User(List<Order> orderList)
说明:一个用户关联多个订单 User(List orderList) ,在User类中定义一个List集合存储多个订单Order对象。
第二步:添加映射关系
因为一个用户可以拥有多个订单,所以用户和订单是一对多的关系;需要在User类中添加一个List<Order>
属性;
package com.itheima.sh.pojo;
import java.io.Serializable;
import java.util.List;
public class User implements Serializable {
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
//0 女性 1 男性
private Integer sex;
//订单
List<Order> orders;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", orders=" + orders +
'}';
}
}
第三步:编写接口方法
在UserMapper接口中,添加关联查询;
/**
* 根据用户id查询用户及其订单信息
* @param id
* @return
*/
User oneToManyQuery(@Param("id") Long id);
第四步:编写SQL
在UserMapper.xml文件中编写SQL语句完成一对多的关联查询;
说明:
1.一对多使用collection子标签进行关联多方Order
<collection property="类中引用多方的成员变量名" javaType="存放多方容器的类型" ofType="多方类型" autoMapping="true">
</collection>
2.属性:
1)property="orders" 这里的orders表示User类的成员变量orders
2)javaType="List" 表示User类的成员变量orders存储的Order对象使用的类型,这里是List 一般不书写
3) ofType="Order" 表示List集合中存储数据的类型 Order
3.一定要记住这里给user表的id起别名是uid,order表的id起别名是oid.在resultMap标签的id子标签中的column属性值书写对应的uid和oid.
<!--自定义结果集-->
<resultMap id="oneToManyResult" type="User" autoMapping="true">
<!--User的主键-->
<id column="uid" property="id"/>
<!--Order关联映射-->
<!--
1.一对多使用collection子标签进行关联多方Order
2.属性:
1)property="orders" 这里的orders表示User类的成员变量orders
2)javaType="List" 表示User类的成员变量orders存储的Order对象使用的类型,这里是List,可以不配置
3) ofType="Order" 表示List集合中存储数据的类型 Order
-->
<collection property="orders" javaType="List" ofType="Order" autoMapping="true">
<!--Order的主键-->
<id column="oid" property="id" />
</collection>
</resultMap>
<!--根据用户ID查询用户及其订单数据-->
<select id="oneToManyQuery" resultMap="oneToManyResult">
SELECT
tbo.id as oid,
tbo.order_number,
tbu.id as uid,
tbu.user_name,
tbu.password,
tbu.name,
tbu.age,
tbu.sex
FROM
tb_user tbu
INNER JOIN tb_order tbo ON tbu.id = tbo.user_id
WHERE
tbu.id = #{id}
</select>
第五步:测试
在用户的测试类中
public class MybatisTest01 {
private static UserMapper mapper = null;
@BeforeClass
public static void beforeClass() throws Exception {
//1.构建SessionFactory
String resouce = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resouce);
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
//2.获取session
SqlSession sqlSession = build.openSession(true);
//3.获取接口对象
mapper = sqlSession.getMapper(UserMapper.class);
}
//根据用户ID查询用户及其订单数据
@Test
public void oneToManyQuery() {
User user = mapper.oneToManyQuery(1L);
System.out.println("user = " + user);
}
}
【小结】
一对多关系配置:
1、在对象中添加映射关系;
2、编写接口方法,编写SQL;
3、编写resultMap处理数据库字段和实体类之间数据的封装;