一、思路:项目启动时,在server
层初始化数据并通过读写锁保存在自定义的cacheMap
对象中,在server
层对数据进行操作时,一并操作自定义的cacheMap
,保证数据同步性。
Springboot
给我们提供了两种跟随项目自启动的方式ApplicationRunner
和CommandLineRunner
,这两种方法提供的目的是为了满足,在项目启动的时候立刻执行某些方法。我们可以通过实现ApplicationRunner
和CommandLineRunner
,他们都是在SpringApplication
执行之后开始执行的。
这里我们要注意类注解的使用,
Spring
为我们提供了@Component
、@Repository
、@Service
、@Controller
几个注解,这几个注解基本上是等效的,在持久层、业务层和控制层分别采用@Repository
、@Service
和@Controller
对分层中的类进行注释,而用@Component
对那些比较中立的类进行注释。 多个自启动类的先后顺序通过注解@Order(value = 3)
来控制。
二、实现
package com.hn.lz.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hn.lz.mapper.DepMapper;
import com.hn.lz.model.Dep;
import com.hn.lz.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Order(value = 3)
@Service
public class DepService implements CommandLineRunner {
@Autowired
private DepMapper depMapper;
// 数据缓存 key:数据ID value:数据对象
private static final Map<String, Dep> cacheMap = new HashMap<String, Dep>();
// 缓存读写锁
private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
private static final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
@Override
public void run(String... strings) throws Exception {
System.out.println("-------------加载部门缓存-------------");
loadCache();
}
// ---------------------------------- 缓存 BEGIN --------------------------------------
/**
* 刷新数据缓存
*/
public void refreshCache(final String id) {
new Thread(new Runnable() {
public void run() {
writeLock.lock();
try {
Dep data = depMapper.selectByPrimaryKey(id);
if (data != null){
cacheMap.put(id, data);
} else {
cacheMap.remove(id);
}
} finally {
writeLock.unlock();
}
}
}).start();
}
/**
* 刷新数据缓存
*/
public void refreshCacheMap() {
new Thread(new Runnable() {
public void run() {
loadCache();
}
}).start();
}
/**
* 加载缓存
*/
private void loadCache() {
writeLock.lock();
try {
Map<String, Dep> map = depMapper.getMap();
cacheMap.clear();
if (map != null) cacheMap.putAll(map);
} finally {
writeLock.unlock();
}
}
/**
* 删除缓存
* @param id 数据id
*/
public void deleteCache(String id) {
writeLock.lock();
try {
cacheMap.remove(id);
} finally {
writeLock.unlock();
}
}
// ---------------------------------- 缓存 END --------------------------------------
// ---------------------------------- 数据操作 BEGIN --------------------------------------
/**
* 插入数据
* @param data
* @return
*/
@Transactional
public int insert(Dep data){
int result = depMapper.insert(data);
refreshCache(data.getId());
return result;
}
/**
* 更新数据
* @param data
* @return
*/
@Transactional
public int update(Dep data){
int result = depMapper.updateByPrimaryKeySelective(data);
refreshCache(data.getId());
return result;
}
/**
* 删除数据
* @param id
* @return
*/
@Transactional
public int delete(String id){
int result = depMapper.deleteByPrimaryKey(id);
deleteCache(id);
return result;
}
/**
* 得到所有数据列表
* @return
*/
public List<Dep> getList() {
readLock.lock();
try {
return new ArrayList<Dep>(cacheMap.values());
} finally {
readLock.unlock();
}
}
// ---------------------------------- 数据操作 END --------------------------------------
}
网友评论