Mybatis

发布时间:2024年01月05日
MyBatis映射文件_<resultMap>

在常规的CRUD中,POJO大多数属性都是基本类型,但是稍微复杂一点的项目,便会出现引用类型,那么普通的SQL就不容易处理了,幸好Mybatis提供了一个非常强大的工具——resultMap

MyBatis映射文件中除了 <insert> 、 <delete> 、 <update> 、 <select> 外,还有一些标签可以使用:

本小节主要来记录 <resultMap>

标签的作用:自定义映射关系

MyBatis可以将数据库结果集封装到对象中,是因为结果集的列名和对象属性名相同:

在这里插入图片描述

当POJO属性名和数据库列名不一致时,MyBatis无法自动完成映射关系。如:

在这里插入图片描述

此时有两种解决方案:

①Sql语句的查询字段起与POJO属性相同的别名。

<select id="findAll" resultType="com.nucty.pojo.Teacher">
select tid as id,tname as teacherName from teacher;
</select>

②自定义映射关系

<!-- 在select标签中,使用resultMap属性代替resultType属性,使用自定义映射关系。 -->
<select id="findAll" resultMap="teacherMapper">
    select * from teacher
</select>

<resultMap id="teacherMapper" type="com.nucty.pojo.Teacher">
    <!-- id定义主键列 property:POJO属性名 column:数据库列名 -->
    <id property="id" column="tid"></id>
    <!-- result定义普通列 property:POJO属性名 column:数据库列名 -->
    <result property="teacherName" column="tname"></result>
</resultMap>
<MyBatis一对一关联查询>

查询班级时,将关联的一个老师对象查询出来,就是一对一关联查询。【虽然班级和老师是多对多的关系,但是数据库中一个班级对应的是一个老师去模拟一对一的关联查询】

创建持久层接口

@Mapper
public interface IClassDao {
    public Classs getClass(Integer id); 
}

创建映射文件

<select id="getClass" parameterType="Integer" resultMap="ClassResultMap">
    select *
    from class c,
         teacher t
    where c.teacher_id = t.t_id
      and c.c_id = #{id}
</select>

<resultMap id="ClassResultMap" type="nuc.ty._20231202myatis.pojo.Classs">
    <!-- id定义主键列 property:POJO属性名 column:数据库列名 -->
    <id property="id" column="c_id"></id>
    <!-- result定义普通列 property:POJO属性名 column:数据库列名 -->
    <result property="name" column="c_name"></result>
    <!-- 一对一对象列 property:属性名 column:关联列名 javaType:对象类型-->
    <association property="teacher" column="teacher_id" javaType="nuc.ty._20231202myatis.pojo.Teacher">
        <!-- 关联对象主键列 -->
        <id property="id" column="t_id"/>
        <!-- 关联对象普通列 -->
        <result property="name" column="t_name"/>
    </association>
</resultMap>

现给出另外一种实现方式,观察区别

<select id="getClass2" parameterType="integer" resultMap="ClassResultMap2">
    select *
    from class
    where c_id = #{id}
</select>

<resultMap id="ClassResultMap2" type="nuc.ty._20231202myatis.pojo.Classs">
    <id property="id" column="c_id"/>
    <result property="name" column="c_name"/>
    <!-- 一对一对象列 
        property:属性名 
        column:关联列名 
        javaType:对象类型 
        select:指定映入嵌套查询的子 SQL 语句,即使用另一个查询封装的结果。
	-->
    <association property="teacher" column="teacher_id" javaType="nuc.ty._20231202myatis.pojo.Teacher"
                 select="getTeacher">
    </association>
</resultMap>

<select id="getTeacher" parameterType="Integer" resultType="nuc.ty._20231202myatis.pojo.Teacher">
    select t_id id, t_name name
    from teacher
    where t_id = #{id}
</select>

其区别在于嵌套查询和嵌套结果查询【着重关注一下sql语句的区别】

嵌套查询 是指通过执行另外一条 SQL 映射语句来返回预期的复杂类型;

嵌套结果 是使用嵌套结果映射来处理重复的联合结果的子集。

嵌套查询嵌套结果
嵌套查询是在查询 SQL 后再进行一个(子)查询嵌套结果是一个多表查询的 SQL 语句
会执行多条 SQL 语句只有一条复杂的 SQL 语句(多表连接)
SQL语句编写较为简单SQL语句编写较为复杂

参考链接:Mybatis 的嵌套查询与嵌套结果的区别 - 东郊 - 博客园 (cnblogs.com)

<MyBatis一对多关联查询>

查询一个部门下的员工信息【模拟一对多关联查询】
创建持久层接口

@Mapper
public interface IDeptDao {
    public Dept findByDeptno(Integer deptno);
}

创建映射文件

<mapper namespace="nuc.ty._20231202myatis.dao.IDeptDao">
    <!--根据部门编号查询员工 -->
    <select id="findByDeptno" parameterType="Integer" resultMap="deptMap">
        select *
        from dept
        where deptno = #{deptno}
    </select>
    
    <resultMap type="nuc.ty._20231202myatis.pojo.Dept" id="deptMap">
        <id property="deptno" column="deptno"/>
        <result property="dname" column="dname"/>
        <result property="location" column="loc"/>
        <!-- collection:一对多关联映射
        根据部门deptno先读取部门信息,然后再读取这个部门所有的用户信息。
         property表示集合类型属性名称,也就是Dept实体类中定义的员工List名字
         ofType表示集合中的对象的类型-->
        <collection property="emps" javaType="ArrayList"
                    ofType="nuc.ty._20231202myatis.pojo.Emp"
                    column="deptno"
                    select="nuc.ty._20231202myatis.dao.IEmpDao.findByDeptno">
        </collection>
    </resultMap>
</mapper>
<mapper namespace="nuc.ty._20231202myatis.dao.IEmpDao">
	<!--根据deptno查询员工-->
    <select id="findByDeptno" parameterType="Integer"
            resultType="nuc.ty._20231202myatis.pojo.Emp">
        select * from emp
        where deptno=#{deptno}
    </select>
</mapper>

<collection>子元素属性大部分与<association>元素相同,但其还包含一个特殊属性-ofType 属性,ofType 属性与< association>中的javaType属性对应,用于指定实体对象中集合类属性所包含的元素类型。

举例说明:

在一对一关联查询中,javaType雀雀实实指的是对象的类型。

在这里插入图片描述

而在一对多关联查询中,ofType指的是实体对象中集合类属性所包含的元素类型即Emp,而javaType指的是集合类型,一般指ArrayList。

在这里插入图片描述

文章来源:https://blog.csdn.net/m0_64280569/article/details/135362845
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。