day04 mybatis 核心

文章详细介绍了在MyBatis中处理对象关系分类,特别是关联关系的建立和保存,如单向多对一的关系。通过示例展示了如何在员工和部门实体类中建立关联,并在XML映射文件中配置SQL,确保在保存数据时能正确获取和插入主键值。此外,还提到了resultMap的使用,以及如何解决N+1查询问题。
摘要由CSDN通过智能技术生成
对象关系分类

泛化关系,实现关系,依赖关系,关联关系,聚合关系,组合关系

使用最多的就是关联关系

单向多对一保存的关系

例子:保存一个部门和两个员工,两个员工属于这个部门

所以需要在员工里面有一个部门的属性

创建员工和部门两个实体类

public class Employee {
private Long id;
private String name;
//关联属性
private Dept dept;
}

此时部门表和员工表都需要同时进行插入数据

将部门的id同时插入到员工表里面,此时只需要给附表添加取主键的属性

deptMapper.xml

<!--
useGeneratadKeys="true":获取数据保存数据的主键值
keyProperty="id": 列名
-->
<insert id="insert" useGeneratadKeys="true" keyProperty="id">
insert into dept values(#{name})
</insert>

EmployeeMapper.xml,可以使用里面的dept属性获取部门的id

<!--主表不用给抽主键的值-->
    <insert id="insert" parameterType="cn.wolfcode.mapper.EmployeeMapper" >
        insert into employee (name,dept_id) values(#{name},#{dept.dept_id})
    </insert>

在测试类里面需要先保存部门才能在保存员工,这样才有部门的id值可以进行返回,穿进去的是一个员工对象

/**
 * 添加员工并且使用从表添加部门编号
 */
@Test
    public void  insert(){
    SqlSession session = MybatisUtil.getSession();
    DeptMapper deptMapper = session.getMapper(DeptMapper.class);
    Dept dept = new Dept();
    dept.setDept_name("研发部");
    //先保存部门
    deptMapper.insert(dept);//这里会返回部门的id,可以使用dept.getid()获取部门的id
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    Employee employee1 = new Employee();
    employee1.setName("小小");
    employee1.setDept(dept);

    Employee employee2 = new Employee();
    employee2.setName("灰灰");
    employee2.setDept(dept);
    //保存员工
    employeeMapper.insert(employee1);
    employeeMapper.insert(employee2);
    session.commit();
    session.close();
单向多对一额外sql查询使用的resultMap标签

方式1,直接使用属性的里面的值,重新给查询结果添加别名

  <resultMap id="emp_resultMap" type="cn.wolfcode.domain.Emp">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="did" property="dept.id"></result>
        <result column="dname" property="dept.name"></result>
    </resultMap>
<select id="selectById" resultType="cn.wolfcode.domain.Emp" resultMap="emp_resultMap">
    select  e.id,e.`name`,d.id did,d.`name` dname
    from employee e
    join department  d
    on e.dept_id=d.id
    where e.id=#{id}
    </select>

方式2

使用多对一查询的时候需要使用sql中的resultMap标签

例子:查询员工及员工的部门

部门表不需要要进行任何处理

<resultMap id="selectAll" type="cn.wolfcode.domain.Employee">
    <id column="id" property="id"></id>
    <result column="name" property="name"></result>
    <association property="dept" javaType="cn.wolfcode.domain.Dept" >
        <id column="dept_id" property="dept_id"></id>
        <result column="dept_name" property="dept_name"></result>
    </association>
</resultMap>
    <select id="select" resultType="cn.wolfcode.domain.Employee" resultMap="selectAll">
        select name,employee.dept_id ,dept.dept_name from employee join dept on employee.dept_id=dept.dept_id
    </select>
resultMap标签及其作用

作用:用于自定义实体类与数据库查询结果集之间的映射关系,可以使用该标签实现查询返回的多个列

参数含义:

<resultMap id="selectAll" type="cn.wolfcode.domain.Employee">
    <id column="id" property="id"></id>
    <result column="name" property="name"></result>

id:给这个resulMap明一个别名

type:这个resoutMap的映射类型

<id column="id" property="id"></id>

表示主键字段或者属性在数据库中的列名

colum:查询出来的列名的名字,可以重新命名

property:主键对应的实体类属性名

 <result column="name" property="name"></result>

表示普通字段或者属性在数据库中的列名

colum:查询出来的列名的名字,可以重新命名

property:实体类的普通属性名

association标签

他是在resultMap标签之中的,一个表查一个的时候使用association

 <association property="dept" javaType="cn.wolfcode.domain.Dept" >
      <id column="dept_id" property="dept_id"></id>
        <result column="dept_name" property="dept_name"></result>
    </association>

在单向多对一查询使用,即一个属性通过另一个sql查询的实体类对象得到

property:指定当前属性在这个实体类中对应的那一个属性名,一般这个属性是由另一个实体类定义而来

javaType:定义这个属性名的实体类的全限定名

里面的,标签就对应这个表名的列名和这个实体类的属性

collection标签

他是在resultMap标签之中的,求list集合的时候使用collection

<resultMap id="stu_teacher_resultMap" type="cn.wolfcode.domain.Stu">
        <!--id标签表示的主键-->
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <!--
        property:stu中的属性
        ofType:teachers本身的类型
        javaType:teachers在stu中的类型
        -->
        <collection property="teachers" javaType="list" ofType="cn.wolfcode.domain.Teacher">
            <id property="id" column="tid"></id>
            <result property="name" column="tname"></result>
        </collection>
    </resultMap>
    <!--
    使用resoutMap进行查询
    -->
<select id="get" resultType="cn.wolfcode.domain.Stu" resultMap="stu_teacher_resultMap">
    select stu.*,teacher.id tid,teacher.name tname
    from stu
        join stu_teacher
        on stu.id=stu_teacher.sid
        join teacher
        on stu_teacher.tid=teacher.id
    where stu.id=#{id}
    </select>

在一对多或者多对多查询的时候使用,一个属性有多个关联的是实体类对象

property:指定当前关联的实体对象属性

javaType:定义这个属性名的实体类的全限定名

oftype:指定集合元素的类型,使用这个自定义属性名的全限定名

select:指定执行sql语句的id(就是其他xxxMapper中的接口中的方法名,和这个属性相互对应)

 <resultMap id="stu_resoutMap"  type="cn.wolfcode.domain.Stu">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <!--这里的select关联到teacher上的查询条件,将这个id传到另一个mapper-->
   <collection column="id" property="teachers" select="cn.wolfcode.mapper.TeacherMapper.queryByStudentid"  />
    </resultMap>

column="id":指定了当前对象在 SQL 语句查询结果集中的列名,这个列名用于匹配关联对象的外键

property="teachers":指定了当前对象(即父对象)中集合类型属性的名称,也就是要将关联对象赋值给哪个属性。

select:这里使用了另一个 Mapper 接口中定义的 ID 为 “queryByStudentid” 的查询方法。

什么是n+1问题及解决办法

出现的原因:若某个查询条件反回了多个结果,并且这些结果又对应了另外一个查询条件的多行结果,此时就会发生n+1次查询的情况

**解决办法:**一般使用关联查询,将多张表进行联合起来进行查询,避免单独查询利用标签和

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值