Mybatis多表查询
1. (回顾)多表之间的关系:
* 一对多:产生关联的方式:在多的一方建立外键,与一的一方的主键进行对应
* 多对一:在mybatis中,多对一被认为是一对一
* 一对一:产生关联的方式
1. 主键映射(让两张表的主键一致) 2. 外键映射(在任一方建立一个外键,与另一方的主键对应)
* 多对多:产生关联的方式:建立中间表(关联两个表的主键)
在Mybatis中,从实体类的角度来说,只有一对一,以及一对多.
一对一:一个丈夫只有一个妻子->在丈夫的实体类中,有一个妻子的对象.
一对多:一个用户有多个订单->在用户的实体类中,设置存储订单的list
多对一:多个订单可以属于一个用户->在订单的类中,设置一个用户对象
多对多:一个教师对应多个学生,一个学生也可以对应多个教师->对于学生以及教师的实体类都是放置了对应多的list
2. mybatis对嵌套对象的封装
2.1 欲对象中包含实体类的对象
* 第一种方式,在实体类的基础上,创建新的实体类继承原来的实体类
* 第二种方式,在原有的实体类中封装对象
当向一个含有对象的对象中封装.需要使用到association
<association property="user" javaType="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<result column="address" property="address"/>
</association>
property对应实体类中的属性
javaType:结果封装成为java实体类的类型
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
2.2 欲对象中包含实体类的list/set等集合
使用collection
<collection property="users" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</collection>
ofType:表示集合中的泛型
* 注意在xml文件中长语句的换行问题
Mybatis的延迟加载
什么是延迟加载:
在真正使用数据的时候才发起查询,不用的时候不查询,按需加载(懒记载)
什么是立即加载:
不管用不用,只要一掉用方法,马上发起查询
在对应关系的四种表关系中:
一对多,多对多(类关系是一对多):多采用延迟加载
多对一,一对一(类关系是一对一):多采用立即加载
xml文件形式
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
注解形式
fetchType=FetchType.LAZY
Mybatis中的缓存
* 一级缓存是sqlsession级别的
可以通过sqlsession的close的方法,或者clearCache方法来清楚缓存
当调用 SqlSession 的修改,添加,删除,commit(),close()等方法的时候,也会清除一级缓存
一级缓存无论是xml配置文件还是注解的方式,都是默认开启的,无需配置
* 二级缓存是sqlsessionfactory级别的
1 二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个
SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
2 二级缓存中,存放的是数据而不是对象,虽然没有发起查询,但是会创建新的对象
3 xml方式开启二级缓存的三个步骤:
1. 在核心文件中开启cache <setting name="cacheEnabled" value="true"/>
因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为
false 代表不开启二级缓存。
2. 在映射文件中开启 <cache/>
3. 在方法上 useCache="true"
注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
4 注解方式开启二级缓存:
1. <setting name="cacheEnabled" value="true"/>
2. 在接口上配置@CacheNamespace
@CacheNamespace(blocking=true)
5 当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这种就可以使用序列化
方式来保存对象。
* 二级缓存可能会不生效:原因是第一次查询完毕没有关闭sqlsession,查询完毕的数据没有存入二级缓存
解决办法:先关闭sqlsession,再次查询.
数据的查询顺序:
一级缓存->二级缓存->数据库