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

文章目录

    • 前言
    • 业务相关数据模型
    • 级联查询示例
      • 业务场景
      • 定义返回数据模型
      • 定义mapper接口
      • 映射文件
      • resultMap的select方法和映射文件
    • 动态sql(foreach)使用示例
      • 业务场景
      • 定义返回数据模型
      • mapper接口
      • 映射文件
    • 后记

前言

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

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

业务相关数据模型

一个简单的教师-班级-学生 关系数据模型
MyBatis常用级联查询(association,collection)和动态sql(foreach)的简单使用_第1张图片

级联查询示例

  • 业务场景

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

  • 定义返回数据模型

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

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

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

    
    
    
    
        
            
            
            
            
        
        
    
    
    
    

    分析:

    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 getStudentList(Long classId);
    }
    

    映射文件:
    TeacherMapper.xml

    
    
    
        
    
    
    

    TStudent.xml

    
    
    
        
    
    
    
    

    这部分就非常简单了,通过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 getTeacherInfo(List ids);
    }
    
  • 映射文件

    
    
    
        
    
    

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 getTeacherInfo(@Param("ids") List ids);
	}

则 collection=“ids”

后记

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

你可能感兴趣的:(数据库,Java后端)