1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/qiujiayu-AutoLoadCache

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
magic.md 6.7 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 27.11.2024 00:26 77bc1ee

Магический режим

Благодаря поддержке пакетной обработки, начиная с версии 7.0.0, а также добавлению магического режима в версии 7.0.1, удалось снизить вероятность расхождения данных в кеше и источнике данных. Также стало удобнее обновлять и удалять данные из кеша. Обычно данные кэшируются на основе первичного ключа, после чего данные извлекаются по идентификатору, как показано в следующих фрагментах кода:

public interface UserMapper {
    
    /**
     * Получение информации о пользователе по его идентификатору
     * 
     * @param id
     * @return
     */
    @Cache(expire = 60, expireExpression = "null == #retVal ? 30: 60", key = "'user-byid-' + #args[0]")
    UserDO getUserById(Long id);

    /**
     * Извлечение списка идентификаторов пользователей на основе динамических условий запроса
     * 
     * @param condition
     * @return
     **/
    List<Long> listIdsByCondition(UserCondition condition);
}

Для получения информации об определённом пользователе выполняется следующий код:

    public List<UserDO> listByCondition(UserCondition condition) {
        List<Long> ids = userMapper.listIdsByCondition(condition);
        List<UserDO> list = null;
        if (null != ids && ids.size() > 0) {
            list = new ArrayList<>(ids.size());
            UserDO userDO = null;
            for (Long id : ids) {
                userDO = userMapper.getUserById(id);
                if (null != userDO) {
                    list.add(userDO);
                }
            }
        }
        return list;
    }

Если в списке ids содержится 10 записей, то при наихудшем сценарии потребуется 10 обращений к кешу и источнику данных, а также 10 операций записи в кеш для завершения операции. В лучшем случае также потребуется 10 обращений к кешу.

Используя магический режим, можно разделить параметры, сначала выполнить пакетный запрос к кешу для извлечения совпадающих данных, затем извлечь данные, не найденные в кеше, из источника данных и загрузить их в кеш. Наконец, объединить данные, найденные в кеше, с данными, загруженными из источника, и вернуть их.

Пример использования магического режима для оптимизации:


public interface UserMapper {
    
    /**
     * Получение информации о пользователе по его идентификатору
     * 
     * @param id
     * @return
     */
    @Cache(expire = 60, expireExpression = "null == #retVal ? 30: 60", key = "'user-byid-' + #args[0]")
    UserDO getUserById(Long id);

    /**
     * Извлечение списка идентификаторов пользователей на основе динамических условий запроса
     * 
     * @param condition
     * @return
     **/
    List<Long> listIdsByCondition(UserCondition condition);
    
    @Cache(expire = 60, expireExpression = "null == #retVal ? 30: 60",
            key = "'user-byid-' + #args[0]",
            magic = @Magic(key = "'user-byid-' + #retVal.id", iterableArgIndex = 0))
    List<UserDO> listByIds(@Param("ids") List<Long> ids);
    
    @Cache(expire = 60, expireExpression = "null == #retVal ? 30: 60",
            // 因为Magic 模式下会对参数进行分隔,所以取参数固定使用 #args[0],
            // 如果参数据是复杂类型,比如List<UserDO>, 那么取参使用 #args[0].id
            // 为了降低缓存不致问题,些处生的有key值要与getUserById 方法的一样
            key = "'user-byid-' + #args[0]",
            magic = @Magic(
                    // 因为Magic 模式下会对数组及集合类型的数据进行分隔,所以取返回值固定使用 #retVal,
                    // 此key表达生成的值也必须要与getUserById  метода的一样
                    key = "'user-byid-' + #retVal.id", iterableArgIndex = 0))
    List<UserDO> listByIds2(@Param("ids") Long... ids);

}

При использовании магического режима и отсутствии доступа к данным в кеше для получения подробной информации о пользователях выполняется следующий код:

    public List<UserDO> listByCondition(UserCondition condition) {
        List<Long> ids = userMapper.listIdsByCondition(condition);
        List<UserDO> list = null;
        if (null != ids && !ids.isEmpty()) {
            list = userMapper.listByIds(ids);
        }
        return list;
    }

В худшем случае потребуется одно обращение к кешу, одному источнику данных и одна операция записи в кеш. В лучшем случае достаточно одного обращения к кешу. Однако использование магического режима не допускает автоматического обновления (установка autoload в значение true не будет иметь эффекта), «присвоения» и асинхронного обновления.

С версии 7.0.4 магический режим также может использоваться для функций без параметров, но в этом случае данные могут быть загружены только из источника и записаны в кеш в пакетном режиме.

    @Cache(expire = 60, expireExpression = "null == #retVal ? 30: 60",
            key = "", magic = @Magic(key = "'user-magic-'+ #retVal.id"))
    public List<UserDO> loadUsers() {
        List<UserDO> list = new ArrayList<>(5);
        for (Long id = 100L; id < 105; id++) {
            list.add(new UserDO(id, "name" + id, "ppp"));
        }
        return list;
    }

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/qiujiayu-AutoLoadCache.git
git@api.gitlife.ru:oschina-mirror/qiujiayu-AutoLoadCache.git
oschina-mirror
qiujiayu-AutoLoadCache
qiujiayu-AutoLoadCache
master