• 配置Mybatis二级缓存为Redis来实现内容缓存


    为了使用缓存功能,要大量修改Service实现类,增加处理缓存的业务逻辑。有没有一个更好的办法实现呢,不用每次都修改Service具体实现类?

    答案是有,我们分析一下我们的架构体系,我们除了可以在Service层做处理意外,也可以考虑在DAO层做处理,但是DAO层我们只是定义了相关接口,具体的数据增删改查都是动态代理在Mybatis层实现的,我们有没有一个办法能在Mybatis层来处理一下实现缓存功能?

    答案是有办法,还记得在第四阶段我们学习Mybatis的时候涉及到一个缓存的概念,当时和大家讲过一级缓存和二级缓存

    Mybatis二级缓存原理

    Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存。

    在同一个namespace下的mapper文件中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;第二次直接从缓存中取。当执行SQL时两次查询中间发生了增删改操作,则二级缓存清空。

     

    二级缓存是mapper级别的。Mybatis默认是没有开启二级缓存。

     

    第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。

    第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果。

    如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存。

     

    代码实例:

     1.导包

    2.Mybtais_con.xml

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE configuration

            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

            "http://mybatis.org/dtd/mybatis-3-config.dtd">

    <configuration>

        <!--开启二级缓存-->

        <settings>

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

        </settings>

        <environments default="development">

            <environment id="development">

                <transactionManager type="JDBC"/>

                <dataSource type="POOLED">

                    <property name="driver" value="com.mysql.jdbc.Driver"/>

                    <property name="url" value="jdbc:mysql://localhost:3306/test"/>

                    <property name="username" value="root"/>

                    <property name="password" value="123456"/>

                </dataSource>

            </environment>

        </environments>

        <mappers>

            <mapper resource="UserMapper.xml"/>

        </mappers>

    </configuration>

    3.mapper文件

    <?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.ujiuye.mapper.UserDao">

        <!--eviction="LRU"  redis的内存管理策略-->

        <cache eviction="LRU" type="com.ujiuye.util.RedisCache"/>

     

        <select id="getAll" resultType="com.ujiuye.bean.UserInfo" useCache="true">

            select *from userinfo

        </select>

     

        <update id="update"  parameterType="com.ujiuye.bean.UserInfo">

            update  userinfo set username=#{username},password=#{password} where uid=#{uid}

        </update>

     

        <delete id="del">

            delete  from userinfo where uid=#{0}

        </delete>

     

        <insert id="add" parameterType="com.ujiuye.bean.UserInfo">

            insert into userinfo values (null ,#{username},#{password},#{birthday})

        </insert>

    </mapper>

     

    4.自定义缓存

    public class RedisCache implements Cache {

        private final String id;

        private Jedis jedis;

        public RedisCache(final String id){

            this.id=id;

            System.out.println(">>>>>>>>>id==="+id);

            ApplicationContext context=new ClassPathXmlApplicationContext("bean_core.xml");

            JedisPool jedisPool = context.getBean(JedisPool.class);

            jedis=jedisPool.getResource();

        }

     

        @Override

        public String getId() {

            return this.id;

        }

     

        @Override

        public void putObject(Object key, Object value) {

            jedis.set(key.toString().getBytes(),SerializeUtil.serialize(value));

            System.out.println("===putObject==="+key+"====value="+value);

            jedis.close();

        }

     

        @Override

        public Object getObject(Object key) {

            byte[] bytes = jedis.get(key.toString().getBytes());

            Object value = SerializeUtil.deserialize(bytes);

            System.out.println("===getObject==="+key+"====values=="+value);

            jedis.close();

            return value;

        }

     

        @Override

        public Object removeObject(Object key) {

            //让有效期变成0  ,就自动失效,相当于删除

            Object expire = jedis.expire(key.toString().getBytes(), 0);

            System.out.println("===removeObject=="+expire);

            jedis.close();

            return expire;

        }

     

        @Override

        public void clear() {

            //清空

            jedis.flushDB();

            jedis.close();

        }

     

        @Override

        public int getSize() {

            long size = jedis.dbSize();

            return Integer.parseInt(size+"");

        }

     

        @Override

        public ReadWriteLock getReadWriteLock() {

            return new ReentrantReadWriteLock();

        }

    }

    5.测试:

    @Test

        public void test() throws IOException {

            //1.读取全局配置

            InputStream is= Resources.getResourceAsStream("mybatis_conf.xml");

     

            SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);

     

            SqlSession session=ssf.openSession();

       //执行查询

            UserDao mapper = session.getMapper(UserDao.class);

            List<UserInfo> list = mapper.getAll();

           // System.out.println(list);

     

           //执行更新时,缓存自动删除

            UserInfo u=new UserInfo();

            u.setUsername("admin");

            u.setPassword("123");

            u.setBirthday("2018-2-10 23:12:2");

            mapper.add(u);

            session.commit();

            //不关闭,不会保存缓存

            session.close();

     

        }

    第一次 将结果存入缓存中

    第二次 不再查询,直接从缓存中读取

     

     

  • 相关阅读:
    django.template.exceptions.TemplateDoesNotExist: login.html 错误处理
    pycharm 如何进行全部搜索
    python调用 sshpass
    sshpass 使用方法
    ssh 绕过The authenticity of host '*.*.*.*' can't be established 直接输入密码
    Django深入----django.db.transaction
    django深入----django.db.transaction
    Flask+ Angularjs 实例: 创建博客
    Python --写excel
    Python --链接Mongodb
  • 原文地址:https://www.cnblogs.com/masterhxh/p/13044835.html
Copyright © 2020-2023  润新知