二,MyBatis表连接查询

1 mapper.xml中的标签

1.1 sql和include标签

抽取mapper.xml中共性sql,进行复用

<sql id="user_select_sql">
    select user_id as userId,user_name as username,password from t_user
</sql>

<select id="selectUserById" resultType="user">
    <include refid="user_select_sql"></include>
    where user_id = #{id}
</select>

1.2 特殊字符(xml实体)

在xml中><用来表示标签,如果运算条件中有><时会有问题。这时候就可以使用特殊符号来表示这些运算符。

>  &gt;
<  &lt;

案例:

<!-- 查询id值大于指定id值得所有User-->
<select id="selectUsersById" resultMap="userResultMap">
		<include refid="user_select_sql"></include>
		where user_id &lt; #{id}
</select>

1.3 resultMap

作用:解决查询结果和实体属性不匹配的问题。

<!-- 
	resultMap 用来解决查询结果和实体属性映射的问题
            id: 唯一的名,不重复就可以
            type: 明确解决哪个实体类型的映射问题,写成实体类型全类名或者短别名
    -->
<resultMap type="com.bz.entity.User" id="userResultMap">
    <!--
            通过result标签,明确 列名和属性名的对应关系
                column:列名
                property:属性名
			id标签的作用和result标签相似,只是专用于主键的映射
        -->
    <id column="user_id" property="userId"/>
    <result column="user_name" property="username"/>
    <result column="password" property="password"/>
</resultMap>

<sql id="user_select_sql">
    select * from t_user
</sql>

<select id="selectUserById" resultMap="userResultMap">
    <include refid="user_select_sql"></include>
    where user_id = #{id}
</select>

注意:resultMap和resultType不能混用

  • select的resultType属性一般写实体类型
  • select的resultMap属性一定要配置成resultMap标签的id值

2 表连接查询

表连接:需要从多张表中查询数据时,此时需要连接查询。

2.1 关系

关联查询的基础是,表和表之间存在关系。

2.1.1 如何记录关系
  1. 在数据库中记录关系:

    使用外键记录表和表之间的关系。

    一般地,一个表的外键通常是另外一张表的主键。

在这里插入图片描述

  1. 在Java应用(实体类)记录关系:

    在实体类中可以定义另外一个类型的属性或者是另外一个类型相关的的List属性。

    外键对应的属性可以不再定义。

在这里插入图片描述

2.1.2 关系的分类
  1. ​ 一对一

    A类型的1个数据对应着B类型的1个数据,反之亦然。
    例如一个人只能有1个护照,反过来这个护照只属于这个人
    
  2. ​ 一对多

    A类型的1数据对应B类型多个的数据。
    例如 一个用户下多个订单,反过来订单只能属于一个用户
    
  3. ​ 多对多

    A类型的1个数据可以对应另外B类型的多个数据,反过来,B类型1个数据也可以对应A类型的多个数据。
    例如 一个学生可以选择多门课程,反过来,一门课程可以被不同的学生选择。
    

2.2 MyBatis表连接的开发思路

    • 使用外键记录关系
    • 如何进行表连接查询
  1. 实体

    • 使用属性记录关系
    • 解决属性定义的问题
  2. 数据转换

    表连接查询的结果转换为有关系的实体对象。

3 一对一关系

    1. 如何记录关系?使用外键

      create table t_people(
          people_id int primary key ,
          people_name varchar(20) not null
      );
      create table t_passport(
          passport_id int primary key,
          serial varchar(20) not null,
          people_id int,
          foreign key (people_id) references t_people(people_id)
      );
      
      insert into t_people values(1,'张3');
      insert into t_people values(2,'李4');
      
      insert into t_passport values(101,'abcdefg',1);
      insert into t_passport values(102,'gfedcba',2)
      

      外键:应该定义在子表中

      父表:先出现的表

      子表:后出现的表

    2. 如何进行表连接查询?

      select 表1.*,表2.*
      from 表1 left join 表2
      on 连接条件;
      
      查询人以及其护照信息
      select p.*,pp.*
      from t_people p left join t_passport pp
      on p.people_id = pp.people_id;
      
  1. 实体

    class People implements Serializable{
        private Integer peopleId;
        private String peopleName;
        private Passport passport;
        //无参构造 get/set
    }
    
    class Passport implements Serializable{
        private Integer passportId;
        private String serial;
        private People people;
        //无参构造  get/set 
        
    }
    

    注意:实体属性要按需定义。

  2. 数据转换

在这里插入图片描述

PeopleMapper.xml
<resultMap type="com.bz.entity.People" id="peopleResultMap">
		<id column="people_id" property="peopleId"/>
		<result column="people_name" property="peopleName"/>
		
		<!-- 将多列映射成一个复杂属性 -->
		<association property="passport" 
			javaType="com.bz.entity.Passport">
			<id column="passport_id" property="passportId"/>
			<result column="passport_serial" property="passportSerial"/>
		</association>
		
	</resultMap>

4 一对多关系

    1. 如何记录关系?使用外键

      create table t_category(
          category_id int primary key ,
          category_name varchar(20) not null unique
      );
      create table t_goods(
          goods_id int primary key ,
          goods_name varchar(20) not null,
          category_id int,
          foreign key (category_id) references t_category(category_id)
      );
      
      insert into t_category values(1,'图书');
      insert into t_category values(2,'数码');
      
      insert into t_goods values(101,'十万个为什么',1);
      insert into t_goods values(102,'MyBatis从入门到精通',1);
      insert into t_goods values(103,'活着最重要',1);
      
      insert into t_goods values(104,'iphone12',2);
      insert into t_goods values(105,'ipad',2);
      insert into t_goods values(106,'macbookpro',2);
      

      注意:在1:N关系下,外键定义在多的一方

    2. 如何写关联查询sql?

    -- 根据一的一方(a)级联查询多个一方(b)
    select a.*,b.*
    from a left join b
    on a.主键 = b.外键;
    
    -- 示例:查询一个类别及类别下所有商品的信息
    select c.*,g.*
    from t_category c left join t_goods g
    on c.category_id = g.category_id;
    
    -- 根据多的一方(b)级联查询一的一方(a)
    select b.*,a.*
    from b left join a
    on b.外键 = a.主键;
    -- 示例:查询所有商品及其类别信息
    select g.*,c.*
    from t_goods g left join t_category c
    on c.category_id = g.category_id;
    
  1. 实体

    public class Category implements Serializable {
        private Integer categoryId;
        private String categoryName;
        
        //该类别下所有商品
        private List<Goods> goods;
        //无参构造 get/set
        
    }
    
    public class Goods implements Serializable {
        private Integer goodsId;
        private String goodsName;
        //无参构造 get/set
    }
    
  2. 数据转换

    <resultMap id="categoryResultMap" type="category">
        <id column="category_id" property="categoryId"/>
        <result column="category_name" property="categoryName"/>
        <collection property="goods" ofType="goods">
            <id column="goods_id" property="goodsId"/>
            <result column="goods_name" property="goodsName"/>
        </collection>
    </resultMap>
    

    注意:多对一查询和一对一查询是一样的,使用association即可!!!

在这里插入图片描述

5 多对多关系

    1. 如何记录关系?使用外键

      create table t_student(
          student_id int primary key,
          student_name varchar(20) not null
      );
      create table t_course(
          course_id int primary key ,
          course_name varchar(20) not null
      );
      
      insert into t_student values(1,'张3');
      insert into t_student values(2,'李4');
      insert into t_student values(3,'王5');
      
      insert into t_course values(101,'语文');
      insert into t_course values(102,'数学');
      insert into t_course values(103,'英语');
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJ9ZXo8c-1672731037813)(MyBatis day02.assets/image-20210606220223447.png)]

      需要使用第3张表记录多对多的关系

      create table t_student_course(
          student_id int,
          course_id int,
          foreign key (student_id) references t_student(student_id),
          foreign key (course_id) references t_course(course_id)
      );
      
      insert into t_student_course values(1,101);
      insert into t_student_course values(1,102);
      insert into t_student_course values(2,102);
      insert into t_student_course values(2,103);
      insert into t_student_course values(3,101);
      insert into t_student_course values(3,103);
      
    2. 如何表连接查询?

      -- 表1级联查询表2
      select 表1.*,表2.*
      from 表1 left join 表3
      on 表1.主键 = 表3.外键1
      left join 表2
      on 表3.外键2 = 表2.主键
      
      -- 示例:查询学员以及其选择的课程的信息
      select s.*,c.*
      from t_student s left join t_student_course sc
      on s.student_id = sc.student_id
      left join t_course c
      on sc.course_id = c.course_id;
      
      -- 表2级联查询表1
      select 表2.*,表1.*
      from 表2 left join 表3
      on 表2.主键 = 表3.外键2
      left join 表1 
      on 表3.外键1 = 表1.主键;
      
      -- 示例:查询课程及选择该课程的学员的信息
      select c.*,s.*
      from t_course c left join t_student_course sc
      on c.course_id = sc.course_id
      left join t_student s
      on sc.student_id = s.student_id;
      
  1. 实体

    class Student implements Serializable {
        private Integer studentId;
        private String studentName;
        
        private List<Course> courses;
        //无参构造 get/set
    }
    
    class Course implements Serializable{
        private Integer courseId;
        private String courseName;
        
        private List<Student> students;
        //无参构造 get/set
    }
    
  2. 数据转换

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-intu80PJ-1672731037813)(MyBatis day02.assets/image-20210606222247936.png)]

    多对多可以看作是双向的一对多。

    <resultMap type="com.bz.entity.Student"
               id="studentResultMap">
        <id column="student_id" property="studentId"/>
        <result column="student_name" property="studentName"/>
    
        <collection javaType="java.util.List" 
                    ofType="com.bz.entity.Course" property="courses">
            <id column="course_id" property="courseId"/>
            <result column="course_name" property="courseName"/>
        </collection>
    
    </resultMap>
    
     id="studentResultMap">
    <id column="student_id" property="studentId"/>
    <result column="student_name" property="studentName"/>
    
    <collection javaType="java.util.List" 
                ofType="com.bz.entity.Course" property="courses">
        <id column="course_id" property="courseId"/>
        <result column="course_name" property="courseName"/>
    </collection>
    
    ```
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斑马有点困

原创不易,多谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值