使用@Cacheable注释的真实DAO的最佳实践

时间:2013-06-11 13:47:07

标签: java spring caching annotations ehcache

我是Spring的新手,我对它提供的所有东西感到非常兴奋!

现在,我正在尝试在现有项目中对几个DAO进行现代化改造。 具体来说,我想用Spring Jdbc支持替换旧的纯JDBC代码,并介绍Spring的透明缓存。

  1. 第一个问题:我是否认为DAO图层是添加@Cacheable注释的正确位置?或者你是在业务层中做到的?

  2. 我可以按照网上的所有简单示例进行操作。但是,当涉及到更多现实世界的代码时,我会陷入困境:

  3. 具体来说,我有几个方法可以返回模型Publisher的实例。在我的手动缓存实现中,我始终确保只为一个实例缓存并为不同的getPublisher()方法提取。但是,使用@Cacheable并尝试在DAO中封装缓存,我遇到的问题是,注释不适用于本地方法调用(因为代理)。

    这是我的示例代码:

    @Cacheable("publisherCache")
    public Publisher getPublisher(int publisherId)
    {
        String sql = "SELECT * FROM publisher LEFT JOIN publisherContacts USING (publisherId) WHERE publisherId=? ORDER BY publisherContactId ASC";
        return getJdbcTemplate().query(sql, publisherResultSetExtractor, publisherId);
    }
    
    public List<Publisher> findVisiblePublishers()
    {
        List<Publisher> publishers = new LinkedList<Publisher>();
        for (int publisherId : findVisiblePublisherIds())
        {
            publishers.add(getPublisher(publisherId));
        }
        return publishers;
    }
    
    @Cacheable(value = "publisherCache", key = "'list'")
    private List<Integer> findVisiblePublisherIds()
    {
        String sql = "SELECT publisherId FROM publisher WHERE isVisible='yes' ORDER BY imprintName";
        return getJdbcTemplate().queryForList(sql, Integer.class);
    }
    
    public Publisher findNearestPublisher(String appx)
    {
        appx = "%" + appx + "%";
        String sql = "SELECT publisherId FROM publisher WHERE publisherName LIKE ? OR imprintName LIKE ? ORDER BY imprintName DESC LIMIT 1";
        Integer publisherId = getJdbcTemplate().queryForObject(sql, Integer.class, appx, appx);
        if (publisherId == null)
            return null;
        else
            return getPublisher(publisherId);
    }
    

    这是我的想法,如上所述,不起作用。

    我现在能看到的唯一选择是:

    a)仅缓存getPublisher(publisherId)方法并定义返回Publisher的所有其他方法以返回int s(publisherIds)或其列表。从API的角度来看,这并不自然。作为服务或业务逻辑,我希望从DAO获取实例,而不仅仅是ID。

    b)向所有方法添加@Cacheable,复制缓存并使用比所需更多的内存(让我们假设有很多发布者并且它们是重型对象)。

    围绕此必须非常常见的问题的最佳做法是什么? 感谢您的任何见解。

1 个答案:

答案 0 :(得分:0)

常见模式如下: 对于持久层,您可以使用休眠二级缓存。 对于服务层,您可以使用@Cacheable来缓存长计算或Web服务调用结果等内容。