今日目标
1. 延迟加载
2. 一级缓存和二级缓存
3. 注解开发 [重点!!]
作业
1.完成延迟加载案例
2.使用注解完成一对一和多对多的开发。
延迟加载
1.1.注意:
在配置文件中,packge如果写了,那么main中的文件和resource中的文件名称必须一致,一一对应。
1.2.Mybatis的延迟加载:
* 在实际开发中,在查询账户时,账户的所属用户信息应该是随着账户时一起查询出来。[立即加载]
* 查询用户时,账户的信息是随着用户的需要才加载出来。 [延迟加载/按需加载/懒加载]
1.3.概念:
1.延迟加载:在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
2.立即加载:不管用不用,只要一调用方法,马上发起查询。
1.4 时机:
1.在对应的四种表关系中:一对多,多对一,一对一,多对多
* 一对多,多对多,通常情况下是延迟加载。
* 多对一,一对一,通常情况下是立即加载。
1.5:好处与坏处
* 好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
* 坏处:因为只有当需要需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以造成用户等待时间变长,造成用户体验下降。
1.6: 配置步骤:
1. 创建Maven工程
2. 导入项目:接口,实体类,核心配置文件,配置文件,测试类;
3. 在SqlMapConfig.xml文件中,在configuration的settings标签中:
* <settings>
* <setting name="lazyLoadingEnabled" value="true"></setting>e1q3
* <setting name="aggressiveLazyLoading" value="falese"></setting> //aggressiveLazyLoading 属性在mybaits3.4.1以上是默认关闭的即可以不写。
* </settings>
4.在映射配置文件中进行配置:
<connection property="accounts" ofType="account" column="uid" select="com.itheima.dao."
5.详细步骤参见文档
缓存[cache]
1.缓存的概念:
* 什么是缓存? ->存在于内存中的临时数据。
* 为什么使用缓存? ->减少和数据库的交互次数,提高执行效率。
* 什么样的数据能使用缓存,什么样的数据不能使用?
1. 适用于缓存: 经常查询并且不经常改变的并且数据的正确与否对最终结果影响不大的。
2. 不适用于缓存:
* 经常改变的数据
* 数据的正确与否对最终结果影响很大的。
* 例如:商品的库存,银行的汇率,股市的牌价。
2.mybatis中的一级缓存和二级缓存 [sqlSession缓存是重点]
1. 一级缓存:它指的是mybatis中SqlSession对象的缓存
* 当我们执行查询结果之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。该区域的结果是一个Map。当我们再次查询同样的数据,mybatis会先去sqlSession中查询是否有,有的话直接拿出来使用。
* 当SqlSession关闭的时候,缓存也会跟着一起清除。
2. 二级缓存:它指的是Mybatis中SqlsessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
3.关闭缓存的方法:
* sqlSession.clearCache(); //清除缓存不关闭sqlsession
* sqlSession.close(); //清除缓存并关闭sqlSession
* 当我们执行增删改的操作时,会进行缓存的更新 //清除缓存不关闭sqlSession
4.一级缓存的问题:
* 其实就是sqlsession帮我们做了一级缓存:第一次查询到的数据封装到了缓存中,以便于下次查询使用。
5.二级缓存的问题:
1. 问题1:如果sqlSession(一级缓存)清空了,那么二级缓存还在吗? * 答: 在。
2. 问题2:一级缓存放在哪里?
* 答:一级缓存存放的是内存,所以地址值一样。
3. 问题3:二级缓存存放在哪儿?
* 二级缓存存的是数据,并且序列化到了本地硬盘。
4. 问题4:为什么二级缓存取出来的对象不是同一个?
* 答:使用反序列化为对象的时候,地址值不一样。
5. 问题5:搭建多个服务器,做集群,问:mybatis的二级缓存能在集群中实现吗?
* 答:不适用mybatis二级缓存,那么使用自己继承二级缓存:
* redis , memcached,encache
6.二级缓存的使用步骤:
* 核心:
* <settings>
*
* 映射:
1. 在mapper标签下第一行<cache/>
2. <select>标签内添加属性:
* 注意:二级缓存中,存放的内容是数据,而不是对象。
Mybatis的注解开发
1. 环境搭建
1. 创建Maven工程 [骨架空,com.itheima,day01_zhujie]
2. 导入坐标 [mybatis,mysql,log4j,junit]
3. 准备实体类 [java.com.itheima.User] ->实现序列化接口,添加内容
4. 准备接口 [java.com.itheima.IUserDao] ->添加方法
5. 配置环境:
1. 创建SqlMapperConfig
2. 配置外部配置文件
3. 映射配置文件
4. 注意: [可引入驱动文件,可配置别名,可导包路径]
6. 接口操作:方法上@Select("sekect * from user")注解
7. 测试类操作:
1. Test.com.itheima.test
2. 获取字节输入流,创建构建者
3. 构建者创建工厂
4. 工厂创建sqlSession对象
5. sqlSession调用getMapper方法
2. 单表CRUD
1.
3. 多表查询
4. 注意:采用注解开发的时候,在同一个dao下不能有xml文件,就是说要么用注解要么就都用配置文件开发。
1. 同一个文件不能同时使用注解和配置文件开发。
2. 如果是不同的接口文件,可以使用不同的方法,但工作中不建议这样使用。
3. 在注解开发中,如何在插入新的用户后获取用户的自增长ID:
* 在查询注解下添加新的注解Options
* 举例:@Options(useGeneratedKeys=true,keyColumn="id",keyProperty="id")
* useGenerateKey:是否要使用自增长ID,如果为true,则需要使用。
4. 关于别名问题:
1. 方法一:
* 举例:@Resoults( id ="userMap" value={
* @Result(id=true,colum="id",property="userId"),
* @Result(id=true,colum="username",property="userName"),
* @Result(id=true,colum="address",property="userAddress"),
* @Result(id=true,colum="sex",property="userSex"),
* @Result(id=true,colum="birthday",property="userBirthday"),
* })
* 如果数据库数据和实体类属性类型不一致,可以采用起别名的方式解决。
2. 方法二:ResultMap [在标签和注解两种方法都能使用]
* @ResultMap("userMap")
* //@Resoults( id ="userMap" value={ 通过前面方法一已经声明了关系,后面就可以使用此注解进行调用。
5.使用注解执行动态SQL?
1.在映射card_one属性时用association标签, 映射card_many时用collection标签.
所以association是用于一对一和多对一,而collection是用于一对多的关系