目录
开发步骤
1、映射文件
- 引入jar包:mysql及mybatis
- 创建全局配置文件mybatis-config.xml,配置数据源、引入映射文件等
- 创建映射文件MajorMapper.xml
- 编写测试类
- 获取SqlSession对象
- 调用SqlSession对象的增删改查方法实现专业信息的基本操作
2、接口引用
- 引入jar包:mysql及mybatis
- 创建全局配置文件mybatis-config.xml,配置数据源、引入映射文件等
- 创建映射文件MajorMapper.xml及映射接口MajorMapper,二者对应
- 编写测试类
- 获取SqlSession对象
- 调用SqlSession对象的getMapper方法,获取MajorMapper应用对象
- 调用MajorMapper的方法实现增删改查专业功能
3、注解开发
- 引入jar包:mysql及mybatis
- 创建全局配置文件mybatis-config.xml,配置数据源、引入映射文件等
- 创建映射接口MajorMapper,添加增删改查注解
- 编写测试类
- 获取SqlSession对象
- 调用SqlSession对象的getMapper方法,获取MajorMapper引用对象
- 调用MajorMapper的方法实现增删改查专业功能
<resultMap>元素
<resultMap>元素表示结果映射集,是MyBatis中最重要也是最强大的元素。
作用:定义映射规则、级联的更新以及定义类型转化器等。
<resultMap type="" id="">
<constructor> <!-- 类在实例化时,用来注入结果到构造方法中-->
<idArg/> <!-- ID参数;标记结果作为ID-->
<arg/> <!-- 注入到构造方法的一个普通结果-->
</constructor>
<id/> <!-- 用于表示哪个列是主键-->
<result/> <!-- 注入到字段或JavaBean属性的普通结果-->
<association property="" /> <!-- 用于一对一关联 -->
<collection property="" /> <!-- 用于一对多关联 -->
<discriminator javaType=""> <!-- 使用结果值来决定使用哪个结果映射-->
<case value="" /> <!-- 基于某些值的结果映射 -->
</discriminator>
</resultMap>
为什么学习MyBatis关联关系?
实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好的处理对象与对象之间的关联关系。本章中,将对MyBatis的关联关系映射进行详细的讲解。
在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多:
一对一:在任意一方引入对方主键作为外键;
一对多:在“多”的一方,添加“一”的一方的主键作为外键;
多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键。
在Java中,通过对象也可以进行关联关系描述,如右图所示:
一对一:在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a;
一对多:一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a;
多对多:在A类中定义B类类型的集合,在B类中定义A类类型的集合。
一对一关联查询
在现实生活中,一对一关联关系是十分常见的。例如:
那么使用MyBatis是怎么处理图中的这种一对一关联关系的呢?
<resultMap>元素中,包含了一个<association>子元素,MyBatis就是通过该元素来处理一对一关联关系的。
一对一:
<association>元素的相关属性
property:指定映射到的实体类对象属性,与表字段一一对应
column:指定表中对应的字段
javaType:指定映射到实体对象属性的类型
select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询
fetchType:指定在关联查询时是否启用延迟加载。该属性有lazy和eager两个属性值,默认值为lazy(即默认关联映射延迟加载)
嵌套查询与嵌套结果
MyBatis加载关联关系对象主要通过两种方式:嵌套查询和嵌套结果。
第一种
嵌套查询是通过执行另外一条SQL映射语句来返回预期的复杂类型。
- 嵌套查询是在查询SQL中嵌入一个子查询SQL;
- 嵌套查询会执行多条SQL语句;
- 嵌套查询SQL语句编写较为简单;
第二种
嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。
- 嵌套结果是一个嵌套的多表查询SQL;
- 嵌套结果只会执行一条复杂的SQL语句;
- 嵌套结果SQL语句编写比较复杂;
嵌套查询:
<!--嵌套查询-->
<select id="getStudent" parameterType="String" resultMap="getStudentAndTeacher">
select * from java2022 where num=#{num}
</select>
<resultMap id="getStudentAndTeacher" type="Student">
<id property="num" column="num"></id>
<result property="name" column="name"></result>
<result property="department" column="department"></result>
<result property="average" column="average"></result>
<result property="pwd" column="pwd"></result>
<result property="mobile" column="mobile"></result>
<result property="email" column="email"></result>
<association property="tclass" column="tclass" javaType="Teacher" select="mapper.TeacherMapper.getTeacher"/>
</resultMap>
嵌套结果:
<!-- 嵌套结果-->
<select id="getStudent2" parameterType="String" resultMap="getStudentAndTeacher2">
select j.*,t.t_name,t.t_id
from java2022 j,teacher t
where j.tclass=t.t_id and j.num=#{num}
</select>
<resultMap id="getStudentAndTeacher2" type="Student">
<id property="num" column="num"></id>
<result property="name" column="name"></result>
<result property="department" column="department"></result>
<result property="average" column="average"></result>
<result property="pwd" column="pwd"></result>
<result property="mobile" column="mobile"></result>
<result property="email" column="email"></result>
<association property="tclass" javaType="Teacher" >
<id property="t_id" column="t_id"></id>
<result property="t_name" column="t_name"></result>
</association>
</resultMap>
提出问题?
虽然使用嵌套查询的方式比较简单,但是嵌套查询的方式要执行多条SQL语句,这对于大型数据集合和列表展示不是很好,因为这样可能会导致成百上千条关联的SQL语句被执行,从而极大的消耗数据库性能并且会降低查询效率。
那怎么解决呢?
MyBatis延迟加载的配置
使用MyBatis的延迟加载在一定程度上可以降低运行消耗并提高查询效率。MyBatis默认没有开启延迟加载,需要在核心配置文件中的<settings>元素内进行配置,配置如下:
<settings>
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
在映射文件中,<association>元素和<collection>元素中都已默认配置了延迟加载属性,即默认属性fetchType="lazy"(属性fetchType="eager"表示立即加载),所以在配置文件中开启延迟加载后,无需在映射文件中再做配置。
一对一关联映射
一对多
开发人员接触更多的关联关系是一对多(或多对一)。例如,一个用户可以有多个订单,同时多个订单归一个用户所有。
使用MyBatis是怎么处理这种一对多关联关系的呢?
MyBatis就是通过<resultMap>元素的子元素<collection>来处理一对多关联关系的。
<collection>子元素的属性大部分与<association>元素相同,但其包含一个特殊属性--ofType ,它与javaType属性对应,用于指定实体对象中集合类属性所包含的元素类型。
一对多关联映射
多对多
在数据库中,多对多的关联关系通常使用一个中间表来维护,中间表中的订单id作为外键参照订单表的id,商品id作为外键参照商品表的id。
多对多关联查询
在MyBatis中,多对多的关联关系查询,同样可以使用前面介绍的<collection >元素进行处理(其用法和一对多关联关系查询语句用法基本相同)
缓存
什么是缓存 [ Cache ]?
MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存
一级缓存:sqlsession
二级缓存:xxx.xml
缓存原理
=========================================================================
实验 Lab10
=======================================================================
补充:
映射文件配置在config.xml
接口方法:
1、接口文件:抽象方法用id
2、映射文件方法:存放SQL语句
映射方法:
1、db.property
2、映射文件
注解方式:
接口文件:SQL语句放在抽象方法上:@value
<id>主键
<result>非主键
<association>一对一关联
<collection>集合