MyBatis常用级联查询(association,collection)和动态sql(foreach)的简单使用

本文介绍了MyBatis中的级联查询(association, collection)和动态SQL(foreach)的简单使用示例,包括教师-班级-学生的关系模型、一对多查询映射配置以及动态SQL在in查询中的应用。" 109362220,8527557,MySQL高级知识入门:配置文件与存储引擎解析,"['数据库理论', 'MySQL', '存储引擎', 'SQL']

前言

MyBatis是一个非常优秀的持久层框架,从工作开始基本所有接触的项目使用的都是MyBatis框架,个人感觉它的优点就是轻量级,易配置,sql自由,结果集映射功能强大。除了使用起来舒服,MyBatis的整体设计理念也是很优秀的,清晰的分层设计,对于设计模式的使用,也是值得学习和思考的,虽然自己目前对于其中一些设计理念还难以理解。

当前想详细介绍和总结一下自己常用到的级联查询和动态sql几个场景。虽然比较简单,但是每次写的时候都要查资料,所以自己记录一下。

业务相关数据模型

一个简单的教师-班级-学生 关系数据模型

级联查询示例

  • 业务场景

    根据上述数据模型,需求是查询某个班级的班级名称、班主任名和所有的学生名。

  • 定义返回数据模型

    定义需求所需要数据的VO实体

    public class ClassInfoVO {
        private Long id;
        private String className;
        private String headTeacherName;
        private List<String> studentName;
       
        /**
         *  getter/setter
         */
    }
    
  • 定义mapper接口

    public interface TClassMapper {
        ClassInfoVO getDetail(@Param("id") Long id);
    }
    
  • 映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.learn.mybatiscrud.mapper.TClassMapper">
    
        <resultMap id="classInfoMapper" type="com.learn.mybatiscrud.vo.ClassInfoVO">
            <id property="id" column="id"/>
            <result property="className" column="name"/>
            <association property="headTeacherName" column="head_teacher_id" select="com.learn.mybatiscrud.mapper.TeacherMapper.getTeacherName"></association>
            <collection property="studentName" column="id" select="com.learn.mybatiscrud.mapper.TStudentMapper.getStudentList"></collection>
        </resultMap>
        <select id="getDetail" resultMap="classInfoMapper">
            select * from t_class where id=#{id}
        </select>
    
    </mapper>
    
    

    分析:

    resultMap可以实现将查询结果映射为较复杂的结果对象(ClassInfoVO),其中resultMap中的property对应的就是ClassInfoVO的属性,colum对应的是数据表字段名称,即select * from中的 *部分。
    其中association和collection标签分别表示一对一和一对多的查询,分别有三个属性,property,colum,select。这里怎么理解呢,既然是叫结果集映射嘛,本质就是将数据库查询的结果和定义的VO字段一一映射起来,property代表的还是VO字段,只不过这里colum值和property值没直接映射起来,而是多做了一次查询,查询的方法是另一个mapper接口方法,接口参数值就是colum的值,然后再把这次查询的结果和property映射起来。

  • resultMap的select方法和映射文件

    mapper接口

    public interface TeacherMapper {
        String getTeacherName(@Param("id") Long id);
    }
    
    public interface TStudentMapper {
        /**
         * 通过班级ID查询该班级所有学生名称
         * @param classId
         * @return
         */
        List<String> getStudentList(Long classId);
    }
    

    映射文件:
    TeacherMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.learn.mybatiscrud.mapper.TeacherMapper">
        <select id="getTeacherName" resultType="String">
            select name from t_teacher where id=#{id}
        </select>
    
    </mapper>
    

    TStudent.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.learn.mybatiscrud.mapper.TStudentMapper">
        <select id="getStudentList" resultType="String">
            select name from t_student where class_id=#{classId}
        </select>
    
    </mapper>
    
    

    这部分就非常简单了,通过t_class表中的head_teacher_id,从t_teacher表中查出教师名称,这个是一对一的查询。通过t_class表中的id,从t_student表中查出属于该班级所有学生的名称,结果就是一个List,这是一对多的查询。

动态sql(foreach)使用示例

动态sql是MyBatis一大特色,MyBatis 采用功能强大的基于 OGNL 的表达式来实现动态sql,用了很多简练易用的标签屏蔽sql拼接细节,真的很舒服。常用的标签有 if test, where之类的。我只想记录一下foreach标签的使用,因为老是忘记。

  • 业务场景

来个最简单的示例吧,查询某些老师的信息,就是一个简单的 in 查询。

  • 定义返回数据模型

    public class Teacher {
        private Long id;
        private String name;
        private String title;
        /**
       	 * getter setter
      	 * /
     }
    
  • mapper接口

    public interface TeacherMapper {
        List<Teacher> getTeacherInfo(List<Long> ids);
    }
    
  • 映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.learn.mybatiscrud.mapper.TeacherMapper">
        <select id="getTeacherInfo" resultType="com.learn.mybatiscrud.entity.Teacher">
            select * from t_teacher
            where id in
            <foreach collection="list" item="item" index="index"
                     open="(" separator="," close=")">
                #{item}
            </foreach>
        </select>
    </mapper>
    

collection:代表要循环的对象
item:代表当前迭代对象
index:代表当前迭代索引(即 0,1,2 …)
open,close:代表循环开始和结束插入的符号
separator:表示每次循环插入的符号。

值得说明的是collection里面的值,是根据mapper接口确定的,如果接口传入List对象,并且没有给方法参数指定key值,那么collection的值默认是list,如果接口传入的是数组,那么collection的值默认是array。
但是如果在mapper接口方法指定了key值,那么collection的值就是key值。
如:

	public interface TeacherMapper {
	    List<Teacher> getTeacherInfo(@Param("ids") List<Long> ids);
	}

则 collection=“ids”

后记

MyBatis还有其他很多知识需要学习,如缓存,事务等,但是感觉最需要学习的整个框架的设计思想,各模块的内聚和耦合,恰恰这个最难的。

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值