首页 > 其他分享 >mybatis一对多,多对一经典案例及优缺点分析

mybatis一对多,多对一经典案例及优缺点分析

时间:2024-01-20 22:05:02浏览次数:32  
标签:insert cId into 优缺点 案例 values student mybatis class


准备数据

新建俩张表(student表,clalss表)sql语句如下:

create table student(
sId int primary key auto_increment,
sName varchar(20) not null,
cId int not null,
constraint f_sid_cid foreign key(cId) references class(cId)
)engine = innodb,charset=utf8;

create table class(
cId int primary key auto_increment,
cName varchar(20) not null
)engine = innodb,charset=utf8;

填充数据sql语句如下:

insert into class (cName) values('A1871');
insert into class (cName) values('A1872');
insert into class (cName) values('A1873');
insert into class (cName) values('A1874');
insert into class (cName) values('A1875');

insert into student (sName,cId) values('李四',1);
insert into student (sName,cId) values('王五',1);
insert into student (sName,cId) values('可乐',1);
insert into student (sName,cId) values('雪碧',2);
insert into student (sName,cId) values('西红柿',2);

class类

public class Classz implements Serializable {
    private static final long serialVersionUID=1L;
    private Integer cId;
    private String cName;
    private List<Student> students;
    此处省略get set tostring方法.......
}

student类

public class Student implements Serializable {
    private static final long serialVersionUID=1L;
    private Integer sId;
    private String sName;
    private Classz classz;
    此处省略get set tostring方法.......
}

ClassMapper

@Repository
public interface ClassMapper {
    Classz selectClassByCid(@Param("cId") int id);    
    Classz selectClassByCidLazy(@Param("cId") int id);
}

studentMapper

@Repository
public interface StudentMapper {
    //对应的xml的resultType为Student即可,属性会自动填充
    List<Student> selectStudentsByCid(@Param("cId") int id);
    Student selectStudentBySid(@Param("sId") int id);
}

一对多

就是查某个班级信息的同时查询下面的所有学生也就是对应着ClassMapper下的selectClassByCid方法。

方法一:直接写sql语句进行多表联查进行结果集的映射

ClassMapper.xml

1. type: 返回值的类型
2. id标签:用于主键的映射
实体类中的属性名
4. collection:表明返回的结果集是集合,用于多对多映射,多指的是属性property=“students” 是list类型是要进行一一映射结果集的,对多的多指的是有多条数据映射
5. oftype:集合中的类型
查询过程中映射的字段名称
7. result:用于属性的映射
8. javaType: 确定这个属性类型

<mapper namespace="com.zzh.data.mapper.ClassMapper">
    <resultMap id="Classz" type="com.zzh.data.entity.Classz">
        <id property="cId" column="ccId"></id>
        <result property="cName" column="cName"></result>
        <collection property="students" 
        ofType="com.zzh.data.entity.Student"
        javaType="ArrayList">
            <id property="sId" column="sId"></id>
            <result property="sName" column="sName"></result>
        </collection>
    </resultMap>
    <select id="selectClassByCid" resultMap="Classz">
         select c.cName,c.cId as ccId,s.sName,s.sId,s.Cid as scId from class as c
  left join student as s on c.cId = s.Cid
  where c.cId = #{cId};
    </select>
</mapper>

优点

缺点

简单明了的就可以完成对应的需求,结果映射就完事了

对于书写sql语句的水平有一定的要求,其次是如果只是需要拿到班级的名字,而不要拿到对应班级下面的所有学生,那么这种写法一次性的会把所有的数据都查出来并且封装到class类中,这无疑是非常消耗性能的

方法二:逐个开启属性的按需加载功能(懒加载)

ClassMapper.xml

1. fetchType=eager: 表示selectClassByCidLazy的时候立即执行关联的selectStudentsByCid中的sql语句
2. fetchType=lazy: 只有用到students这个属性时,才会执行关联的select中的selectStudentsByCid中的sql语句

<select id="selectClassByCidLazy" resultMap="ClasszLazy">
         select * from class where cId = #{cId};
    </select>
    <!--如果开启了全局的lazy开关,那么不必在一个个的加fetchType="lazy"的属性了-->
    <resultMap id="ClasszLazy" type="com.zzh.data.entity.Classz">
        <id property="cId" column="cId"></id>
        <result property="cName" column="cName"></result>
        <collection property="students"
                    ofType="com.zzh.data.entity.Student"
                    javaType="ArrayList"
                    fetchType="lazy"
                    select="com.zzh.data.mapper.StudentMapper.selectStudentsByCid"
                    column="cId"></collection>
    </resultMap>

studentMapper.xml

返回类型是List,resultType也只需要写list中的类型。多条数据mybatis会自动帮我们进行封装成list

<mapper namespace="com.zzh.data.mapper.StudentMapper">
    <select id="selectStudentsByCid" parameterType="int" resultType="com.zzh.data.entity.Student">
    select * from student where cId = #{cId}
    </select>
</mapper>

优点

缺点

可以实现对属性的按需加载,大大提高的整体项目的性能

配置起来可能比较复杂

方法三:开启全部的属性按需加载(懒加载全局配置)
此时去掉那些fetchType = lazy属性照样懒加载

mybatis:
  mapper-locations: classpath:mapperXml/*.xml
  configuration:
    #开启全局的懒加载 aggressive-lazy-loading: false lazy-loading-enabled: true
    #true 会使带有延时属性的对象立即加载
    #false 每种属性按需加载
    #aggressive-lazy-loading默认为true
    aggressive-lazy-loading: false
    #lazy-loading-enabled默认为false 属性延时加载的开关
    lazy-loading-enabled: true
    #开启mysqlbatis打印sql
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

一对多测试方法一:正常获取数据

mybatis一对多,多对一经典案例及优缺点分析_spring boot

一对多测试方法二:按需获取数据

只有在用到students时才会去DB

mybatis一对多,多对一经典案例及优缺点分析_mybatis_02

一对多测试方法三:按需获取数据

效果和上面的测试方法二一样,读者可以自行去测试

多对一

也就是查询学生的信息的同时去查询对应的所在的班级信息

StudentMapper.xml

  • association:用于一对一映射,一指的是属性property=“classz” 是单个的只需要单个映射结果集,对一的一指的是只有一条数据映射
<mapper namespace="com.zzh.data.mapper.StudentMapper">
    <select id="selectStudentBySid" parameterType="int" resultMap="student">
    select * from student where sId = #{sId}
    </select>
    <resultMap id="student" type="com.zzh.data.entity.Student">
        <id property="sId" column="sId"></id>
        <result property="sName" column="sName"></result>
        <association property="classz" column="cId"
                     javaType="com.zzh.data.entity.Classz">
        </association>
    </resultMap>
</mapper>

多对一测试成功

成功查出了该学生及其所在的班级信息

mybatis一对多,多对一经典案例及优缺点分析_spring boot_03


本文所用测试代码下载链接


标签:insert,cId,into,优缺点,案例,values,student,mybatis,class
From: https://blog.51cto.com/u_16414043/9346300

相关文章

  • springboot+mybatis-plus+redis整合(附上脚手架完整代码)
    首先新建一个springboot项目next到这里的时候,我们可以选择用jdk几,还有就是Group,这个一般就是com.公司名字了,artifact就是项目名字。个人开发我还是喜欢用com.名字前缀哈。到了这一步的话,如果对这个项目有什么别的需求,比如需要用到mybatis啥的可以勾相应的选项。其实就是idea自动帮......
  • 云计算-代码开发流水线及CCE容器集群使用案例
    总结自己在使用华为云商业CI/CD代码流水和CCE容器集群部署案例学无止尽啊新项目构建镜像使用华为codearts代码流水线,详细见官方文档https://support.huaweicloud.com/productdesc-devcloud/devcloud_pdtd_00000.html以部署report-service构建测试镜像为例dockerfile文件前端FRO......
  • MyBatis 系列:MyBatis 源码环境搭建
    目录一、环境准备二、下载MyBatis源码和MyBatis-Parent源码三、创建空项目、导入项目四、编译mybatis-parent五、编译mybatis六、测试总结一、环境准备jdk:17maven:3.9.5二、下载MyBatis源码和MyBatis-Parent源码Mybatis:https://github.com/mybatis/mybatis-3.gitMy......
  • 深入剖析MyBatis缓存机制
    第1章:引言大家好,我是小黑。今天我们要聊的是MyBatis的缓存机制。作为Java开发中经常使用的持久层框架,MyBatis以其灵活性和简便性而广受欢迎。但你知道吗,很多时候,正是因为这些特点,我们需要更深入地理解它的内部工作原理,尤其是缓存机制。这不仅能帮助我们更高效地使用MyBatis,还能......
  • 【Mybatis-Plus】Mybatis-Plus多数据源(三)
    参考官网:多数据源|MyBatis-Plus(baomidou.com)使用方法1、引入dynamic-datasource-spring-boot-starter。1<dependency>2<groupId>com.baomidou</groupId>3<artifactId>dynamic-datasource-spring-boot-starter</artifactId>4&l......
  • 10种经典神经网络结构优缺点
    十种常见的CNN架构LeNet优点:是最早的卷积神经网络之一,对于手写数字识别等小规模图像分类任务表现良好。缺点:对于大规模图像数据集或高维数据处理能力有限。应用场景:手写数字识别、简单的图像分类任务。AlexNet优点:引入了ReLU激活函数和Dropout技术,大幅提高了网络的准确性和稳定性......
  • mybatis-plus作为maven分模块dao层引入的配置
    1.maven分模块说明demo-daodemo-webdemo-web中引用demo-dao层,进行crud2.数据库配置放到哪里?放到demo-web模块的application.propertiesspring.datasource.driver-class-name=@[email protected][email protected]@[email protected]@......
  • 手写 Mybatis-plus 基础架构(工厂模式+ Jdk 动态代理统一生成代理 Mapper)
    这里写目录标题前言温馨提示手把手带你解析@MapperScan源码手把手带你解析@MapperScan源码细节剖析工厂模式+Jdk代理手撕脚手架,复刻BeanDefinitionRegistryPostProcessor手撕FactoryBean代理Mapper在Spring源码中的生成流程手撕MapperProxyFactory手撕增强逻辑Invoca......
  • 关于mybatis批处理那点事
    前言最近在写爬虫的时候,需要定时的将数据爬取然后导入到数据库中(数据量有点大哦),我最开始的写法是这样的,每爬取到一条数据就立即将数据入库,IO了好多次,这样在无形之中给数据库施压了,唉我这个猪队友…不是还有一个叫做批处理的东西存在嘛!!!于是我用批处理的技术优化了一下代码,顺便研究了......
  • 把Mybatis Generator生成的代码加上想要的注释
    1前言在日常开发工作中,我们经常用MybatisGenerator根据表结构生成对应的实体类和Mapper文件。但是MybatisGenerator默认生成的代码中,注释并不是我们想要的,所以一般在Generator配置文件中,会设置不自动生成注释。带来的问题就是自动生成代码之后,我们还要自己去类文件中把注释加......