美文网首页
第四课 项目中使用redis

第四课 项目中使用redis

作者: Arroganter | 来源:发表于2018-08-27 08:39 被阅读1次

    二、项目中使用redis

    2.1、使用jedis操作redis测试

    进行测试之前需要引入依赖

    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
    </dependency>
    

    测试:

    @Test
        public void testJedis() throws Exception{
            //创建一个连接jedis对象,参数:host,port
            Jedis jedis = new Jedis("192.168.25.128", 6379);
            //直接使用jedis来操作redis,所有jedis的命令都对应一个方法
            jedis.set("test123", "my first jedis test");
            String s = jedis.get("test123");
            System.out.println(s);
            //关闭连接
            jedis.close();
        }
        输出结果:my first jedis test
        去客户端查看:
        192.168.25.128:6379> get test123
        "my first jedis test"
    

    这里只测试了String类型,Jedis提供了与redis操作对应的方法来操作redis。
    操作hash类型主要有:hset(…),hget(…),hdel(…),hexist(…)
    key命令:persist(key),expire(key,seconds)
    具体的根据提示来选择自己需要的。

    测试,从连接池获取jedis:

        @Test//连接
        public void testJedisPool() throws Exception{
            JedisPool jedisPool = new  JedisPool("192.168.25.128", 6379);
            //从连接池获得一个连接,就是一个jedis对象
            Jedis jedis = jedisPool.getResource();
            //操作redis
            String s = jedis.get("test123");
            System.out.println(s);
            //关闭连接,每次使用完毕后关闭连接,连接池回收资源
            jedis.close();
            //关闭连接池
            jedisPool.close();
        }
    

    这个就跟从数据库连接池获取连接道理是一样的,需要连接的时候从连接池中取获取一个连接就行,使用完后就放回连接池,而不用重新去创建一个连接,这项技术能大大提高操作redis的性能。

    2.2、使用JedisClient操作redis

    测试的时候我们发现,每次都要自己创建关闭连接,频繁使用的话会显得很繁琐。所以我们可以一开始就定义好对应方法来帮我们关闭连接。使用的时候调用自己的方法即可。

    接口如下:

    public interface JedisClient {
        String set(String key, String value);
        String get(String key);
        Boolean exists(String key);
        Long expire(String key, int seconds);
        Long ttl(String key);
        Long incr(String key);
        Long hset(String key, String field, String value);
        String hget(String key, String field);
        Long hdel(String key, String... field);
        Boolean hexists(String key, String field);
        List<String> hvals(String key);
        Long del(String key);
    }
    

    这里定义的方法主要是针对String类型,Hash类型,key命令。
    比如String类型,Hash类型的存储、获取、删除、是否存在指定key,设置过期时间,自增,自间,有效时间等。

    实现类如下:

    public class JedisClientPool implements JedisClient {
    
        private JedisPool jedisPool;
    
        public JedisPool getJedisPool() {
            return jedisPool;
        }
        public void setJedisPool(JedisPool jedisPool) {
            this.jedisPool = jedisPool;
        }
        public String set(String key, String value) {
            Jedis jedis = jedisPool.getResource();
            String result = jedis.set(key, value);
            jedis.close();
            return result;
        }
        public String get(String key) {
            Jedis jedis = jedisPool.getResource();
            String result = jedis.get(key);
            jedis.close();
            return result;
        }
        public Boolean exists(String key) {
            Jedis jedis = jedisPool.getResource();
            Boolean result = jedis.exists(key);
            jedis.close();
            return result;
        }
        public Long expire(String key, int seconds) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.expire(key, seconds);
            jedis.close();
            return result;
        }
        public Long ttl(String key) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.ttl(key);
            jedis.close();
            return result;
        }
    
        public Long incr(String key) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.incr(key);
            jedis.close();
            return result;
        }
        public Long hset(String key, String field, String value) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.hset(key, field, value);
            jedis.close();
            return result;
        }
        public String hget(String key, String field) {
            Jedis jedis = jedisPool.getResource();
            String result = jedis.hget(key, field);
            jedis.close();
            return result;
        }
        public Long hdel(String key, String... field) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.hdel(key, field);
            jedis.close();
            return result;
        }
        public Boolean hexists(String key, String field) {
            Jedis jedis = jedisPool.getResource();
            Boolean result = jedis.hexists(key, field);
            jedis.close();
            return result;
        }
        public List<String> hvals(String key) {
            Jedis jedis = jedisPool.getResource();
            List<String> result = jedis.hvals(key);
            jedis.close();
            return result;
        }
        public Long del(String key) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.del(key);
            jedis.close();
            return result;
        }
    }
    

    其实这些方法主要还是调用了jedis的方法,主要是帮我们创建、关闭了连接然后进行封装,从而在项目中使用可以简化操作。

    2.3、从Spring容器中获取JedisClient

    在案例中,JedisClient是与Spring整合的。不然每次都要自己创建JedisClient对象,使用Spring那么就不用我们自己创建对象了。

    JedisClient与spring整合:applicationContext-redis.xml
    
    <!-- 连接-->
        <bean class="cn.e3mall.jedis.JedisClientPool">
            <property name="jedisPool" ref="jedisPool"/>
        </bean>
        配置jedis连接池
        <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
            <constructor-arg name="host" value="192.168.25.128"/>
            <constructor-arg name="port" value="6379"/>
        </bean>
    

    这样初始化Spring容器的时候就会创建JedisClient了

    测试:

    public void testJedisClient() throws Exception{
            ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
            //从容器中拿到JedisClient对象
            JedisClient jc = ac.getBean(JedisClient.class);
            jc.set("mytest", "jedisClient");
            String s = jc.get("mytest");
            System.out.println(s);  
        }
    
    输出:jedisClient
    

    到这里就可以大胆的在项目中使用JedisClient来操作redis了。

    2.4、实现redis在文章案例中进行缓存

    2.4.1、在文章详情中使用redis
    点击某篇文章会进入到文章详情页。这里也使用了redis,比如某篇文章很热门,那么单位时间的浏览量就会很高,对于这种情况我们可以将文章信息添加到redis中。

    点击文章的时候会根据文章id去redis中查询是否存在该文章信息,有的话直接响应,如果没有那么就去查数据库,查出来的数据存到redis中再做响应。

    但文章信息不能一直在redis中存放,文章过多的话非常耗费redis的存储空间,所以需要设置一下过期时间,如果这段时间该文章没人访问的话就应该将该文章信息从redis中清除来释放空间,如果有人访问的话那么就重新设置回原来的过期时间。

    @Service
    public class ArticleService implements IArticleService {
    
        @Autowired
        ArticleMapper articleMapper;
    
        @Autowired
        CommentMapper commentMapper;
        @Autowired
        private SolrServer solrServer;
    
        @Autowired
        private JedisClient jedisClient;
        @Value("${REDIS_ITEM_PRE}")
        private String REDIS_ITEM_PRE;
        @Value("${ITEM_CACHE_EXPIRE}")
        private Integer ITEM_CACHE_EXPIRE;
    
    
      
        @Override
        public Article getArticleByID(int aid) {
            jedisClient.del(REDIS_ITEM_PRE+":"+aid+":BASE");
    
            try {
                String string = jedisClient.get(REDIS_ITEM_PRE+":"+aid+":BASE");
    
                if(string !=null && !string.isEmpty()){
                    Article tbItem = JSON.parseObject(string,new TypeReference<Article>() {});
                    return tbItem;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            Article article = articleMapper.getArticleByID(aid);
    
            if(article != null){
                //把结果添加到缓存
                try {
                    jedisClient.set(REDIS_ITEM_PRE+":"+aid+":BASE", JSON.toJSONString(article));
                    //设置过期时间
                    jedisClient.expire(REDIS_ITEM_PRE+":"+aid+":BASE", ITEM_CACHE_EXPIRE);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return article;
            }else{
                return null;
            }
    
        }
    }
    

    applicationContext-redis.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">
    
    
            <!--<bean class="com.neusoft.util.JedisClientPool">-->
                    <!--<property name="jedisPool" ref="jedisPool"/>-->
            <!--</bean>-->
    
            <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
                    <constructor-arg name="host" value="192.168.47.141"/>
                    <constructor-arg name="port" value="6379"/>
            </bean>
            <context:property-placeholder location="classpath:app.properties"/>
    
    </beans>
    

    这里使用的是String类型,写成 前缀:d:后缀,这种形式在桌面版redis客户端中文件目录会有层次结构。

    Redis实现缓存同步
    考虑这么个问题,如果在后台我们修改或删除了文章信息,这就存在信息不同步问题了。这里解决的办法是,每次修改或删除了文章,那么就需要清空redis中的信息。当下次访问首页的时候会去数据库中查询最新的内容信息,存放到redis中,从而实现了缓存同步,代码如下。

    jedisClient.del(REDIS_ITEM_PRE+":"+aid+":BASE");

    相关文章

      网友评论

          本文标题:第四课 项目中使用redis

          本文链接:https://www.haomeiwen.com/subject/tqtjiftx.html