HashMap与redis在项目中的应用

刚从.net转java三个月,这里记录一下在java项目中使用缓存的学习。

因为项目之前的开发人员离职了,在之前的项目上进行维护,对应从来没有接触过java的小白,只能自己多看多理解多动手了。

这个项目原来是没有用java真正意义上的缓存,而是用的静态的HashMap,但是在性能测试的过程中出现了死锁的过程,因为hashmap是不安全的线程,建议使用ConcurrentHashMap这个和.net的Dictonary很像。因为性能测试不通过,所以后来加了redis,其实java的一级缓存ehcache也是很好的,因为项目到了后期阶段,项目时间紧就没改ehcahe(这个.net的asp.net cache一样)。

言归正传:

hashmap的使用方法:

首先定义一个InitCacheData类,里面填充各种属性和方法。

public class InitCacheData {
    private static InitCacheData instance;

    private InitCacheData() {
    }

    /**
     * description 单例模式
     * @param @return
     * @return InitCacheData
     */
    public static InitCacheData getInstance() {
        synchronized (InitCacheData.class) {
            if (instance == null) {
                instance = new InitCacheData();
            }
            return instance;
        }
    }

    /**
     * 初始化数据的缓存,key:数据类型,value:数据(key:实体类主键的值,value对应的实体类)
     */
    private Map<CacheType, Map<Integer, Object>> cacheData = new HashMap<CacheType, Map<Integer, Object>>();
    private Map<CacheType, Map<Integer, List<Object>>> cacheTreeData = new HashMap<CacheType, Map<Integer, List<Object>>>();
    private Map<CacheType, Map<String, Object>> cacheItemMappingData = new HashMap<CacheType, Map<String, Object>>();

    private Map<String,List<SingleTrainStudentAnswer>> cacheAnswerData = new ConcurrentHashMap<String,List<SingleTrainStudentAnswer>>();
    private Map<CacheType,List<ProjectItem>> projectItemData = new HashMap<CacheType,List<ProjectItem>>();

    /**
     * @description 初始化数据的类型
     */
    public enum CacheType {
        CLASS, MAJOR, COLLEGE, COURSE,USER_INFO,KNOW_POINT,STUDENT,TEACHER,ITEMMAPPING,PARAMETER_TYPE,TRDCO,ANSWER,PROJECTITEM,BASEITEMS
    };

    public Map<Integer, Object> getCacheData(CacheType dataType){
        return this.cacheData.get(dataType);
    }

    public Map<CacheType, List<ProjectItem>> getBasicItemsData() {
        return basicItemsData;
    }

    /**
     * description 初始化数据执行的方法
     * @param
     * @return void
     */
    public void initData() {

        initCourseData();
        initBasicItemsData();

    }

    //获取学生练习列表:对应登录后的练习菜单
    private void initBasicItemsData() {
        IProjectItemService projectItemService = (IProjectItemService) SpringContextUtil.getBean("projectItemService");
        List<ProjectItem> list = projectItemService.getBasicItems();
        if(basicItemsData.get(CacheType.BASEITEMS)!=null) {
            basicItemsData.get(CacheType.BASEITEMS).clear();
        }
        basicItemsData.put(CacheType.BASEITEMS,list);
    }

    private void initCourseData() {
        ICourseService courseService = (ICourseService)SpringContextUtil.getBean("courseService");
        List<Course> courseList = courseService.findAll();
        Map<Integer, Object> courseMap = new HashMap<Integer, Object>(courseList.size());
        Iterator<Course> courseIt = courseList.iterator();
        Course course = null;
        while(courseIt.hasNext()){
            course = courseIt.next();
            courseMap.put(course.getId(), course);
        }

        if(cacheData.get(CacheType.COURSE) != null){
            cacheData.get(CacheType.COURSE).clear();
        }
        cacheData.put(CacheType.COURSE, courseMap);
    }

    /**
     * @description 通过递归获得所有选中节点下面的所有节点id
     * @param
     * @return void
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void getChildNodes(List<Integer> idsList,int nodeId){
        Map<Integer,List<Object>> knowPointMap = cacheTreeData.get(CacheType.KNOW_POINT);
        if(knowPointMap.containsKey(nodeId)){
            List<KnowPoint> knowPointList = (List)knowPointMap.get(nodeId);
            for(KnowPoint know : knowPointList){
                idsList.add(know.getId());
                getChildNodes(idsList,know.getId());
            }
        }

    }
    

redis的使用方法:

1.在maven项目中添加引用依赖

 1 <dependency>
 2             <groupId>org.springframework.data</groupId>
 3             <artifactId>spring-data-redis</artifactId>
 4             <version>1.5.0.RELEASE</version>
 5         </dependency>
 6         <dependency>
 7             <groupId>redis.clients</groupId>
 8             <artifactId>jedis</artifactId>
 9             <version>2.9.0</version>
10         </dependency>
11         

2.要创建spring-redis.xml

<beans     xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
               ">

    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="minIdle" value="${redis.minIdle}" />
        <property name="maxTotal" value="${redis.maxTotal}" />
        <property name="maxWaitMillis" value="${redis.max-wait-millis}" />
    </bean>  

    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
        p:host-name="${redis.host}"
        p:port="${redis.port}"
        p:password="${redis.password}"
        p:database="0"
        p:timeout="${redis.timeout}"
        p:pool-config-ref="poolConfig"/>  

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory"   ref="connectionFactory" />
        <property name="defaultSerializer"   ref="jdkSerializationRedisSerializer" />
    </bean>
    <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
        <property name="connectionFactory"   ref="connectionFactory" />
    </bean>
    <bean id="jdkSerializationRedisSerializer" class=" org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
</beans>  

3.添加redis.properties配置文件

#redis setting
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
redis.maxIdle=100
redis.maxActive=300
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=100000

fep.local.cache.capacity =10000

4.在spring-context.xml文件中导入redis配置 <import resource="spring-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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/task
       http://www.springframework.org/schema/task/spring-task-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
       http://www.springframework.org/schema/jms
       http://www.springframework.org/schema/jms/spring-jms-3.2.xsd">
    <!-- 启用annotation方式 -->
    <task:annotation-driven scheduler="myScheduler" />

    <!-- 配置任务线程池 -->
    <task:scheduler id="myScheduler" pool-size="5" />
    <context:annotation-config/>

    <!-- 设置属于Spring管理的类 -->
    <context:component-scan base-package="com.gta">
        <!-- 排除com.gta.demo.controller包下的类,由SpringMVC来管理 -->
        <context:exclude-filter type="regex" expression="com.gta.kjzh.controller.*"/>
    </context:component-scan>

    <!-- 设置项目中可以获取到的properties配置文件 -->
    <context:property-placeholder location="classpath*:/config/*.properties"/>

    <!-- 设置Druid数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <!-- 数据源URL -->
        <property name="url" value="${url}"/>
        <!-- 数据库用户名 -->
        <property name="username" value="${db.username}"/>
        <!-- 数据库密码 -->
        <property name="password" value="${db.password}"/>
        <!-- 数据库驱动 -->
        <property name="driverClassName" value="${driverClassName}"/>

        <!-- 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall -->
        <property name="filters" value="${druid.filters}"/>

        <!-- 最大连接池数量 -->
        <property name="maxActive" value="${maxActive}"/>
        <!-- 初始化时建立物理连接的个数 -->
        <property name="initialSize" value="${initialSize}"/>
        <!-- 获取连接时最大等待时间,单位毫秒 -->
        <property name="maxWait" value="${maxWait}"/>
        <!-- 启用非公平锁 -->
        <property name="useUnfairLock" value="true"/>
        <!-- 最小连接池数量 -->
        <property name="minIdle" value="${minIdle}"/>

        <!-- 有两个含义:
            1) Destroy线程会检测连接的间隔时间
            2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明 -->
        <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}"/>

        <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}"/>

        <!-- 用来检测连接是否有效的sql,要求是一个查询语句,如果validationQuery为null,testOnBorrow、testOnReturn、 testWhileIdle都不会其作用 -->
        <property name="validationQuery" value="${validationQuery}"/>
        <!-- 建议配置为true,不影响性能,并且保证安全性。 申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。-->
        <property name="testWhileIdle" value="${testWhileIdle}"/>
        <!-- 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 -->
        <property name="testOnBorrow" value="${testOnBorrow}"/>
        <!-- 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->
        <property name="testOnReturn" value="${testOnReturn}"/>
        <!-- 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 -->
        <!--<property name="maxOpenPreparedStatements" value="${maxOpenPreparedStatements}"/>-->
        <!-- 打开removeAbandoned功能 -->
        <property name="removeAbandoned" value="${removeAbandoned}"/>
        <!-- 1800秒,也就是30分钟 -->
        <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}"/>
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="logAbandoned" value="${logAbandoned}"/>
    </bean>

    <!-- spring上传文件配置,这里申明的id必须为multipartResolver -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="314572800" />
    </bean> 

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>  

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
            <props>
                <!-- 设置数据库方言 -->
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <!--<prop key="hibernate.current_session_context_class">${hibernate.current_session}</prop>-->
                <!-- 设置是否在控制台输出sql语句 -->
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <!-- 输出格式化的sql语句 -->
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <!-- 设置项目启动时,hibernate检查数据库和实体类是否匹配 -->
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>

                <!-- hibernate ehcache 配置  EhCacheRegionFactory-->
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory </prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                 <!-- 二级缓存配置文件路径 /resources/hibernate-->
                <prop key="net.sf.ehcache.configurationResourceName">/config/ehcache.xml</prop>

            </props>
        </property>
        <!-- 扫描受Hibernate管理的实体类所在的包-->
        <property name="packagesToScan" value="com.gta.kjzh.*"/>
    </bean>

    <bean id="genericDao" class="com.gta.kjzh.sdk.base.dao.HibernateGenericDAO"></bean>

    <!-- 设置spring使用Hibernate的事务处理方式 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 设置事务注解使用spring事务管理的方式 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
    <!-- 通用springMVC拦截器的设置
    <bean id="springMVCInterceptor" class="com.gta.filter.SpringMVCInterceptor"></bean>
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="springMVCInterceptor"/>
            </list>
        </property>
    </bean> 

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
       <tx:attributes>
          <tx:method name="get*" read-only="true" propagation="REQUIRED"/>
          <tx:method name="find*" read-only="true" propagation="REQUIRED"/>
          <tx:method name="save*" propagation="REQUIRED"/>
          <tx:method name="update*" propagation="REQUIRED"/>
          <tx:method name="remove*" propagation="REQUIRED"/>
          <tx:method name="add*" propagation="REQUIRED"/>
          <tx:method name="*"/>
       </tx:attributes>
    </tx:advice>

    <aop:config proxy-target-class="true">
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.gta.kjzh.*.service..*.*(..))"/>
    </aop:config>-->
    <!-- <import resource="activemq.xml"/> -->
    <import resource="spring-redis.xml"/>
    <!-- <import resource="spring-quartz-answer.xml"/>
    <import resource="spring-quartz.xml"/>  -->
</beans>

5.编辑RedisCache类,里面放有redis的增删改查操作。

package com.kjzh.redis.cache;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import com.gta.kjzh.util.SerializeUtils;

import net.sf.ehcache.CacheException;
@Component
public class RedisCache<K, V> {
    private static String redisCode = "utf-8";
    private String prefix;
    @Autowired
    private RedisTemplate<byte[], V> redisTemplate;

    @Autowired
    private RedisTemplate<String, String> stringRedisTemplate;

    public Set<String> getKeys(String keyPattern) {
        return stringRedisTemplate.keys(keyPattern);
    }

    public String getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    public void setString(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    public V get(K key) {
        byte[] bkey = getByteKey(key);
        return redisTemplate.opsForValue().get(bkey);
    }

    public void set(K key, V value) {
        byte[] bkey = getByteKey(key);
        redisTemplate.opsForValue().set(bkey, value);
    }

    public void remove(K key) {
        byte[] bkey = getByteKey(key);
        redisTemplate.delete(bkey);
    }

    public void set(K key, V value, long timeout) {

         byte[] bkey = getByteKey(key);
        redisTemplate.opsForValue().set(bkey, value, timeout, TimeUnit.SECONDS);
    }

     String get(K key, long start, long end){
         byte[] bkey = getByteKey(key);
         return redisTemplate.opsForValue().get(bkey,start,end);
     }
     Long size(K key){
         byte[] bkey = getByteKey(key);
         return redisTemplate.opsForValue().size(bkey);
     }

     List<V> range(K key, long start, long end){
         byte[] bkey = getByteKey(key);
         return redisTemplate.opsForList().range(bkey,start,end);
     }

     public void clear() throws CacheException {
         redisTemplate.getConnectionFactory().getConnection().flushDb();
     }

     public List<V> getListValue(K key) {
             byte[] bkey = getByteKey(key);
            ListOperations<byte[], V> list = redisTemplate.opsForList();
            return redisTemplate.opsForList().range(bkey, 0,list.size(bkey));

     }

     private byte[] getByteKey(K key){
            if(key instanceof String){
                String preKey = this.prefix + key;
                return preKey.getBytes();
            }else{
                return SerializeUtils.serialize(key);
            }
        }

     public String getPrefix() {
            return prefix;
     }

     /**
     * 批量删除对应的value
     *
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 批量删除key
     *
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0)
            redisTemplate.delete(keys);
    }

    /**
     * 判断缓存中是否有对应的value
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

}

6.具体使用

if(redisCache.get(answerkey)!=null) {
                redisCache.remove(answerkey);
            }
            redisCache.set(answerkey,reCombinsList);

原文地址:https://www.cnblogs.com/songStar/p/9359176.html

时间: 2024-07-29 15:37:13

HashMap与redis在项目中的应用的相关文章

redis在项目中的应用

redis在项目中的应用  ps:PHP 会自动 关redis连接 不需要手动关 对于临时的数据 可以不经过数据库直接redis上操作<pre>/*消息队列实例 消息队列详细步骤在http://newmiracle.cn/?p=227*/public function insertinfo(){  //连接本地的 Redis 服务        $redis = new \Redis();        $redis->connect('127.0.0.1', 6379);       

spring3.0结合Redis在项目中的运用

推荐一个程序员的论坛网站:http://ourcoders.com/home/ 以下内容使用到的技术有:Redis缓存.SpringMVC.Maven.项目中使用了redis缓存,目的是在业务场景中,提高SQL的查询效率,做出性能优化.先看pom.xml的配置文件中,Jedis是Redis的Java客户端,Jedis基本实现了Redis的所有功能.在使用的时候,我们创建一个Jedis对象,通过操作Jedis来操作Redis,实现我们的业务场景需求.项目中使用了Maven来托管,先看Jedis在p

redis在项目中的运用

先引用百度百科的一段话吧,具体可以到百科查看吧. Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMware主持.从2013年5月开始,Redis的开发由Pivotal赞助. 官方下载地址:http://redis.io/download,不过官方没有64位的Windows下的可执行程序,目前有个开源的托管在github上, 地址:https://githu

redis在项目中的使用

缓存的使用就是为了提高效率,避免重复的IO操作浪费效率. 查询时使用,如selectById value:缓存区名称,key:在缓存区内对应的键, 表示查询缓存区“user”中key为参数id的缓存,如果没有则查询数据库,并把数据放入缓存中(注意这里缓存的数据是指方法执行完成返回的结果),以后直接从缓存取数据. @Cacheable(key = "#id", value = "user") 查询时使用,如getAll value:缓存区名称,key:没有指定采用默认

Liunx下Redis集群的安装与测试,以及项目中的应用(redis中对象和集合的储存)。

Liunx下Redis集群的安装与测试,以及项目中的应用. 首先准备ruby和redis接口: redis-3.0.0.gem和 去https://redis.io/下载 1.使用ruby脚本搭建集群.需要ruby的运行环境. 安装ruby yum install ruby yum install rubygems 1.1安装ruby脚本运行使用的包. [[email protected] ~]# gem install redis-3.0.0.gem Successfully installe

项目中使用Redis的一些总结和体会

第一部分:为什么我的项目中要使用Redis 我知道有些地方没说到位,希望大神们提出来,我会吸取教训,大家共同进步! 注册时邮件激活的部分使用Redis 发送邮件时使用Redis的消息队列,减轻网站压力. 使用Lucene.Net在进行分词时使用Redis消息队列和多线程来避免界面卡死等性能问题. 请大家先思考一个问题:这个问题在大并发.高负载的网站中必须考虑!大家思考如何让速度更快. 三种方法:(1)数据库(2)页面静态化(3)Redis.Memcached 第二部分:Redis是什么 概述:r

【新手总结】在.Net项目中使用Redis作为缓存服务

最近由于项目需要,在系统缓存服务部分上了redis,终于有机会在实际开发中玩一下,之前都是自己随便看看写写,很零碎也没沉淀下来什么,这次算是一个系统学习和实践过程的总结. 和Redis有关的基础知识 Redis是一个开源的分布式NoSql数据库,可以用来做缓存服务.消息队列.数据存储等等,数据类型之丰富,效率之高,简直逆天!没有了解过的可以移步去问度娘~客户端之丰富,足可见它的社区有多强大: 其中C#的客户端就有这么多: 没错,我们的项目里也选择了最热门的StackExchange.Redis作

OpenResty--mysql,redis 项目中的应用

最近刚刚接手同事的OpenResty的项目,发现对mysql,redis的操作没有用连接池,故对此进行了改造. MYSQL 主要是通过mysql_pool.lua 和 dbutil.lua 来封装对数据库的操作 mysql_pool.lua: 1 module("mysql_pool", package.seeall) 2 3 local dbConfig = require"config" 4 local mysql = require("resty.m

简单介绍在C# 项目中使用 redis

搜索了一圈, 发现没有比较全面且简单的介绍如何在C#项目中使用redis的, 大部分都是零碎的文章,稍微组织了一下,希望对要用redis的人有帮助. 前提 1. Redis is an open source, BSD licensed, advanced key-value store, 简单说用来缓存数据,更多信息参照官网 http://redis.io/,很多大网站都在用这个, 参照 http://redis.io/topics/whos-using-redis. 2. Redis官方是没