• Redis内存数据库


      这些天项目上赶得有些急,每天都要学一些新东西,像WebLogic配置啊,Redis的用法啊,反向代理服务器啊(其实都是后台大佬家里有事,我就顶着了-_-||),老师布置的读论文的任务不好意思要拖一拖了((。・_・。)ノI’m sorry~啊~),不过今天的东西也很有用,(如果毕设数据量大的话-_-||),相当有用啊。好了,现在开始Redis学习之旅吧。

      Redis 是完全开源免费的一个高性能的key-value数据库

      Redis 有以下三个特点:
    1)Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
    2)Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储(这些数据类型主要指的的是value的,key是正常的字符串)
    3)Redis支持数据的备份

      Redis的安装:

    根据自己的情况,新建一个目录,名字为redis(例如,D: edis),注意路径中不要出现中文字符.

    把下载好的Redis的压缩包解压到新建的指定文件夹中,可见一些可执行文件(版本不同可能此处会有区别)
    redis-server.exe redis 服务器
    redis-cli.exe redis 命令行客户端
    redis-benchmar.exe redis 性能测试工具
    redis-check-aof.exe AOF 文件修复工具

      Redis简单的测试:
    启动Redis服务器
    开启一个cmd窗口
    使用cd命令切换目录到 D: edis
    运行 redis-server.exe redis.windows.conf
    启动成功后会看到启动的图案和启动信息(包括Redis版本、监听端口号等)
    注意:这个服务器的运行窗口不能关闭,如果关闭Redis服务器就停了
    注意:ctrl+c可以也关闭redis服务器

    启动Redis客户端
    另开启一个cmd窗口,原来的不要关闭,不然就无法访问服务端了
    切换到redis目录下运行
    redis-cli.exe -h 127.0.0.1 -p 6379
    或者
    redis-cli.exe
    不加任何参数默认就是127.0.0.1 和 6379

    设置键值对操作 set name briup
    取出键值对操作 get name

    这时候客户端使用shutdown命令可以关闭服务端

    其余的一些命令我也不做详细解释了,我使用Redis的重点在于使用Redis作为Mybatis的二级缓存!!!

    mybatis缓存分为一级缓存和二级缓存

    一级缓存,又叫本地缓存,是PerpetualCache类型的永久缓存,保存在执行器中(BaseExecutor),而执行器又在SqlSession(DefaultSqlSession)中,所以一级缓存的生命周期与SqlSession是相同的。

    二级缓存,又叫自定义缓存,实现了Cache接口的类都可以作为二级缓存,所以可配置如encache等的第三方缓存。二级缓存以namespace名称空间为其唯一标识,被保存在Configuration核心配置对象中。

    所以我们可以自定义缓存类,实现Mybatis提供的缓存接口Cache,其中的方法使用Jedis来实现,然后把这个缓存实现类配置为Mybatis的二级缓存提供者即可

    Jedis相关配置文件和工具类

    redis.properties

    redis.pool.maxTotal=100
    redis.pool.maxIdle=20
    redis.pool.maxWait=3000
    redis.ip=127.0.0.1
    redis.port=6379

    封装Jedis的工具类
    JedisUtils.java

    package com.briup.utils;
    
    import java.util.ResourceBundle;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    
    
    /*
     * 工具类
     */
    public class JedisUtils {
        
        public static JedisPool jedisPool;
        
        static{
            
            //ResourceBundle会查找classpath下的xxx.properties的文件,xxx是方法中指定的
            ResourceBundle resourceBundle = 
                    ResourceBundle.getBundle("redis");
            
            int maxTotal = Integer.parseInt(resourceBundle.getString("redis.pool.maxTotal"));
            int maxIdle = Integer.parseInt(resourceBundle.getString("redis.pool.maxIdle"));
            int maxWait = Integer.parseInt(resourceBundle.getString("redis.pool.maxWait"));
            String ip = resourceBundle.getString("redis.ip");
            int port = Integer.parseInt(resourceBundle.getString("redis.port"));
            
            
            JedisPoolConfig config = new JedisPoolConfig();
            // 设置最大连接数
            config.setMaxTotal(maxTotal);
            // 设置最大空闲数
            config.setMaxIdle(maxIdle);
            // 设置超时时间
            config.setMaxWaitMillis(maxWait);
            // 初始化连接池
            jedisPool = new JedisPool(config, ip, port);
            
        }
        
        
        public static void set(Object key, Object value) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.set(SerializingUtils.serialize(key), SerializingUtils.serialize(value));
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                jedis.close();
            }
        }
    
        
        public static Object get(Object key) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                byte[] keyBytes = SerializingUtils.serialize(key);
                if(jedis.exists(keyBytes)){
                    return SerializingUtils.deserialize(jedis.get(keyBytes));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                jedis.close();
            }
            return null;
        }
        
        public static void del(Object key) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.del(SerializingUtils.serialize(key));
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                jedis.close();
            }
        }
        
        public static void clear() {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.flushDB();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                jedis.close();
            }
        }
        public static int getSize() {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                jedis.close();
            }
            return jedis.dbSize().intValue();
        }
        
        public static Jedis getResource(){
            return jedisPool.getResource();
        }
        
        
    }

    SerializingUtils.java

    package com.briup.utils;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    
    /*
     * 工具类
     */
    public class SerializingUtils {
        
        //java对象 ---> 字节数组
        public static byte[] serialize(Object obj) {
            ByteArrayOutputStream bos = null;
            ObjectOutputStream out = null;
            try {
                bos = new ByteArrayOutputStream();
                out = new ObjectOutputStream(bos);
                out.writeObject(obj);
                out.flush();
            }
            catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if(out!=null)out.close();
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return bos.toByteArray();
        }
        
        //字节数组 ---> java对象
        public static Object deserialize(byte[] data) {
            ObjectInputStream in = null;
            Object obj = null;
            try {
                ByteArrayInputStream bis = new ByteArrayInputStream(data);
                in = new ObjectInputStream(bis);
                obj = in.readObject();
            }catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if(in!=null)in.close();
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return obj;
        }
        
        
    }

    封装MyBatis的工具类
    MyBatisSqlSessionFactory.java

    package com.briup.utils;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class MyBatisSqlSessionFactory {
        private static SqlSessionFactory sqlSessionFactory;
        
        public static SqlSessionFactory getSqlSessionFactory(){
            if(sqlSessionFactory == null){
                InputStream inputStream = null;
                try {
                    inputStream = Resources.getResourceAsStream("mybatis-config.xml"); 
                    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e.getCause());
                }
            }
            return sqlSessionFactory;
        }
        
        public static SqlSession openSession() { 
            return openSession(false); 
        }
        public static SqlSession openSession(boolean autoCommit) { 
            return getSqlSessionFactory().openSession(autoCommit); 
        }
        
    }

    自定义cache接口实现类MybatisRedisCache.java

    package com.briup.cache;
    
    import java.util.concurrent.locks.ReadWriteLock;
    
    import org.apache.ibatis.cache.Cache;
    import org.apache.ibatis.cache.CacheException;
    
    import com.briup.utils.JedisUtils;
    /**
     * Cache为缓存接口,给缓存供应商的SPI(Service Provider Interface)
     * Cache接口的实现类必须有一个具有String类型参数的构造方法,该参数作为实现类对象的id,对其进行唯一标识
     */
    public class MybatisRedisCache implements Cache{
    
        private String id;
        
        public MybatisRedisCache(String id) {
            this.id = id;
        }
        
        /**
         * 清空缓存
         */
        @Override
        public void clear() {
            JedisUtils.clear();
        }
        
        /**
         * 获取缓存类对象的唯一标识
         */
        @Override
        public String getId() {
            return this.id;
        }
        
        /**
         * 从缓存中获取key对应的value
         */
        @Override
        public Object getObject(Object key) {
            return JedisUtils.get(key);
        }
        
        
        /**
         * 获取读写锁
         * 可选的方法,从3.2.6起这个方法不再被框架核心调用
         * 任何需要的锁,都必须由缓存供应商提供
         */
        @Override
        public ReadWriteLock getReadWriteLock() {
            
            return null;
        }
        
        /**
         * 获取缓存对象中存储的键/值对的数量
         * 可选的方法,没有被框架核心调用
         */
        @Override
        public int getSize() {
            return JedisUtils.getSize();
        }
        
        /**
         * 保存key/value到缓存对象中
         * key可以是任何对象
         */
        @Override
        public void putObject(Object key, Object value) {
            JedisUtils.set(key, value);
        }
        
        
        /**
         * 可选的方法,没有被核心框架调用,移除key对应的value
         */
        @Override
        public Object removeObject(Object key) {
            
            return null;
        }
        
        /**
         * 重新equals方法
         */
        @Override
        public boolean equals(Object o) {
            if (getId() == null)
                throw new CacheException("Cache instances require an ID.");
            if (this == o)
                return true;
            if (!(o instanceof Cache))
                return false;
    
            Cache otherCache = (Cache) o;
            return getId().equals(otherCache.getId());
        }
        
        /**
         * 重新hashCode方法
         */
        @Override
        public int hashCode() {
            if (getId() == null)
                throw new CacheException("Cache instances require an ID.");
            return getId().hashCode();
        }
    
    }

    在mybatis中开启二级缓存(虽然默认也是开启的)

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

    配置<cache/>标签
    在需要缓冲的映射文件中加入<cache/>标签,并且指定提供缓存功能的cache实现类的全限定名

    <cache type="XXX.MybatisRedisCache"></cache>

    测试:

      第一次运行,mybatis【发出】对应select进行查询数据库,然后在redis中查看key可知,已经把数据存进了redis中,
    之后再运行,mybatis【不发出】sql语句,数据直接从redis中取出

  • 相关阅读:
    序列化与反序列化
    进程与线程
    winform基础
    MD5加密
    Docker安装Nextcloud+collabora office+ocdownloader
    Docker安装MariaDB
    Docker 安装 Nginx
    Docker命令大全
    Docker之镜像操作
    Linux入门-Docker安装
  • 原文地址:https://www.cnblogs.com/wsyblog/p/8686534.html
Copyright © 2020-2023  润新知