Day15 Mybatis(7)多表查询(一对一、一对多)

Mybatis 多表查询

  1. 项目不可能只有一个表,一般是多表
  2. 多表关系为,一对一,一对多,多对多
  3. 查询的数据来自多个表,要使用多表查询
    笛卡尔集,显示内连接inner join,左外连接left outer join,右外连接right outer join,子查询select嵌套select。
  4. 查询的结果要封装成javaBean对象 ,在Mybatis中重点掌握resultType与resultMap

下面通过用户和订单的模型来分析Mybatis多表关系。

用户user表
在这里插入图片描述

订单order表
在这里插入图片描述
架构关系
在这里插入图片描述

一、关联查询(一对一)

  1. 站在订单角度,一个订单对应一个用户,表现为一对一的关系
  2. 数据来自两个表,使用连接查询,需要输出所有订单,使用左外连接
  3. 查询结果可以有两种方式封装数据
  • resultType 指定一个自定义javaBean类(通常要再编写一个新的javaBean类)
  • resultMap 指定映射关系(不用编写新的javaBean类 推荐使用)映射文件

1、使用resultType,编写一个OrderUser类

编写测试

@Test
public void test01(){
    
    
    SqlSession sqlSession = MySessionUtils.getSession();

    OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
    List<OrderUser> list = orderDao.findAllOrderUser();
    
    sqlSession.close();
}

创建新类OrderUser

public class OrderUser {
    
    
    //订单的属性
    private int oid;
    private Integer user_id;
    private String number;
    private Date createtime;
    private String note;
    //用户的属性
    private int uid;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //省略get set toString方法
}    

定义接口方法

List<OrderUser> findAllOrderUser();

resultType配置映射

<select id="findAllOrderUser" resultType="cn.cyl.bean.OrderUser">
    select o.id as oid,
        o.user_id ,
        o.number,
        o.createtime,
        o.note,
        u.id as uid,
        u.username,
        u.birthday,
        u.sex,
        u.address
        from  `order` o left join `user` u
        on o.user_id=u.id;
</select>

输出结果

在这里插入图片描述
在这里插入图片描述

小结:

定义专门的javabean类作为输出类型,其中定义了 sql 查询结果集所有的字段。此方法较为简单,企业中使用普遍。

2、使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果。

编写测试

@Test
public void test01(){
    
    
    SqlSession sqlSession = MySessionUtils.getSession();

    OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
    List<Order> list = orderDao.findAllOrder2();
    
    sqlSession.close();
}

改造Order类

通过面向对象的(has a)关系可以得知,我们可以在 Order类中加入一个 User 类的对象来代表这个订单是哪个用户的。

public class Order {
    
    
    // 订单id
    private int id;
    // 用户id
    private Integer userId;
    // 订单号
    private String number;
    // 订单创建时间
    private Date createtime;
    // 备注
    private String note;

    //增加User成员变量来接收一条记录的用户的查询字段。
    private User user;
    //省略get set toString方法
} 

定义接口方法

//因为Order类中包含了一个User类的对象,它可以封装订单所对应的用户信息
List<Order> findAllOrder2();

resultMap的association配置映射

<!--select标签中的属性resultMap,会在select语句执行之后,查找resultMap属性对应的resultMap标签
    在resultMap标签中必须指定order类与连接查询的结果字段的对应关系
        (1)property指定的java中的变量
        (2)column指定的是数据中的字段
            两者相同可以不写(但是要添加antoMapping="true")
        (3)association关联标签,表示自定义类的类型
        (4)autoMapping:关联查询必须添加此属性,表示自动映射。
            如果不添加,相同名的就查不到值-->
<resultMap id="findAllOrder2Map" type="cn.cyl.bean.Order" autoMapping="true">
    <id property="id" column="id"></id>
    <!--property:表示Order类中User类对象的名字
        javaType:表示Order类中包含的User类的全路径名
        autoMapping:表示如果字段名和属性名一致,则自动映射-->
    <association property="user" javaType="cn.cyl.bean.User" autoMapping="true">
        <!--查询的字段名为uid,成员变量名为id-->
        <id column="uid" property="id"/>
    </association>
</resultMap>
<select id="findAllOrder2" resultMap="findAllOrder2Map">
    select o.id as id,
        o.user_id as userId,
        o.number,
        o.createtime,
        o.note,
        u.id as uid,
        u.username,
        u.birthday,
        u.sex,
        u.address
        from  `order` o left join `user` u
        on o.user_id=u.id;
</select>

输出结果

在这里插入图片描述
在这里插入图片描述

二、关联查询(一对多)

  1. 站在用户角度,一个用户(User)可以有多个订单(Order),表现为一对多的关系。
  2. 数据来自两个表,使用连接查询,需要输出每一个用户有多少个订单
  3. 查询结果使用collection标签 映射List<元素>

编写测试

@Test
public void test01(){
    
    
    SqlSession sqlSession = MySessionUtils.getSession();

    UserDao userDao = sqlSession.getMapper(UserDao.class);
    List<User> list = userDao.findAllUsers();
    for(User user:list){
    
    
        System.out.println(user);
    }
    sqlSession.close();
}

改造User类

User 类加入 List< Order> 存储该用户的所有订单

public class User {
    
    
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //变量类型是集合List
    private List<Order> orders;
    //省略get set toString方法
}

定义接口方法

List<User> findAllUsers();

ResultMap的collection配置映射

<resultMap id="findAllUsersMap" type="cn.cyl.bean.User" autoMapping="true">
    <id property="id" column="uid"></id>
    <!--如果一个类中出现集合类型List,则需要使用collection标签来映射字段与变量的关系-->
    <!--property表示集合变量名,ofType表示集合元素的类型-->
    <collection property="orders" ofType="cn.cyl.bean.Order" autoMapping="true">
        <id property="id" column="oid"></id>
    </collection>
</resultMap>
<select id="findAllUsers" resultMap="findAllUsersMap">
    select u.id as uid,
        u.username,
        u.birthday,
        u.sex,
        u.address,
        o.id as oid,
        o.user_id as userId,
        o.number,
        o.createtime,
        o.note
        from `user` u left join `order` o
        on u.id=o.user_id;
</select>

输出结果

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43639081/article/details/108856046