01_今日课程安排
-
延迟加载和立即加载的概念
-
Mybatis中的缓存
1.什么是缓存
2.为什么使用缓存
3.什么样的数据能使用缓存,什么样的数据不能使用
4.Mybatis中的一级缓存和二级缓存 -
Mybatis中的注解开发
1.环境搭建
2.单表的CRUD操作(代理Dao方式)
3.多表查询操作
4.缓存的配置
学习目标 -
能够使用mybatis的延迟加载
-
能够使用mybatis的一级缓存二级缓存
-
能够掌握mybatis中的注解开发
02_延迟加载和立即加载的概念
问题:
在一对多中,当我们有一个用户,它有100个账户。
在查询用户的时候,要不要把关联的账户查出来?
在查询账户的时候,要不要把关联的用户查出来?
回答
在查询用户时,用户下的账户信息应该是,什么时候使用,什么时候查询的。
在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。
什么是延迟加载
在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
什么是立即加载
不管用不用,只要一调用方法,马上发起查询。
在对应的四种表关系中:一对多,多对一,一对一,多对多
一对多,多对多:通常情况下我们都是采用延迟加载。
多对一,一对一:通常情况下我们都是采用立即加载。
03_mybatis一对一实现延迟加载
- 配置AccuntDao.xml
- 这个地方,各个属性代表什么,搞混了,逻辑还算清晰,知道要干什么
<!-- 一对一的关系映射,配置封装user内容
select属性指定的内容,查询用户的唯一标识
column属性指定的内容,查询用户的唯一标识
用户根据id查询时,所需要的参数的值,
就是关联的那个表,where查询条件
-->
<association property="user" column="uid" javaType="user" select="com.itheima.dao.UserDao.findOneUser">
</association>
- 配置UserDao.xml
<select id="findOneUser" parameterType="Integer" resultType="User">
select * from user where id=#{id};
</select>
- 配置SqlMapConfig.xml
<!-- 配置参数-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
05_缓存的概念
一级缓存的概念
清空一级缓存
- 代码实现:
@Test
public void testFistLevelCache() {
User user1 = userDao.findOneUser(41);
System.out.println(user1);
// session.close();
//再次获取session对象
// session = factory.openSession();
//使用SqlSession创建Dao接口的代理对象
session.clearCache();//此方法也可以清空缓存
userDao = session.getMapper(UserDao.class);
User user2 = userDao.findOneUser(41);
System.out.println(user2);
System.out.println(user1 == user2);
}
在测试类当中清空,这个地方感觉挺简单,
自动清空一级缓存的情况
二级缓存:
它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
二级缓存的使用步骤:
二级缓存没有敲代码,因为就有些许的烦,不敲了
- 第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
- 第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
- 第三步:让当前的操作支持二级缓存(在select标签中配置)
012_mybatis注解开发CRUD
这个地方还挺简单,一共有四个注解
@Select
@Select("select * from user where id=#{id}")
@Update
@Delect
@Insert
013_mybatis注解当建立实体类属性和数据库表中列名称不对应时
- 使用@Results
- value={}里面放一个集合
- id = true主键
- @Result集合中成员
- column数据库列名
- property实体类属性
- id = “userMap” 唯一标识,其他的抽象方法也可以用,用@ResultMap(“userMap”),
- 正确形式@ResultMap(value={“userMap”}),当里面就一个条件时,value属性可省略
代码如下
@Results(id = "userMap", value = {
@Result(id = true, column = "id", property = "userId"),
@Result(column = "username", property = "userName"),
@Result(column = "address", property = "userAddress"),
@Result(column = "sex", property = "userSex"),
@Result(column = "birthday", property = "userBirthday")
})
@ResultMap("userMap")
014_mybatis注解开发一对一的查询配置
前提:查询账户时,把用户信息查询出来。
- 首先配置在账户接口中,抽象方法上配置,用@Results
- 先配置账户表的信息(实体类和数据库列名一一对应)
- 然后配置关联的用户表
@Result(property ="user",column = "uid",)
- property :account实体类中定义的那个属性名称
- column :我感觉写的应该是外键,这个地方有些许的迷茫
- 接下来配置一对一和立即加载延迟加载
- 大部分一对一和多对一都使用立即加载
one = @One(select = "com.itheima.dao.UserDao.findOneUser", fetchType = FetchType.EAGER))
- one:代表一对一
- select:里面写的关联的那个表.类名称.方法名,相当于把两个方法给串联到一起了
- fetchType :是设置立即加载还是延迟加载用的
总结
public @interface Result {
boolean id() default false;主键
String column() default "";数据库列名
String property() default "";实体类属性名
Class<?> javaType() default void.class;
JdbcType jdbcType() default JdbcType.UNDEFINED;
Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
One one() default @One;一对一,多对一
Many many() default @Many;一对多,多对多,many跟进里面和one一样
}
public @interface One {
String select() default "";
里面写的关联的那个表.类名称.方法名,相当于把两个方法给串联到一起了
FetchType fetchType() default FetchType.DEFAULT;
跟进
public enum FetchType {
LAZY,延时加载
EAGER,立即加载
DEFAULT;默认
private FetchType() {
}
}
}
016_mybatis注解开发使用二级缓存
- 先在SqlMapConfig.xml中开启二级缓存
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- 设置标签在接口上面
@CacheNamespace(blocking = true)