La mise en cache est simple à mettre en œuvre

1. Origines

Dans un projet, dans une interface, il y aura de nombreuses opérations répétées de vérification de la base de données, ce qui affecte grandement les performances.
À l'heure actuelle, vous pouvez implémenter la mise en cache automatique pour réduire les opérations de vérification de la base de données et améliorer les performances.

2. Idées de conception de cache :

1. Le cache doit fournir une fonction de stockage ; un cache a besoin d'un conteneur pour stocker les données mises en cache ; choisissez généralement Map, en tenant compte de la concurrence, utilisez généralement ConcurrentHashMap ; 2. Le cache doit fournir une interface pour obtenir des données ; lors de l'interrogation de données
, vous pouvez appeler cette interface directement depuis Obtenir des données du cache pour éviter les recherches dans la base de données ;
3. Le cache doit fournir une interface pour ajouter des données ; dans l'interface métier, si de nouvelles données sont ajoutées, cette interface peut être appelée pour mettre en cache les nouvelles données ;
4. Le cache doit fournir une interface pour supprimer les données ; dans l'interface métier Dans l'interface, si les données sont modifiées ou supprimées, cette interface peut être appelée pour supprimer les données mises en cache ; 5. Le cache doit fournir
un interface de données d'actualisation ; dans l'interface métier, si les données sont modifiées, cette interface peut être appelée pour actualiser les données mises en cache ; 6. Le cache doit
fournir une interface de données d'actualisation par lots ; lorsque le système démarre, cette interface peut être appelée pour charger les données dans le cache par lots ;

3. Réalisation

1. Interface de cache


import java.util.List;

/**
 * 缓存应用服务接口。
 *
 * @param <K> 缓存 key。
 * @param <T> 缓存 value。
 */
public interface CacheService<K, T> {
    
    

    /**
     * 缓存最大个数常量。
     */
    public static final int CACHE_MAX_SIZE = 1000;

    /**
     * 添加缓存数据。
     *
     * @param key 缓存 key。
     * @param value 缓存 value。
     */
    void putData(K key, T value);

    /**
     * 获取缓存数据。(单条)
     *
     * @param key 缓存 key。
     */
    T getData(K key);

    /**
     * 获取缓存数据。(批量)
     *
     * @param ids
     * @return
     */
    List<T> getDataBy(List<K> ids);

    /**
     * 删除缓存数据。(单条)
     *
     * @param key 缓存 key。
     */
    void removeDate(K key);

    /**
     * 删除缓存数据。(批量)
     *
     * @param keys 缓存 key 列表。
     */
    void removeBy(List<K> keys);

    /**
     * 清空缓存数据。
     */
    void removeAll();

    /**
     * 刷新缓存数据。(单条)
     *
     * @param key 缓存 key。
     */
    void refreshDataBy(K key);

    /**
     * 加载缓存数据。(批量)(启动时)
     */
    void refreshAll();
}

2. Implémentation de l'abstraction du cache


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public abstract class AbstractCacheService<K, T> implements CacheService<K, T> {
    
    

    public abstract T getDataFromDB(K key);

    public abstract ConcurrentHashMap<K, T> getCacheContainer();

    /**
     * 从缓存获取数据。默认直接从缓存中获取返回。
     *
     * @param key key。
     * @return 缓存数据。
     */
    public T getDataFromCache(K key) {
    
    
        return getCacheContainer().get(key);
    }

    @Override
    public void putData(K key, T value) {
    
    
        if (getCacheContainer() == null) {
    
    
            return;
        }
        if (getCacheContainer().size() >= CACHE_MAX_SIZE) {
    
    
            long index = (long) (Math.random() * CACHE_MAX_SIZE);
            getCacheContainer().remove(index);
        }
        getCacheContainer().put(key, value);
    }

    @Override
    public T getData(K key) {
    
    
        if (getCacheContainer() == null) {
    
    
            return null;
        }
        if (getCacheContainer().get(key) != null) {
    
    
            return getDataFromCache(key);
        }
        T value = this.getDataFromDB(key);
        if (getCacheContainer().size() >= CACHE_MAX_SIZE) {
    
    
            long index = (long) (Math.random() * CACHE_MAX_SIZE);
            getCacheContainer().remove(index);
        }
        if (key != null && value != null) {
    
    
            getCacheContainer().put(key, value);
        }
        return value;
    }

    @Override
    public void removeDate(K key) {
    
    
        if (getCacheContainer() == null) {
    
    
            return;
        }
        if (getCacheContainer().get(key) != null) {
    
    
            getCacheContainer().remove(key);
        }
    }

    @Override
    public void refreshDataBy(K key) {
    
    
        if (getCacheContainer() == null) {
    
    
            return;
        }
        if (getCacheContainer().contains(key)) {
    
    
            getCacheContainer().remove(key);
        }
        getData(key);
    }

    @Override
    public List<T> getDataBy(List<K> ids) {
    
    
        if (getCacheContainer() == null) {
    
    
            return new ArrayList<>();
        }

        List<T> result = new ArrayList<>();
        for (K key : ids) {
    
    
            T data = getData(key);
            result.add(data);
        }
        return result;
    }

    @Override
    public void removeAll() {
    
    
        if (getCacheContainer() == null) {
    
    
            return;
        }
        getCacheContainer().clear();
    }

    @Override
    public void removeBy(List<K> keys) {
    
    
        if (getCacheContainer() == null || keys == null) {
    
    
            return;
        }
        for (K key : keys) {
    
    
            if (getCacheContainer().get(key) != null) {
    
    
                getCacheContainer().remove(key);
            }
        }
    }
}

3. Implémentation réelle du cache


import com.example.cache.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用户缓存服务实现。
 */
@Service
public class UserCacheServiceImpl extends AbstractCacheService<Long, User> {
    
    

    /** 保存 CACHE_MAX_SIZE 个 key 为 K 类型, value 为 T 类型的数据. */
    private static ConcurrentHashMap<Long, User> userCacheData = new ConcurrentHashMap<>(CACHE_MAX_SIZE);

    /** 用户应用层接口。 */
    @Autowired
    @Lazy
    private UserService userService;

    /** 初始化。 */
    @PostConstruct
    public void init() {
    
    
        refreshAll();
    }

    @Override
    public User getDataFromDB(Long key) {
    
    
        return userService.find(key);
    }

    @Override
    public User getDataFromCache(Long key) {
    
    
        return super.getDataFromCache(key);
    }

    @Override
    public ConcurrentHashMap<Long, User> getCacheContainer() {
    
    
        return userCacheData;
    }

    @Override
    public void refreshAll() {
    
    
        // 加载组件信息
        Page<User> users = userService.findAll(Pageable.ofSize(CACHE_MAX_SIZE));
        for (User user : users) {
    
    
            userCacheData.put(user.getId(), user);
        }
    }
}

4. Adresse du projet

Adresse du gîte : https://gitee.com/AiWanDeXiaoCaiNiao/nobiz/tree/master/cache

Je suppose que tu aimes

Origine blog.csdn.net/weixin_39651041/article/details/129810351
conseillé
Classement