mybatis-plus、mybatis源码

    public static void main(String[] args) throws IOException {
        System.out.println("测试javaEE使用mybatis-plus");
        InputStream is = Resources.getResourceAsStream("conf/mybatis_conf.xml");
//        GenericTypeUtils.setGenericTypeResolver(null); // 3.5 javaEE 需要手动添加
//        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        SqlSessionFactory factory = new MybatisSqlSessionFactoryBuilder().build(is);
//        SqlSession session = factory.openSession();
//        UserMapper userMapper = session.getMapper(UserMapper.class);
//        System.out.println("--------session start---------");
//        System.out.println(userMapper.selectById(1));
//        System.out.println("--------session end---------");
//        SqlSession session2 = factory.openSession();
//        System.out.println("--------session2 start---------");
//        UserMapper userMapper1 = session2.getMapper(UserMapper.class);
//        System.out.println("--------session2 end---------");
//        User user1 = null;
//        System.out.println("--------session start---------");
//        System.out.println(user1 = userMapper1.selectById(1));
//        System.out.println("--------session end---------");
//
//        // 测试一级缓存
//        System.out.println("------------------------------");
//        user1.setEmail(System.currentTimeMillis() + "");
//        System.out.println("--------session2 start update---------");
//        userMapper1.updateById(user1);
//        session2.commit();
//        System.out.println("--------session2 end update---------");
//        System.out.println("--------session start---------");
//        System.out.println(userMapper.selectById(1)); // 会话1依然是老数据
//        System.out.println("--------session end---------");
//        System.out.println("--------session2 start---------");
//        System.out.println(userMapper1.selectById(1)); // 会话2为最新数据
//        System.out.println("--------session2 end---------");
//        // 测试一级缓存,是否有一个更新会导致 当前会话中的所有缓存给清空
//        System.out.println("测试一级缓存,是否有一个更新会导致 当前会话中的所有缓存给清空");
//        User user2 = new User();
//        user2.setEmail(System.currentTimeMillis() + "");
//        System.out.println("--------session start update---------");
//        userMapper.updateById(user2);
//        session.commit();
//        System.out.println("--------session end update---------");
//        System.out.println("--------session start---------");
//        System.out.println(userMapper.selectById(1)); // 会话1存在更新缓存,数据最新获取
//        System.out.println("--------session end---------");
//        // 二级缓存
        二级缓存测试(factory);
    }

    private static void 二级缓存测试(SqlSessionFactory factory) {
        System.out.println("mybatis 二级缓存测试");
        SqlSession session3 = factory.openSession();
        UserMapper mapper3 = session3.getMapper(UserMapper.class);
        // 同一个Mapper下的namespace update 会清空该namespace下的 CachingExecutor的tcm所有 缓存
        // 不同的namespace 不相互影响
//        User user9 = new User();
//        user9.setAge(100);
//        user9.setEmail("*****@163.com");
//        user9.setName("lilei");
//        System.out.println("--------session3 start insert---------");
//        mapper3.insert(user9);
//        session3.commit();
//        System.out.println("--------session3 end insert---------");
        System.out.println("--------session3 start---------");
        System.out.println(mapper3.getAllUsers());
        session3.commit(); // 当前session 二级缓存持久化
        System.out.println("--------session3 end---------");

        // 不同的session测试二级缓存
        SqlSession session4 = factory.openSession();
        UserMapper mapper4 = session4.getMapper(UserMapper.class);
        System.out.println("--------session4 start---------");
        System.out.println(mapper4.getAllUsers());
        System.out.println("--------session4 end---------");

        System.out.println("--------session3 start---------");
        mapper3 = session3.getMapper(UserMapper.class);
        System.out.println(mapper3.getAllUsers());
        System.out.println("--------session3 end---------");
    }

一、Mapper的初始化

jdk动态代理Mapper

二、mybatis数据库连接池

 ​​

三、mybatis缓存

一二级缓存key皆是CacheKey。

CacheExecutor为Executor的装饰器类,mybatis开启了二级换粗之后,即可有次装饰器。

 优先二级缓存(全局的,所有会话session共享的)

其次一级缓存(基于session会话的)

二级缓存调用堆栈

tcm.put只是压入TrasactionCache的entriesToAddCommit的Map。现在是session对话私有的,还未压入目标Cache。待后续session.commit或者close()

tcm->同步块Cache(线程安全)->日志统计Cache(总请求数、缓存命中率)->序列化Cache->策略Cache(LRU、FIFO、SOFT、WEAK)->目标Cache(map操作)

 当session.close()之后,或者session.commit之后二级缓存才会提交,写入Map。

否则同一个session下,二级缓存是不会命中的,只能走后续的一级缓存。

二级缓存全局共享是基于Configuration:

 基于Mapper的namespace + sql接口进行Map存储Mapstatement。

四、redis作为mybatis二级缓存介质

public class JedisPoolConf {
    public static JedisPool pool = null;

    public static JedisPool getPool() {
        if (pool == null) {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxIdle(10);
            config.setMaxTotal(100);
            config.setMaxWait(Duration.ofSeconds(30));
            pool = new JedisPool(config, "localhost", 6379, 30,"123456", 10);
        }
        return pool;
    }
}
public class RedisCache implements Cache {

    private JedisPool jedisPool = JedisPoolConf.getPool();

    private final String id;

    public RedisCache(String id) {
        this.id = id;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void putObject(Object key, Object value) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.hset(id.getBytes(), key.toString().getBytes(), serialize(value));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        } finally {
            jedis.close();
        }
    }

    @Override
    public Object getObject(Object key) {
        Jedis jedis = jedisPool.getResource();
        Object back = null;
        try {
            byte[] v = jedis.hget(id.getBytes(), key.toString().getBytes());
            if (v != null) {
                back = deserialize(v);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        } finally {
            jedis.close();
        }
        return back;
    }

    @Override
    public Object removeObject(Object key) {
        Jedis jedis = jedisPool.getResource();
        try {
            return jedis.hdel(id.getBytes(), key.toString().getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        } finally {
            jedis.close();
        }
        return 0;
    }

    @Override
    public void clear() {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(id.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        } finally {
            jedis.close();
        }
    }

    @Override
    public int getSize() {
        return 0;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return null;
    }

    private byte[] serialize(Object value) {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(bos)) {
            oos.writeObject(value);
            oos.flush();
            return bos.toByteArray();
        } catch (Exception e) {
            throw new CacheException("Error serializing object.  Cause: " + e, e);
        }
    }

    private Serializable deserialize(byte[] value) {
        SerialFilterChecker.check();
        Serializable result;
        try (ByteArrayInputStream bis = new ByteArrayInputStream(value);
             ObjectInputStream ois = new SerializedCache.CustomObjectInputStream(bis)) {
            result = (Serializable) ois.readObject();
        } catch (Exception e) {
            throw new CacheException("Error deserializing object.  Cause: " + e, e);
        }
        return result;
    }
}

调用堆栈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值