我是Spring的新手,对它提供的所有功能都非常兴奋!
目前,我正在尝试现代化我的现有项目中的一些DAO。具体来说,我想用Spring Jdbc支持取代旧的普通JDBC代码,并引入Spring的透明缓存。
第一个问题:我是否正确认为在DAO层添加
@Cacheable
注释是正确的方法?或者您是在业务层这样做的?我可以按照网络上找到的所有简单示例进行操作。然而,当涉及到更多实际的代码时,我陷入了困境:
具体而言,我有几个返回我的模型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`或其列表。从API角度来看,这并不自然。作为服务或业务逻辑,我希望从DAO中获取实例,而不仅仅是ID。
b)将`@Cacheable`添加到所有方法中,复制缓存并使用比所需更多的内存(假设有很多出版商并且它们是重型对象)。
在这个必须非常普遍的问题上,最佳实践是什么?感谢任何见解。