有的时候我们需要频繁用到一些数据,我们不需要频繁去查数据库,这样不仅浪费数据库的IO,也浪费单次业务的时间,如果我们要用到的数据就是数据库中的某一张表的固定数据,那么我们就可以在项目启动的时候将该表的数据加载到缓存中。
设计思路:
1. 一个加载缓存数据的 服务Bean
2. 一个存储缓存数据的类
实现加载缓存数据的服务Bean采用了实现Spring提供的InitializingBean
public class MyCacheService implements InitializingBean { public synchronized void loadCache() { // 从数据库获取数据放到内存中 String[] array = {"张三","李四","王五"}; for(int i=0; i<3; i++){ MyCacheMap.accounts.put(String.valueOf(i), new Account(Integer.toUnsignedLong(i), array[i])); } } @Override public void afterPropertiesSet() throws Exception { loadCache(); } }
通过ConcurrentHashMap保存数据,保证了多线程环境下的数据一致性
public class MyCacheMap { public static final Map<String, Account> accounts = new ConcurrentHashMap<>(); }
账户类
@Getter @Setter public class Account { private Long accountId; private String accountNo; private String accountName; public Account(Long accountId, String accountName) { this.accountId = accountId; this.accountNo = String.valueOf(new Random().nextInt(100) + accountId); this.accountName = accountName; } }
为了让MyCacheService能随Spring容器一起加载,需要在Spring的配置文件中配置这个服务Bean,这里请读者自己去配置,就不赘述了。
写一个测试类试试是否能正确加载吧
public class MyCacheServiceTest { private static final Logger logger = LoggerFactory.getLogger(MyCacheServiceTest.class); @Test public void testLoadCache() { for(Entry<String, Account> entry:MyCacheMap.accounts.entrySet()) { logger.debug("accountName:{}, accountNo:{}", entry.getValue().getAccountName(), entry.getValue().getAccountNo()); } } }
测试结果:
11:01:14.904 [main] DEBUG t.service.MyCacheServiceTest - accountName:张三, accountNo:4 11:01:14.904 [main] DEBUG t.service.MyCacheServiceTest - accountName:李四, accountNo:45 11:01:14.904 [main] DEBUG t.service.MyCacheServiceTest - accountName:王五, accountNo:88