1.mybatis中的延时加载

问题:在一对多中,当我们有一个用户,它有100个账户。
  在查询用户的时候,要不要把关联的账户查出来?
  在查询账户的时候,要不要把关联的用户查出来?

  在查询用户时,用户下的账户信息应该是,什么时候使用,什么时候查询的。
  在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。

什么是延迟加载
  在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
什么是立即加载
  不管用不用,只要一调用方法,马上发起查询。

总结:在对应的四种表关系中:一对多,多对一,一对一,多对多

  一对多,多对多:通常情况下我们都是采用延迟加载。
  多对一,一对一:通常情况下我们都是采用立即加载。

2.实现需求

需求:
  查询账户(Account)信息并且关联查询用户(User)信息。如果先查询账户(Account)信息即可满足要求,当我们需要查询用户(User)信息时再查询用户(User)信息。把对用户(User)信息的按需去查询就是延迟加载。
  mybatis第三天实现多表操作时,我们使用了resultMap来实现一对一,一对多,多对多关系的操作。主要是通过 association、collection 实现一对一及一对多映射。association、collection 具备延迟加载功能。

3.使用assocation实现延迟加载

3.1账户的持久层DAO接口

  1. package com.itheima.dao;
  2.  
  3. import com.itheima.domain.Account;
  4.  
  5. import java.util.List;
  6.  
  7. public interface IAccountDao {
  8. List<Account> findAll();
  9. }

3.2账户的持久层映射文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.itheima.dao.IAccountDao">
  6.  
  7. <!-- 定义封装account和user的resultMap -->
  8. <resultMap id="accountUserMap" type="account">
  9. <id property="id" column="id"></id>
  10. <result property="uid" column="uid"></result>
  11. <result property="money" column="money"></result>
  12. <!-- 一对一的关系映射:配置封装user的内容
  13. select属性指定的内容:查询用户的唯一标识:
  14. column属性指定的内容:用户根据id查询时,所需要的参数的值
  15. -->
  16. <association property="user" column="uid" javaType="user"
  17. select="com.itheima.dao.IUserDao.findById"></association>
  18. </resultMap>
  19.  
  20. <!-- 查询所有 -->
  21. <select id="findAll" resultMap="accountUserMap">
  22. select * from account;
  23. </select>
  24.  
  25. <!-- 根据用户id查询账户列表 -->
  26. <select id="findAccountByUid" resultType="account">
  27. select * from account where uid = #{uid}
  28. </select>
  29.  
  30. </mapper>

select : 填写我们要调用的 select 映射的 id
column : 填写我们要传递给 select 映射的参数

3.3用户的持久层接口和映射文件

  1. package com.itheima.dao;
  2.  
  3. import com.itheima.domain.User;
  4.  
  5. import java.util.List;
  6.  
  7. /**
  8. * @author 黑马程序员
  9. * @Company http://www.ithiema.com
  10. *
  11. * 用户的持久层接口
  12. */
  13. public interface IUserDao {
  14.  
  15. /**
  16. * 查询所有用户,同时获取到用户下所有账户的信息
  17. * @return
  18. */
  19. List<User> findAll();
  20.  
  21. /**
  22. * 根据id查询用户信息
  23. * @param userId
  24. * @return
  25. */
  26. User findById(Integer userId);
  27. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.itheima.dao.IUserDao">
  6.  
  7. <!-- 定义User的resultMap-->
  8. <resultMap id="userAccountMap" type="user">
  9. <id property="id" column="id"></id>
  10. <result property="username" column="username"></result>
  11. <result property="address" column="address"></result>
  12. <result property="sex" column="sex"></result>
  13. <result property="birthday" column="birthday"></result>
  14. <!-- 配置user对象中accounts集合的映射 -->
  15. <collection property="accounts" ofType="account">
  16. <id column="aid" property="id"></id>
  17. <result column="uid" property="uid"></result>
  18. <result column="money" property="money"></result>
  19. </collection>
  20. </resultMap>
  21.  
  22. <!-- 查询所有 -->
  23. <select id="findAll" resultMap="userAccountMap">
  24. select * from user u left outer join account a on u.id = a.uid
  25. </select>
  26.  
  27. <!-- 根据id查询用户 -->
  28. <select id="findById" parameterType="INT" resultType="user">
  29. select * from user where id = #{uid}
  30. </select>
  31.  
  32. </mapper>

3.4开启 Mybatis的延迟加载策略

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 配置properties-->
  7. <properties resource="jdbcConfig.properties"></properties>
  8.  
  9. <!--&lt;!&ndash;配置参数&ndash;&gt;-->
  10. <settings>
  11. <!--开启Mybatis支持延迟加载-->
  12. <setting name="lazyLoadingEnabled" value="true"/>
  13. <setting name="aggressiveLazyLoading" value="false"></setting>
  14. </settings>
  15.  
  16. <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
  17. <typeAliases>
  18. <package name="com.itheima.domain"></package>
  19. </typeAliases>
  20.  
  21. <!--配置环境-->
  22. <environments default="mysql">
  23. <!-- 配置mysql的环境-->
  24. <environment id="mysql">
  25. <!-- 配置事务 -->
  26. <transactionManager type="JDBC"></transactionManager>
  27.  
  28. <!--配置连接池-->
  29. <dataSource type="POOLED">
  30. <property name="driver" value="${jdbc.driver}"></property>
  31. <property name="url" value="${jdbc.url}"></property>
  32. <property name="username" value="${jdbc.username}"></property>
  33. <property name="password" value="${jdbc.password}"></property>
  34. </dataSource>
  35. </environment>
  36. </environments>
  37. <!-- 配置映射文件的位置 -->
  38. <mappers>
  39. <package name="com.itheima.dao"></package>
  40. </mappers>
  41. </configuration>

3.5编写测试只查账户信息不查用户信息

  1. package com.itheima.test;
  2.  
  3. import com.itheima.dao.IAccountDao;
  4. import com.itheima.domain.Account;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12.  
  13. import java.io.InputStream;
  14. import java.util.List;
  15.  
  16. public class AccountTest {
  17.  
  18. private InputStream in;
  19. private SqlSession sqlSession;
  20. private IAccountDao accountDao;
  21.  
  22. @Before//用于在测试方法执行之前执行
  23. public void init()throws Exception{
  24. //1.读取配置文件,生成字节输入流
  25. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  26. //2.获取SqlSessionFactory
  27. SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
  28. //3.获取SqlSession对象
  29. sqlSession = factory.openSession(true);
  30. //4.获取dao的代理对象
  31. accountDao = sqlSession.getMapper(IAccountDao.class);
  32. }
  33.  
  34. @After//用于在测试方法执行之后执行
  35. public void destroy()throws Exception{
  36. //提交事务
  37. // sqlSession.commit();
  38. //6.释放资源
  39. sqlSession.close();
  40. in.close();
  41. }
  42.  
  43. /**
  44. * 测试查询所有
  45. */
  46. @Test
  47. public void testFindAll(){
  48. List<Account> accounts = accountDao.findAll();
  49. }
  50. }

如果不配置这个

  1. <settings>
  2. <!--开启Mybatis支持延迟加载-->
  3. <setting name="lazyLoadingEnabled" value="true"/>
  4. <setting name="aggressiveLazyLoading" value="false"></setting>
  5. </settings>

4.Mybaits中缓存的概念

什么是缓存
  存在于内存中的临时数据。
为什么使用缓存
  减少和数据库的交互次数,提高执行效率。
什么样的数据能使用缓存,什么样的数据不能使用
  适用于缓存:
    经常查询并且不经常改变的。
    数据的正确与否对最终结果影响不大的。
  不适用于缓存:
    经常改变的数据
    数据的正确与否对最终结果影响很大的。
    例如:商品的库存,银行的汇率,股市的牌价。

Mybatis中的一级缓存和二级缓存

一级缓存:
  它指的是Mybatis中SqlSession对象的缓存。
  当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。 该区域的结构是一个Map。
  当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。
  当SqlSession对象消失时,mybatis的一级缓存也就消失了。

二级缓存:
  它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
  二级缓存的使用步骤:
    第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
    第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
    第三步:让当前的操作支持二级缓存(在select标签中配置)

4.1证明一级缓存的存在

一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。

4.2user实体类

  1. package com.itheima.domain;
  2.  
  3. import java.io.Serializable;
  4. import java.util.Date;
  5. import java.util.List;
  6.  
  7. public class User implements Serializable {
  8.  
  9. private Integer id;
  10. private String username;
  11. private String address;
  12. private String sex;
  13. private Date birthday;
  14.  
  15. public Integer getId() {
  16. return id;
  17. }
  18.  
  19. public void setId(Integer id) {
  20. this.id = id;
  21. }
  22.  
  23. public String getUsername() {
  24. return username;
  25. }
  26.  
  27. public void setUsername(String username) {
  28. this.username = username;
  29. }
  30.  
  31. public String getAddress() {
  32. return address;
  33. }
  34.  
  35. public void setAddress(String address) {
  36. this.address = address;
  37. }
  38.  
  39. public String getSex() {
  40. return sex;
  41. }
  42.  
  43. public void setSex(String sex) {
  44. this.sex = sex;
  45. }
  46.  
  47. public Date getBirthday() {
  48. return birthday;
  49. }
  50.  
  51. public void setBirthday(Date birthday) {
  52. this.birthday = birthday;
  53. }
  54.  
  55. // @Override
  56. // public String toString() {
  57. // return "User{" +
  58. // "id=" + id +
  59. // ", username='" + username + '\'' +
  60. // ", address='" + address + '\'' +
  61. // ", sex='" + sex + '\'' +
  62. // ", birthday=" + birthday +
  63. // '}';
  64. // }
  65. }

4.3编写用户持久层Dao接口

  1. package com.itheima.dao;
  2.  
  3. import com.itheima.domain.User;
  4.  
  5. import java.util.List;
  6.  
  7. public interface IUserDao {
  8.  
  9. /**
  10. * 查询所有用户,同时获取到用户下所有账户的信息
  11. * @return
  12. */
  13. List<User> findAll();
  14.  
  15. /**
  16. * 根据id查询用户信息
  17. * @param userId
  18. * @return
  19. */
  20. User findById(Integer userId);
  21. }

4.4编写用户持久层映射文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.itheima.dao.IUserDao">
  6.  
  7. <!-- 查询所有 -->
  8. <select id="findAll" resultType="user">
  9. select * from user
  10. </select>
  11.  
  12. <!-- 根据id查询用户 -->
  13. <select id="findById" parameterType="INT" resultType="user">
  14. select * from user where id = #{uid}
  15. </select>
  16.  
  17. </mapper>

4.5测试方法

  1. package com.itheima.test;
  2.  
  3. import com.itheima.dao.IUserDao;
  4. import com.itheima.domain.User;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12.  
  13. import java.io.InputStream;
  14. import java.util.List;
  15.  
  16. /**
  17. * @author 黑马程序员
  18. * @Company http://www.ithiema.com
  19. */
  20. public class UserTest {
  21.  
  22. private InputStream in;
  23. private SqlSession sqlSession;
  24. private IUserDao userDao;
  25. private SqlSessionFactory factory;
  26.  
  27. @Before//用于在测试方法执行之前执行
  28. public void init() throws Exception {
  29. //1.读取配置文件,生成字节输入流
  30. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  31. //2.获取SqlSessionFactory
  32. factory = new SqlSessionFactoryBuilder().build(in);
  33. //3.获取SqlSession对象
  34. sqlSession = factory.openSession(true);
  35. //4.获取dao的代理对象
  36. userDao = sqlSession.getMapper(IUserDao.class);
  37. }
  38.  
  39. @After//用于在测试方法执行之后执行
  40. public void destroy() throws Exception {
  41. //提交事务
  42. // sqlSession.commit();
  43. //6.释放资源
  44. sqlSession.close();
  45. in.close();
  46. }
  47.  
  48. /**
  49. * 测试一级缓存
  50. */
  51. @Test
  52. public void testFirstLevelCache() {
  53. User user1 = userDao.findById(41);
  54. System.out.println(user1);
  55. sqlSession.close();
  56. sqlSession = factory.openSession();
  57. userDao = sqlSession.getMapper(IUserDao.class);
  58. User user2 = userDao.findById(41);
  59. System.out.println(user2);
  60.  
  61. System.out.println(user1 == user2);
  62.  
  63. }
  64.  
  65. }

如果关闭了sqlSession,可以看出不是同一个对象,并且可以看到数据库查询了两次。如果不关闭sqlSession会怎么样呢?

  1. package com.itheima.test;
  2.  
  3. import com.itheima.dao.IUserDao;
  4. import com.itheima.domain.User;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12.  
  13. import java.io.InputStream;
  14. import java.util.List;
  15.  
  16. /**
  17. * @author 黑马程序员
  18. * @Company http://www.ithiema.com
  19. */
  20. public class UserTest {
  21.  
  22. private InputStream in;
  23. private SqlSession sqlSession;
  24. private IUserDao userDao;
  25. private SqlSessionFactory factory;
  26.  
  27. @Before//用于在测试方法执行之前执行
  28. public void init() throws Exception {
  29. //1.读取配置文件,生成字节输入流
  30. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  31. //2.获取SqlSessionFactory
  32. factory = new SqlSessionFactoryBuilder().build(in);
  33. //3.获取SqlSession对象
  34. sqlSession = factory.openSession(true);
  35. //4.获取dao的代理对象
  36. userDao = sqlSession.getMapper(IUserDao.class);
  37. }
  38.  
  39. @After//用于在测试方法执行之后执行
  40. public void destroy() throws Exception {
  41. //提交事务
  42. // sqlSession.commit();
  43. //6.释放资源
  44. sqlSession.close();
  45. in.close();
  46. }
  47.  
  48. /**
  49. * 测试一级缓存
  50. */
  51. @Test
  52. public void testFirstLevelCache() {
  53. User user1 = userDao.findById(41);
  54. System.out.println(user1);
  55. // sqlSession.close();
  56. // sqlSession = factory.openSession();
  57. // userDao = sqlSession.getMapper(IUserDao.class);
  58. User user2 = userDao.findById(41);
  59. System.out.println(user2);
  60.  
  61. System.out.println(user1 == user2);
  62.  
  63. }
  64.  
  65. }

如果不关闭sqlSession,对象时同一个,说明应用了缓存中的对象,并且数据库只被查询了一次。

  1. package com.itheima.test;
  2.  
  3. import com.itheima.dao.IUserDao;
  4. import com.itheima.domain.User;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12.  
  13. import java.io.InputStream;
  14. import java.util.List;
  15.  
  16. /**
  17. * @author 黑马程序员
  18. * @Company http://www.ithiema.com
  19. */
  20. public class UserTest {
  21.  
  22. private InputStream in;
  23. private SqlSession sqlSession;
  24. private IUserDao userDao;
  25. private SqlSessionFactory factory;
  26.  
  27. @Before//用于在测试方法执行之前执行
  28. public void init() throws Exception {
  29. //1.读取配置文件,生成字节输入流
  30. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  31. //2.获取SqlSessionFactory
  32. factory = new SqlSessionFactoryBuilder().build(in);
  33. //3.获取SqlSession对象
  34. sqlSession = factory.openSession(true);
  35. //4.获取dao的代理对象
  36. userDao = sqlSession.getMapper(IUserDao.class);
  37. }
  38.  
  39. @After//用于在测试方法执行之后执行
  40. public void destroy() throws Exception {
  41. //提交事务
  42. // sqlSession.commit();
  43. //6.释放资源
  44. sqlSession.close();
  45. in.close();
  46. }
  47.  
  48. /**
  49. * 测试一级缓存
  50. */
  51. @Test
  52. public void testFirstLevelCache() {
  53. User user1 = userDao.findById(41);
  54. System.out.println(user1);
  55. sqlSession.clearCache();//此方法也可以清空缓存
  56. User user2 = userDao.findById(41);
  57. System.out.println(user2);
  58.  
  59. System.out.println(user1 == user2);
  60.  
  61. }
  62.  
  63. }

4.6 一级缓存的分析

一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

4.7测试一级缓存的清空

  1. package com.itheima.dao;
  2.  
  3. import com.itheima.domain.User;
  4.  
  5. import java.util.List;
  6.  
  7. public interface IUserDao {
  8.  
  9. /**
  10. * 查询所有用户,同时获取到用户下所有账户的信息
  11. * @return
  12. */
  13. List<User> findAll();
  14.  
  15. /**
  16. * 根据id查询用户信息
  17. * @param userId
  18. * @return
  19. */
  20. User findById(Integer userId);
  21.  
  22. /**
  23. * 更新用户信息
  24. * @param user
  25. */
  26. void updateUser(User user);
  27. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.itheima.dao.IUserDao">
  6.  
  7. <!-- 查询所有 -->
  8. <select id="findAll" resultType="user">
  9. select * from user
  10. </select>
  11.  
  12. <!-- 根据id查询用户 -->
  13. <select id="findById" parameterType="INT" resultType="user">
  14. select * from user where id = #{uid}
  15. </select>
  16.  
  17. <!-- 更新用户信息-->
  18. <update id="updateUser" parameterType="user">
  19. update user set username=#{username},address=#{address} where id=#{id}
  20. </update>
  21.  
  22. </mapper>
  1. package com.itheima.test;
  2.  
  3. import com.itheima.dao.IUserDao;
  4. import com.itheima.domain.User;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12.  
  13. import java.io.InputStream;
  14. import java.util.List;
  15.  
  16. /**
  17. * @author 黑马程序员
  18. * @Company http://www.ithiema.com
  19. */
  20. public class UserTest {
  21.  
  22. private InputStream in;
  23. private SqlSession sqlSession;
  24. private IUserDao userDao;
  25. private SqlSessionFactory factory;
  26.  
  27. @Before//用于在测试方法执行之前执行
  28. public void init() throws Exception {
  29. //1.读取配置文件,生成字节输入流
  30. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  31. //2.获取SqlSessionFactory
  32. factory = new SqlSessionFactoryBuilder().build(in);
  33. //3.获取SqlSession对象
  34. sqlSession = factory.openSession(true);
  35. //4.获取dao的代理对象
  36. userDao = sqlSession.getMapper(IUserDao.class);
  37. }
  38.  
  39. @After//用于在测试方法执行之后执行
  40. public void destroy() throws Exception {
  41. //提交事务
  42. // sqlSession.commit();
  43. //6.释放资源
  44. sqlSession.close();
  45. in.close();
  46. }
  47.  
  48. /**
  49. * 测试一级缓存
  50. */
  51. @Test
  52. public void testFirstLevelCache() {
  53. User user1 = userDao.findById(41);
  54. System.out.println(user1);
  55. sqlSession.clearCache();//此方法也可以清空缓存
  56. User user2 = userDao.findById(41);
  57. System.out.println(user2);
  58.  
  59. System.out.println(user1 == user2);
  60. }
  61. /**
  62. * 测试一级缓存
  63. */
  64. @Test
  65. public void testClearCache() {
  66. //1.根据id查询用户
  67. User user1 = userDao.findById(41);
  68. System.out.println(user1);
  69. //2.更新用户信息
  70. user1.setUsername("update user clear cache");
  71. user1.setAddress("beijing");
  72. userDao.updateUser(user1);
  73. //3.再次查询id为41的用户
  74. User user2 = userDao.findById(41);
  75. System.out.println(user2);
  76.  
  77. System.out.println(user1 == user2);
  78. }
  79. }

4.8二级缓存

二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

4.9开启二级缓存

第一步:在 SqlMapConfig.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 配置properties-->
  7. <properties resource="jdbcConfig.properties"></properties>
  8.  
  9. <settings>
  10. <setting name="cacheEnabled" value="true"/>
  11. </settings>
  12.  
  13. <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
  14. <typeAliases>
  15. <package name="com.itheima.domain"></package>
  16. </typeAliases>
  17.  
  18. <!--配置环境-->
  19. <environments default="mysql">
  20. <!-- 配置mysql的环境-->
  21. <environment id="mysql">
  22. <!-- 配置事务 -->
  23. <transactionManager type="JDBC"></transactionManager>
  24.  
  25. <!--配置连接池-->
  26. <dataSource type="POOLED">
  27. <property name="driver" value="${jdbc.driver}"></property>
  28. <property name="url" value="${jdbc.url}"></property>
  29. <property name="username" value="${jdbc.username}"></property>
  30. <property name="password" value="${jdbc.password}"></property>
  31. </dataSource>
  32. </environment>
  33. </environments>
  34. <!-- 配置映射文件的位置 -->
  35. <mappers>
  36. <package name="com.itheima.dao"></package>
  37. </mappers>
  38. </configuration>

第二步:配置相关的Mapper映射文

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.itheima.dao.IUserDao">
  6.  
  7. <!--开启user支持二级缓存-->
  8. <cache/>
  9.  
  10. <!-- 查询所有 -->
  11. <select id="findAll" resultType="user">
  12. select * from user
  13. </select>
  14.  
  15. <!-- 根据id查询用户 -->
  16. <select id="findById" parameterType="INT" resultType="user" useCache="true">
  17. select * from user where id = #{uid}
  18. </select>
  19.  
  20. <!-- 更新用户信息-->
  21. <update id="updateUser" parameterType="user">
  22. update user set username=#{username},address=#{address} where id=#{id}
  23. </update>
  24.  
  25. </mapper>

4.10测试

  1. package com.itheima.test;
  2.  
  3. import com.itheima.dao.IUserDao;
  4. import com.itheima.domain.User;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12.  
  13. import java.io.InputStream;
  14.  
  15. /**
  16. * @author 黑马程序员
  17. * @Company http://www.ithiema.com
  18. */
  19. public class SecondLevelCacheTest {
  20.  
  21. private InputStream in;
  22. private SqlSessionFactory factory;
  23.  
  24. @Before//用于在测试方法执行之前执行
  25. public void init() throws Exception {
  26. //1.读取配置文件,生成字节输入流
  27. in = Resources.getResourceAsStream("SqlMapConfig.xml");
  28. //2.获取SqlSessionFactory
  29. factory = new SqlSessionFactoryBuilder().build(in);
  30.  
  31. }
  32.  
  33. @After//用于在测试方法执行之后执行
  34. public void destroy() throws Exception {
  35. in.close();
  36. }
  37.  
  38. /**
  39. * 测试一级缓存
  40. */
  41. @Test
  42. public void testFirstLevelCache() {
  43. SqlSession sqlSession1 = factory.openSession(true);
  44. IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
  45. User user1 = dao1.findById(41);
  46. System.out.println(user1);
  47. sqlSession1.close();
  48.  
  49. SqlSession sqlSession2 = factory.openSession(true);
  50. IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
  51. User user2 = dao2.findById(41);
  52. System.out.println(user2);
  53. sqlSession2.close();
  54. System.out.println(user1 == user2);
  55. }
  56. }

因为两个对象的内存地址不一样,而数据库查询方法只调用了一次,所以可以看出二级缓存存入的不是对象二是数据,所以共享的是数据。

22_6mybatis中的缓存的更多相关文章

  1. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  2. 清除oracle中的缓存(具体细节未知, 慎用)

    oracle中的缓存主要是指SGA中的:1.share pool2.database buffer cache清空命令如下:首先要登录到sqlplus命令下,输入如下命令即可:SQL> alte ...

  3. AngularJS中的缓存

    欢迎大家指导与讨论 : ) 缓存篇 一个缓存就是一个组件,它可以透明地储存数据,以便以后可以更快地服务于请求.多次重复地获取资源可能会导致数据重复,消耗时间.因此缓存适用于变化性不大的一些数据,缓存能 ...

  4. 如何在 apache 中设置缓存有效时间

    今天学习了下如何在 apache 中设置缓存时间,记之以备忘. 在 http 报文头中,与缓存时间有关的两个字段是 Expires 以及 Cache-Control 中的 max-age,Expire ...

  5. 谈谈MVC项目中的缓存功能设计的相关问题

    本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据 ...

  6. iOS中dyld缓存的实现原理是怎样的?

    在iOS开发中,为了提升系统的安全性,很多系统库文件都被打包到一个缓存的文件当中即dyld缓存,那大家对dyld缓存了解多少呢?今天小编将和大家分享的就是一位iOS大神对dyld缓存的使用分析,一起来 ...

  7. angular中$cacheFactory缓存的使用

    最近在学习使用angular,慢慢从jquery ui转型到用ng开发,发现了很多不同点,继续学习吧: 首先创建一个服务,以便在项目中的controller中引用,服务有几种存在形式,factory( ...

  8. 如何在 Linux 中清除缓存(Cache)

              如何在 Linux 中清除缓存(Cache)            方法一: http://mp.weixin.qq.com/s?__biz=MjM5ODAzODgyMQ==&am ...

  9. 菜鸟-手把手教你把Acegi应用到实际项目中(7)-缓存用户信息

    首先讲讲EhCache.在默认情况下,即在用户未提供自身配置文件ehcache.xml或ehcache-failsafe.xml时,EhCache会依据其自身Jar存档包含的ehcache-fails ...

随机推荐

  1. linux常用命令---------------find

    1.find 基本模式 find path -option [ -print ] [ -exec -ok command ] {} \; 2.常用的参数 -name name, -iname name ...

  2. Hibernate使用中防止SQL注入的几种方案

    Hibernate使用中防止SQL注入的几种方案 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数 ...

  3. element-ui--按需引入

    参考链接:https://www.cnblogs.com/qiezuimh/p/10103522.html

  4. 【Python】【基础知识】【内置函数】【print的使用方法】

    原英文帮助文档: print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) Print objects to the text ...

  5. 【LOJ】#3090. 「BJOI2019」勘破神机

    LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...

  6. localStorage 杂记

    localStorage html5标准 Web 存储现在的主流浏览器,包括IE 8+.Chrome 4+.Firefox 3.5+.Opera 10.5+.Safari 4+.iPhone 2+.A ...

  7. Python编程之注释

    一.注释 当你把变量理解透了,你就已经进入了编程的世界.随着学习的深入,用不了多久,你就可以写复杂的上千甚至上万行的代码啦,有些代码你花了很久写出来,过了些天再回去看,发现竟然看不懂了,这太正常了. ...

  8. OpenCV-图像处理

    直方图比较方法-概述 对输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间 然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度进 而比较图像本身的相似程度.Opencv提供的比 ...

  9. ale.js 对比其他框架

    欢迎!我们相信你来这里的目的就是为了解 Ale 与其他大型框架的区别,这也正是我们想要在此回答的. 客观来说,作为 Ale 的核心开发者,我们肯定会更偏爱 Ale,认为对于某些问题来讲用 Ale 解决 ...

  10. Vasya and Magic Matrix CodeForces - 1042E (概率dp)

    大意:给定n*m矩阵, 初始位置(r,c), 每一步随机移动到权值小于当前点的位置, 得分为移动距离的平方, 求得分期望. 直接暴力dp的话复杂度是O(n^4), 把距离平方拆开化简一下, 可以O(n ...