本地缓存Caffeine的使用

缓存的用途:
用于减小对数据库的访问次数,频繁的访问数据库产生很大的开销,影响程序的执行效率!引入缓存,效率能几何倍递增。
缓存的应用思想:
初次查询时,添加缓存。修改方法时去除缓存

// 最大缓存数量
    public static final int MAX_SIZE = 10000;
    // 自动失效时间(分钟)
    public static long expireAfterWriteMinutes = 60;插入代码片

private LoadingCache<Long, Object> idCacheFunction = null;
    @Autowired
    IdCacheFunctionLoader idCacheFunctionLoader;

@Override
    public SecuritysFunction findById(Integer id) {
        if(id==null){
            return null;
        }
        Object object;
        try {
            securitysFunction = getIdCache().get(id);
        } catch (Exception e) {
            return null;
        }
        return securitysFunction;
    }

 private LoadingCache<Long, SecuritysFunction> getIdCache() {
        if (null != this.idCacheFunction) {
            return this.idCacheFunction;
        }
        // 临界区-排队
        synchronized (this) {
            //
            if (null != this.idCacheFunction) {
                return this.idCacheFunction;
            }
            this.idCacheFunction = Caffeine.newBuilder()
                    .maximumSize(MAX_SIZE)
                    .expireAfterWrite(expireAfterWriteMinutes, TimeUnit.MINUTES)
                    .build(idCacheFunctionLoader);
        }
        return this.idCacheFunction;
    }

/**
缓存加载器
*/
@Component
    public class IdCacheFunctionLoader implements CacheLoader<Long, Object> {
        @Override
        public SecuritysFunction load(Long id) throws Exception {
            if (null == id){
                return null;}
            SecuritysFunction entity = ecuritysFunctionMapper.selectByPrimaryKey(id);
            return entity;
        }
    }

(2)之前封装的一个缓存方法

package com.mepu.mygis.manager.util;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.mepu.mygis.manager.config.Constant;
import com.mepu.mygis.manager.config.Enum;
import com.mepu.mygis.manager.domain.po.mygis.ObjectAndShape;

import com.mepu.mygis.manager.domain.po.mygis.ThirdInvCcwjq;
import com.mepu.mygis.manager.util.GetGeometryUtil;
import org.apache.poi.ss.formula.functions.T;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @创建人
 * @创建时间 2019/12/4 09:53
 * @描述
 */
@Component
public class CacheUtil{
    // 最大缓存数量
    public static final int MAX_SIZE = 10000;
    // 自动失效时间(分钟)
    public static long expireAfterWriteMinutes = 60;
    //正确数据缓存容器
    public static Cache <String, List<Object>> cache=null;
    //不正确数据缓存容器
    public static Cache <String, List<ObjectAndShape>> cacheError=null;

    public static Cache<String, Long> cacheCount=null;




    ObjectAndShape objectAndShape = null;



    public  Cache <String, List<Object>> cacheShapeList(Object entity) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        synchronized (this){
            Class <?> aClass = entity.getClass();
            Object o = aClass.newInstance();
            Field[] declaredFields = aClass.getDeclaredFields();
            for (int i=0;i<declaredFields.length-1;i++) {
                Field declaredField = aClass.getDeclaredField(declaredFields[i].getName());
                declaredField.setAccessible(true);
                declaredField.set(o,declaredField.get(entity));

            }
            Field shapeField = aClass.getDeclaredField("shape");
            Field maxXField = aClass.getDeclaredField("maxX");
            Field maxYField = aClass.getDeclaredField("maxY");
            Field minXField = aClass.getDeclaredField("minX");
            Field minYField = aClass.getDeclaredField("minY");
            Field batchField =aClass.getDeclaredField("batchId");
            shapeField.setAccessible(true);
            maxXField.setAccessible(true);
            maxYField.setAccessible(true);
            minXField.setAccessible(true);
            minYField.setAccessible(true);
            batchField.setAccessible(true);
            String shape = shapeField.get(o).toString();
            String batchId = batchField.get(o).toString();
            //生成几何图形
            Geometry geometry = GetGeometryUtil.getGemetrys(shape);
            //获取几何图形的最小边界
            Envelope envelope = geometry.getEnvelopeInternal();
            Double minX = envelope.getMinX();
            Double minY = envelope.getMinY();
            Double maxX = envelope.getMaxX();
            Double maxY = envelope.getMaxY();
            minXField.set(o,new BigDecimal(minX).setScale(15, BigDecimal.ROUND_HALF_UP));
            minYField.set(o,new BigDecimal(minY).setScale(15, BigDecimal.ROUND_HALF_UP));
            maxXField.set(o,new BigDecimal(maxX).setScale(15, BigDecimal.ROUND_HALF_UP));
            maxYField.set(o,new BigDecimal(maxY).setScale(15, BigDecimal.ROUND_HALF_UP));
            StringBuilder key=new StringBuilder();
            key.append(aClass.getSimpleName());
            key.append(batchId);

            if(cache!=null){
                List <Object> ifPresent = CacheUtil.cache.getIfPresent(key.toString());
                if(ifPresent!=null){
                    ifPresent.add(o);
                    cache.put(key.toString(), ifPresent);
                }else{
                    List <Object> list = new ArrayList <>();
                    list.add(o);
                    cache.put(key.toString(), list);
                }

                return CacheUtil.cache;
            }else{
                cache = Caffeine.newBuilder()
                        .expireAfterWrite(expireAfterWriteMinutes, TimeUnit.MINUTES)
                        .maximumSize(10)
                        .build();
                List <Object> list = new ArrayList <>();
                list.add(o);
                cache.put(key.toString(), list);

            }
        }

        return cache;

        }

    /**
     * 处理添加数据不正常数据的缓存
     * @param entity
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public  Cache <String, List<ObjectAndShape>> cacheErrorList(Object entity, Integer errorCheckStatus) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        synchronized (this){
            if(cacheError!=null){
                Class <?> aClass = entity.getClass();
                List <ObjectAndShape> ifPresent = CacheUtil.cacheError.getIfPresent(aClass.getSimpleName());
                System.err.println("**********缓存数之前*************"+ifPresent.size());
                Field objectidField = aClass.getDeclaredField("objectid");
                Field shapeField = aClass.getDeclaredField("shape");
                objectidField.setAccessible(true);
                shapeField.setAccessible(true);
                Integer objectId = Integer.valueOf(objectidField.get(entity).toString());
                String shape=shapeField.get(entity).toString();
                objectAndShape = new ObjectAndShape();
                objectAndShape.setObjectId(objectId);
                //objectAndShape.setShape(shape);
                objectAndShape.setErrorCheckName(Enum.ErrorDataStatus.getName(errorCheckStatus));
                ifPresent.add(objectAndShape);
                cacheError.put(aClass.getSimpleName(), ifPresent);


                System.err.println("**********缓存数*************"+ifPresent.size());
                return CacheUtil.cacheError;
            }else{

                cacheError = Caffeine.newBuilder()
                        .expireAfterWrite(expireAfterWriteMinutes, TimeUnit.MINUTES)
                        .maximumSize(10)
                        .build();
                List <ObjectAndShape> list = new ArrayList <>();
                System.err.println(entity);
                Class <?> aClass = entity.getClass();
                System.err.println(aClass.getSimpleName());

                Field objectidField = aClass.getDeclaredField("objectid");
                Field shapeField = aClass.getDeclaredField("shape");
                objectidField.setAccessible(true);
                shapeField.setAccessible(true);
                Integer objectId = Integer.valueOf(objectidField.get(entity).toString());
                //String shape=shapeField.get(entity).toString();
                objectAndShape = new ObjectAndShape();
                objectAndShape.setObjectId(objectId);
                //objectAndShape.setShape(shape);
                list.add(objectAndShape);
                cacheError.put(aClass.getSimpleName(), list);

            }
        }
        return cacheError;

    }

        public Cache<String, Long> createCacheCount(String key, Long value){
        /**
         * @Author:         
         * @Description: 创建缓存容器,如果没有则创建。有则添加key
         * @param: [key, value]
         * @return: com.github.benmanes.caffeine.cache.Cache
         * @CreateDate:     2019/12/5
         * @UpdateUser:
         * @UpdateDate:     2019/12/5
         * @UpdateRemark:   修改内容
         * @Version:        1.0
         */

        synchronized(this){
            if(cacheCount!=null){
                cacheCount.put(key, value);
                return cacheCount;
            }else{
                cacheCount = Caffeine.newBuilder()
                        .expireAfterWrite(expireAfterWriteMinutes, TimeUnit.MINUTES)
                        .maximumSize(10)
                        .build();
                cacheCount.put(key, value);
            }
        }
        return cacheCount;
        }

}

(3)踩过的坑
本地缓存主要存放在内存,不要放太大太多的数据,容易内存溢出

你可能感兴趣的:(本地缓存Caffeine的使用)