AutoLoadCache 7.0.4 发布,完善 Magic 模式

栏目: 软件资讯 · 发布时间: 5年前

内容简介:7.0.4 版本修改日志: 1. 修复了Magic模式下数据不正确问题; 2. 支持无参函数下使用Magic模式; 3. 对Magic模式下的缓存删除功能进行重构,不仅支持基于参数进行批量删除缓存,也支持通过返回进行批量删除缓存;...

7.0.4 版本修改日志:

1. 修复了Magic模式下数据不正确问题;

2. 支持无参函数下使用Magic模式;

3. 对Magic模式下的缓存删除功能进行重构,不仅支持基于参数进行批量删除缓存,也支持通过返回进行批量删除缓存;

下面是对Magic模式的详细说明:

为了降低缓存数据与数据源数据不一致,也是为了更加方便更新、删除缓存,通常做法是,数据以主键为key进行缓存,然后根据id获取数据,如下面两段代码所示:

public interface UserMapper {
    
    /**
     * 根据用户id获取用户信息
     * 
     * @param id
     * @return
     */
    @Cache(expire = 60, expireExpression = "null == #retVal ? 30: 60", key = "'user-byid-' + #args[0]")
    UserDO getUserById(Long id);

    /**
     * 根据动态组合查询条件,获取用户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次缓存才能完成以上操作,最好的情况也需要访问10次缓存才能完成操作。 使用Magic模式,则会将参数分隔,先批量去缓存中查询,获取命中的缓存,然后将缓存未命中的,再批量从数据源加载,然后把从数据源加载的数据刷入缓存,最后把缓存命中的与数据源加载的数据一并返回。 下面是使用Magic模式进行优化:

public interface UserMapper {
    
    /**
     * 根据用户id获取用户信息
     * 
     * @param id
     * @return
     */
    @Cache(expire = 60, expireExpression = "null == #retVal ? 30: 60", key = "'user-byid-' + #args[0]")
    UserDO getUserById(Long id);

    /**
     * 根据动态组合查询条件,获取用户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> 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);

}

下面是在没有使用Magic模式下根据一定条件查询用户信息,先获取用户id列表,然后再遍历获取用户详细信息:

    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;
    }

使用Magic模式后,如果上面ids有10条记录,最差情况需要访问1次缓存、1数据源以及1次写缓存操作;最好的情况只需要访问1次缓存。但使用Magic模式后,就不允许使用自动加载(autoload设置为true也不会生效)、不支持“拿来主义”、异步刷新等功能。

    @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;
    }

有时我们也需要动态精确批量删除缓存,比如更新一批商品信息后,也要批量删除缓存,在7.0.1版本之前需要在业务代码中使用循环操作来实现。 7.0.4版本中增加@CacheDeleteMagicKey 用于开启Magic模式,并支持对参数或返回值进行分割,然后生成多个Cache key进行批量删除缓存。如下例子所示:

 

/**
 * 根据用户ids删除用户记录
 **/
@CacheDelete(magic = { @CacheDeleteMagicKey(value = "'user-byid-' + #args[0]", condition = "#retVal > 0", iterableArgIndex = 0, iterableReturnValue = false) })
int deleteUserByIds(@Param("ids") Long... ids);

// 遍历ids,删除所有缓存, iterableReturnValue 必须设置false
@CacheDelete(magic = {
        @CacheDeleteMagicKey(value = "'user-testMagic-' + #args[0] + '-' + #args[1] + '-' + #args[2]", iterableArgIndex = 2, iterableReturnValue = false)
})
public void testDeleteMagicForArg(String name, String password, Long... ids) {

}

// 遍历返回值,删除所有缓存,iterableArgIndex必须设置为-1, iterableReturnValue 必须设置为true
@CacheDelete(magic = {
        @CacheDeleteMagicKey(value = "'user-testMagic-' + #args[0] + '-' + #args[1] + '-' + #retVal.id", iterableArgIndex = -1, iterableReturnValue = true)
})
public List<UserDO> testDeleteMagicForRetVal(String name, String password, Long... ids) {
    List<UserDO> list = new ArrayList<>(ids.length);
    for (Long id : ids) {
        list.add(new UserDO(id, name, password));
    }
    return list;
}

使用Magic模式不仅能简少手动遍历的代码,同时也会使用 redis 的Pipeline批量处理,减少与Redis的交互次数,提升性能。


以上所述就是小编给大家介绍的《AutoLoadCache 7.0.4 发布,完善 Magic 模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据挖掘中的新方法:支持向量机

数据挖掘中的新方法:支持向量机

邓乃扬、田英杰 / 科学出版社 / 2004-6-10 / 53.00元

支持向量机是数据挖掘中的一个新方法。支持向量机能非常成功地处理回归问题(时间序列分析)和模式识别(分类问题、判别分析)等诸多问题,并可推广于预测和综合评价等领域,因此可应用于理科、工科和管理等多种学科。目前国际上支持向量机在理论研究和实际应用两方面都正处于飞速发展阶段。希望本书能促进它在我国的普及与提高。 本书对象既包括关心理论的研究工作者,也包括关心应用的实际工作者。对于有关领域的具有高等......一起来看看 《数据挖掘中的新方法:支持向量机》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具