个人学习---SSM---Mybatis的缓存概念

Mybatis中的以及缓存和二级缓存

一级缓存:
    它指的是Mybatis中SqlSession对象的缓存
    当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供的一块区域中
    该区域的结构是一个Map。
    当我们再次查询同样的数据,mybatis会先去SqLSession中查询是否有,有的话直接拿来用
    当SqlSession对象消失时,mybatis的一级缓存也消失
二级缓存:
    它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存
    使用步骤:
    1.让mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
    2.让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
    3.让当前的操作支持二级缓存(在select标签中配置)

注意

一级缓存是把数据存到sqlsession对象中的map里,二级缓存是根据sqlsessionfactory先创建sqlsession对象,然后把缓存的中的数据填充到sqlsession中

二级缓存是以序列化形式存储的,如果domain对象不支持序列化就会包NotSerializableExecption

这里我们创建一个user实体类(set和get就不展示了)

public class User implements Serializable {

    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;
}

写上它的Dao接口

/*
    用户的持久层接口
*/
public interface IUserDao {
    /**
     * 查询所有用户,同时获取到用户下所有账户的信息
     * @return
     */
    List<User> findAll();

    //根据id查询用户信息
    User findById(Integer userid);

    //更新用户信息
    void updateUser(User user);
}

编写xml配置文件



<mapper namespace="com.itheima.dao.IUserDao">
    
    <cache/>

    
    <select id="findAll" resultType="com.itheima.domain.User">
        select u.*, a.id as aid, uid, money from user u left outer join account a on u.id = a.uid;
    select>

    
    <select id="findById" parameterType="int" resultType="com.itheima.domain.User" useCache="true">
        select * from user where id = #{uid} /*{}内为占位符,可随意写*/
    select>


    <update id="updateUser" parameterType="com.itheima.domain.User">
        update user set username = #{username},address = #{address} where id = #{id}
    update>
mapper>

编写测试类,测试一级缓存


        //6.释放资源
        sqlSession.close();
        in.close();
    }

    /**
     * 测试一级缓存
     */
    @Test
    public void testFirstLevelCache() {
        User user1 = userDao.findById(41);
        System.out.println(user1);

        sqlSession.close();
        // 再次获取SqlSession对象
        sqlSession = factory.openSession();
        userDao = sqlSession.getMapper(IUserDao.class);

        User user2 = userDao.findById(41);
        System.out.println(user2);
        System.out.println(user1 == user2); // false
    }

    /**
     * 测试缓存的同步
     */
    @Test
    public void testClearCache() {
        //1.根据id查询用户
        User user1 = userDao.findById(41);
        System.out.println(user1);

        //2.更新用户信息
        user1.setUsername("update user clear cache");
        user1.setAddress("北京市海淀区");
        userDao.updateUser(user1);

        //3.再次查询id为41的用户
        User user2 = userDao.findById(41);
        System.out.println(user2);
        System.out.println(user1 == user2);
    }

编写第二个测试类,测试二级缓存

public class SecondLevelCacheTest {

    private InputStream in;

    private SqlSessionFactory factory;

    @Before//用于在测试方法之前执行
    public void init() throws IOException {
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory对象
        factory = new SqlSessionFactoryBuilder().build(in);
    }

    @After//用于在测试方法之后执行
    public void destroy() throws IOException {
        in.close();
    }

    /**
     * 测试二级缓存
     */
    @Test
    public void testFirstLevelCache() {
        SqlSession sqlSession1 = factory.openSession();
        IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
        User user1 = dao1.findById(41);
        System.out.println(user1);
        sqlSession1.close(); //一级缓存消失

        SqlSession sqlSession2 = factory.openSession();
        IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
        User user2 = dao1.findById(41);
        System.out.println(user2);
        sqlSession2.close();

        System.out.println(user1 == user2); // false
    }

你可能感兴趣的:(Mybatis,mybatis)