Магический режим
Благодаря поддержке пакетной обработки, начиная с версии 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 )