Mybatis使用笔记(二)

Mybatis查询之resultMap的使用

使用result的高级功能,一对一映射、一对多映射以及多对多映射
一对一映射对应的标签为association,一对多映射对应的标签为collection
一对一映射使用包装对象实现,例如:要查找学生和班级,但是学生信息以及班级信息在两个类中,可以将班级类型作为一个对象包装进入学生类中

@Data
public class Student {
    private Integer id;
    private String studentName;
    private String studentSex;
    private Integer studentClass;
    private Integer studentAge;

    private ClassEntity classEntity;
}

association和collection二者标签的内部属性基本是一致的,它们的属性介绍如下:

  • (常用)property:映射 实体类属性名。
  • (常用)column:映射数据库字段名或者其别名(这个别名是数据库起的,如 select username as name)。
  • (常用)javaType:映射java类型。
  • (常用)jdbcType:映射数据库类型。
  • (常用)ofType:映射集合的类型(注意:javaType是用来指定pojo中属性的类型,而ofType指定的是映射到list集合属性中pojo的类型,也就是尖括号的泛型private List users)。
  • (常用)select:用于加载复杂类型属性的映射语句的id(全限定名加方法,方法名后面无括号,例如:com.thr.mapper.UserMapper.selectAllUser),它会从column 属性指定的列中检索数据,作为参数传递给目标 select 语句。
  • (常用)fetchType:延迟加载,lazy打开延迟加载,eager积极加载。指定属性后,将在映射中忽略全局配置参数lazyLoadingEnabled,使用属性的值。
  • resultMap:不使用嵌套模式,而是将此关联的嵌套结果集映射到一个外部的标签中,然后通过 id 进行引入。
  • resultSet:指定用于加载复杂类型的结果集名字。
  • autoMapping:自动封装,如果数据库字段和javaBean的字段名一样,可以使用这种方式,但是不建议采取,如果非要使用此功能,那就在全局配置中加上mapUnderscoreToCamelCase=TRUE,它会使经典数据库字段命名规则翻译成javaBean的经典命名规则,如:a_column翻译成aColumn。
  • columnPrefix:关联多张表查询时,为了使列明不重复,使用此功能可以减少开发量。
  • foreignColumn:指定外键对应的列名,指定的列将与父类型中 column 的给出的列进行匹配。
  • notNullColumn:不为空的列,如果指定了列,那么只有当字段不为空时,Mybatis才会真正创建对象,才能得到我们想要的值。
  • typeHandler:数据库与Java类型匹配处理器(可以参考前面的TypeHandler部分)。

一对一映射

嵌套查询

映射xml语句

    <resultMap id="StudentClassMap" type="com.spring.demo.entity.Student">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="student_name" property="studentName" jdbcType="VARCHAR"/>
        <result column="student_sex" property="studentSex" jdbcType="VARCHAR"/>
        <result column="student_age" property="studentAge" jdbcType="INTEGER"/>
        <result column="student_class" property="studentClass" jdbcType="INTEGER"/>
        <!--一对一关联对象-->
        <!--property:映射实体类属性名字-->
        <!--javaType:映射Java类型-->
        <association property="classEntity" javaType="com.spring.demo.entity.ClassEntity">
            <!--property和column表示映射实体类和其表中字段绑定-->
            <!--此处有一个小问题,就是如果id为 <id property="id" column="id"/> 时,会出现查询结果中的id是学生的id,className没有错误-->
            <id property="classId" column="class_id"/>
            <result property="className" column="class_name"/>
        </association>
    </resultMap>
    <!--查询所有数据-->
    <select id="selectStudentClass" resultMap="StudentClassMap">
        select * from
        student_table s,
        class_table c
        where
        s.student_class = c.class_id
    </select>
    <!--根据学生id查找其信息-->
    <select id="selectStudentClassById" parameterType="java.lang.Integer" resultMap="StudentClassMap">
        select * from
        student_table s,
        class_table c
        where
        s.student_class = c.class_id
        and s.id = #{id}
    </select>

分布查询

    <!--分布查询-->
    <resultMap id="StudentClassMap2" type="com.spring.demo.vo.StudentVo">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="student_name" property="studentName" jdbcType="VARCHAR"/>
        <result column="student_sex" property="studentSex" jdbcType="VARCHAR"/>
        <result column="student_age" property="studentAge" jdbcType="INTEGER"/>
        <result column="student_class" property="studentClass" jdbcType="INTEGER"/>
        <!--column为student表中班级字段, property为StudentVo类中班级类名,javaType为班级类,select指定通过id查询班级的接口-->
        <association column="student_class" property="classEntity" javaType="com.spring.demo.entity.ClassEntity"
                    select="com.spring.demo.dao.ClassDAO.selectById"/>

    </resultMap>
    
    <select id="selectStudentClassById_" parameterType="java.lang.Integer" resultMap="StudentClassMap2">
        select * from
        student_table
        where
        id = #{id}
    </select>
// studentVo类
@Data
// 作用是在 json 序列化时忽略 bean 中的一些不需要转化的属性
@JsonIgnoreProperties(value = { "handler" })
public class StudentVo {
    private Integer id;
    private String studentName;
    private String studentSex;
    private Integer studentClass;
    private Integer studentAge;

    private ClassEntity classEntity;
}

总结

分布查询会比嵌套查询多执行几个sql,所以效率上是嵌套查询更好,但是分布查询可以延迟加载(懒加载)

一对多映射

嵌套查询

    <resultMap id="ClassStudentMap" type="com.spring.demo.vo.ClassEntityVo">
        <id column="class_id" property="classId"/>
        <result column="class_name" property="className"/>
        <!--一对多映射-->
        <!--ofType:指定pojo的类型,为list尖括号内部的泛型-->
        <collection property="students" ofType="com.spring.demo.entity.Student">
            <id column="id" property="id"/>
            <result column="student_name" property="studentName"/>
            <result column="student_sex" property="studentSex"/>
            <result column="student_age" property="studentAge"/>
            <result column="student_class" property="studentClass"/>
        </collection>
    </resultMap>
	<!--查询所有班级学生-->
    <select id="selectClassStudent" resultMap="ClassStudentMap">
        select * from
        class_table c,
        student_table s
        where
        c.class_id = s.student_class
    </select>
    <!--通过班级id查询班级学生-->
    <select id="selectClassStudentById" parameterType="java.lang.Integer" resultMap="ClassStudentMap">
        select * from
        class_table c,
        student_table s
        where
        c.class_id = s.student_class
        and c.class_id = #{classId}
    </select>

分布查询

    <resultMap id="ClassStudentMap2" type="com.spring.demo.vo.ClassEntityVo">
        <id column="class_id" property="classId"/>
        <result column="class_name" property="className"/>
        <collection column="class_id" property="students" ofType="com.spring.demo.entity.Student"
                    select="com.spring.demo.dao.StudentDAO.selectByClass"/>
    </resultMap>
    
    <!--分布查询,通过班级id查询班级学生-->
    <select id="selectClassStudentById_" parameterType="java.lang.Integer" resultMap="ClassStudentMap2">
        select * from class_table
        where class_id = #{classId}
    </select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值