Mybatis 事务管理和缓存机制

 

一级缓存--SqlSession级别

数据库表tb_user

User

package com.example.demo.domain;

public class User {
    private Integer id;
    private String name;
    private String sex;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
View Code

UserMapper

package com.example.demo.mapper;

import com.example.demo.domain.User;

import java.util.List;

public interface UserMapper {
    User selectUserById(Integer id);
    List<User> selectAllUser();
    void deleteUserById(Integer id);
}
View Code

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">

    <select id="selectUserById" parameterType="int" resultType="com.example.demo.domain.User">
        SELECT  *  FROM tb_user WHERE id=#{id}
    </select>
    <select id="selectAllUser" resultType="com.example.demo.domain.User">
        SELECT * FROM tb_user
    </select>
    <delete id="deleteUserById" parameterType="int">
        DELETE FROM tb_user WHERE id=#{id}
    </delete>
</mapper>
View Code

FKSqlSessionFactory

package com.example.demo.factory;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class FKSqlSessionFactory {
    private static SqlSessionFactory sqlSessionFactory=null;
    static {
        try {
            InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}
View Code

TestOneLevelCache

package com.example.demo.test;

import com.example.demo.domain.User;
import com.example.demo.factory.FKSqlSessionFactory;
import com.example.demo.mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;

public class TestOneLevelCache {
    public static void main(String[] args){
        TestOneLevelCache testOneLevelCache=new TestOneLevelCache();
        testOneLevelCache.testCache1();
    }
    public void testCache1(){
        SqlSession session= FKSqlSessionFactory.getSqlSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=mapper.selectUserById(1);
        System.out.println(user);
        User user1=mapper.selectUserById(1);
        System.out.println(user1);
        session.close();
    }
    public void testCache2() {
        SqlSession session = FKSqlSessionFactory.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selectUserById(1);
        System.out.println(user);
        mapper.deleteUserById(4);
        User user1=mapper.selectUserById(1);
        System.out.println(user1);
        session.close();
    }
}
View Code

运行testcache1

可以看到只查询了一次,返回的是同一个对象。

运行testcache2

 

 当SqlSession执行过DML操作(insert,update,delete)并提交到数据库后,Mybatis会清空一级缓存。

新加testCache3方法

public void testCache3(){
        SqlSession session = FKSqlSessionFactory.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selectUserById(1);
        System.out.println(user);
        session.close();
        session = FKSqlSessionFactory.getSqlSession();
        mapper = session.getMapper(UserMapper.class);
        user = mapper.selectUserById(1);
        System.out.println(user);
        session.close();
    }
View Code

运行

此时可以看到查询了两次。

二级缓存--mapper级别

 MyBatis默认开启一级缓存,开启二级缓存需要在settings中配置

<settings>
        <setting name="cacheEnabled" value="true"></setting>
    </settings>

在UserMapper.xml中添加配置

<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"></cache>

这里添加了一个LRU(最近最少使用策略)缓存,每隔60秒刷新,最大存储512个对象,且返回对象为只读。

TestTwoLevelCache

package com.example.demo.test;

import com.example.demo.domain.User;
import com.example.demo.factory.FKSqlSessionFactory;
import com.example.demo.mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;

public class TestTwoLevelCache {
    public static void main(String[] args){
        TestTwoLevelCache testTwoLevelCache=new TestTwoLevelCache();
//        testTwoLevelCache.testCache1();
        testTwoLevelCache.testCache2();
    }
    public void testCache1(){
        SqlSession session = FKSqlSessionFactory.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selectUserById(1);
        System.out.println(user);
        mapper.deleteUserById(4);
        User user1=mapper.selectUserById(1);
        System.out.println(user1);
        session.close();
    }
    public void testCache2(){
        SqlSession session = FKSqlSessionFactory.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selectUserById(1);
        System.out.println(user);
        session.close();
        session = FKSqlSessionFactory.getSqlSession();
        mapper = session.getMapper(UserMapper.class);
        user = mapper.selectUserById(1);
        System.out.println(user);
        session.close();
    }
}
View Code

运行testCache2()

可以看到命中缓存了。

 

posted @ 2017-12-17 17:20  uptothesky  阅读(770)  评论(0编辑  收藏  举报