使用Java代碼實現(xiàn)Redis和數(shù)據(jù)庫數(shù)據(jù)同步
這里我用到了Redis當中的發(fā)布訂閱模式實現(xiàn)(JAVA代碼實現(xiàn))
先看圖示

下面為代碼實現(xiàn)
首先將RedisMessageListenerContainer交給Spring管理.
@Configuration
public class redisConfig {
@Autowired
RedisConnectionFactory redisConnectionFactory;
@Autowired
@Qualifier("carServiceDb")
private CarService carService;//操作數(shù)據(jù)庫
@Bean
public RedisMessageListenerContainer listenerContainer(){
//創(chuàng)建一個Redis消息監(jiān)聽器容器對象
RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
//設置Redis連接工廠對象
listenerContainer.setConnectionFactory(redisConnectionFactory);
//向監(jiān)聽器容器中添加一個監(jiān)聽器,該監(jiān)聽器的主題為INSERTED
listenerContainer.addMessageListener(new MessageListener() {
@Override
public void onMessage(Message message, byte[] pattern) {
System.out.println("*************insert*************");
String carJsonStr = new String(message.getBody());
Car car = JSONObject.parseObject(carJsonStr, Car.class);
carService.addCar(car);
System.out.println(new String(message.getBody()));
System.out.println(new String(pattern));
System.out.println("*************insert*************");
}
}, new ChannelTopic(ChannelEnum.INSERTED.name()));
//向監(jiān)聽器容器中添加一個監(jiān)聽器,該監(jiān)聽器的主題為UPDATED
listenerContainer.addMessageListener(new MessageListener() {
@Override
public void onMessage(Message message, byte[] pattern) {
System.out.println("*************UPDATED*************");
String carJsonStr = new String(message.getBody());
Car car = JSONObject.parseObject(carJsonStr, Car.class);
carService.updataCount(car.getBookId(),car.getNumber(),car.getUserId());
System.out.println(new String(message.getBody()));
System.out.println(new String(pattern));
System.out.println("*************UPDATED*************");
}
}, new ChannelTopic(ChannelEnum.UPDATED.name()));
//向監(jiān)聽器容器中添加一個監(jiān)聽器,該監(jiān)聽器的主題為DELETED
listenerContainer.addMessageListener(new MessageListener() {
@Override
public void onMessage(Message message, byte[] pattern) {
System.out.println("*************DELETED*************");
System.out.println(new String(message.getBody()));
System.out.println(new String(pattern));
List<String[]> strings = JSONArray.parseArray(new String(message.getBody()), String[].class);
String[] bookIds = strings.get(0);
String userId = strings.get(1)[0];
carService.delCar(bookIds,userId);
System.out.println("----------------------");
System.out.println(Arrays.toString(bookIds));
System.out.println(userId);
System.out.println("--------delete--------");
System.out.println("*************DELETED*************");
}
}, new ChannelTopic(ChannelEnum.DELETED.name()));
return listenerContainer;
}
}下面代碼中的 stringRedisTemplate.convertAndSend();就是發(fā)送消息的,其中參數(shù)1是發(fā)送消息的名稱,參數(shù)2是發(fā)送消息的內容
@Service("carService")
@Slf4j
public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements CarService {
//購物車hash的Key
public static final String CAR_KEY = "carKey";
//hash購物車中field的前綴
public static final String USER_CAR_HASH_FIELD_PREFIX = "car::";
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 這里存儲的時候采用Redis當中的hash存儲
*
* @param car
*/
@Override
@Synchronized
public void addCar(Car car) {
//這里存儲的時候采用Redis當中的hash存儲
HashOperations<String, String, String> opsForHash = stringRedisTemplate.opsForHash();
//這里field為CAR_HASH_FIELD
String userCarKey = USER_CAR_HASH_FIELD_PREFIX + car.getUserId();
//Map<String,Car> 鍵(存儲bookId) 值存儲購物車某一個商品的信息
Map<String, Car> CarMap = null;
boolean flag = true;
//獲得Redis中以存儲的當前用戶的購物車信息
if (opsForHash.hasKey(CAR_KEY, userCarKey)) {
//存在當前用戶的購物車信息,那么獲取原有的數(shù)據(jù)
String carMapJson = opsForHash.get(CAR_KEY, userCarKey);
CarMap = JSONObject.parseObject(carMapJson, new TypeReference<Map<String, Car>>() {
});
//檢測當前購物車信息中是否包含新添加上的商品,如果包含則更新數(shù)量,如果不包含才新增
if (CarMap.containsKey(car.getBookId())) {
//獲取原先商品的數(shù)量
Integer BeforeNumber = CarMap.get(car.getBookId()).getNumber();
log.info("BeforeNumber==============>{}", BeforeNumber);
Integer nowNumber = car.getNumber(); //前端傳過來現(xiàn)在的
log.info("nowNumber==============>{}", nowNumber);
CarMap.get(car.getBookId()).setNumber(BeforeNumber + nowNumber);
flag = false; //存在商品
//修改
//包含才新增 圖書的數(shù)量 在原有的基礎上新增圖書的數(shù)量
} else {
//新增
//如果不包含當前商品信息 那么直接將商品添加到購物車信息當中
CarMap.put(car.getBookId(), car);
}
} else {
/* 新增
*
* 當前的用戶的購物車信息不存在
* 首先把其添加的商品首先存儲到CarMap中
* */
CarMap = new HashMap<>();
CarMap.put(car.getBookId(), car);
}
//最后將其存入redis當中
opsForHash.put(CAR_KEY, userCarKey, JSONObject.toJSONString(CarMap));
if (flag){
//新增
stringRedisTemplate.convertAndSend(ChannelEnum.INSERTED.name(), JSONObject.toJSONString(CarMap.get(car.getBookId())));
}else {
//修改
stringRedisTemplate.convertAndSend(ChannelEnum.UPDATED.name(), JSONObject.toJSONString(CarMap.get(car.getBookId())));
}
}
@Override
public Collection<Car> getCarList(String userId) {
//這里存儲的時候采用Redis當中的hash存儲
HashOperations<String, String, String> opsForHash = stringRedisTemplate.opsForHash();
String userCarKey = USER_CAR_HASH_FIELD_PREFIX + userId;
String jsonStr = opsForHash.get(CAR_KEY, userCarKey);
Map<String,Car> CarMap = JSONObject.parseObject(jsonStr, Map.class);
return CarMap.values();
}
@Override
public void updataCount(String bookId, int number, String userId) {
//這里存儲的時候采用Redis當中的hash存儲
HashOperations<String, String, String> opsForHash = stringRedisTemplate.opsForHash();
String userCarKey = USER_CAR_HASH_FIELD_PREFIX + userId;
String jsonStr = opsForHash.get(CAR_KEY, userCarKey);
Map<String,Car> CarMap = JSONObject.parseObject(jsonStr, new TypeReference<Map<String, Car>>() {
});
if (!CarMap.containsKey(bookId)){ //不包含
return;
}
Car car = CarMap.get(bookId);
car.setNumber(number);
//最后將其存入redis當中
opsForHash.put(CAR_KEY, userCarKey, JSONObject.toJSONString(CarMap));
stringRedisTemplate.convertAndSend(ChannelEnum.UPDATED.name(), JSONObject.toJSONString(CarMap.get(car.getBookId())));
}
@Override
public void delCar(String[] bookIds, String userId) {
//獲得操作RedisHash的對象
HashOperations<String, String, String> forHash = stringRedisTemplate.opsForHash();
String userCarKey = USER_CAR_HASH_FIELD_PREFIX+userId;
List<String[]> list = new ArrayList<>();
//從redis中獲取用戶對應的購物車數(shù)據(jù)
String carJsonStr = forHash.get(CAR_KEY, userCarKey);
//修改指定商品的數(shù)量
Map<String,Car> carMap = JSONObject.parseObject(carJsonStr, new TypeReference<Map<String,Car>>() {
});
for(String bookId : bookIds){
carMap.remove(bookId);
}
//將修改后的數(shù)據(jù)重新添加到redis中
forHash.put(CAR_KEY,userCarKey,JSONObject.toJSONString(carMap));
list.add(bookIds);
list.add(new String[]{userId});
stringRedisTemplate.convertAndSend(ChannelEnum.DELETED.name(), JSONObject.toJSONString(list));
}
}上述的兩段代碼中
第二段代碼中stringRedisTemplate.convertAndSend();就是發(fā)送消息的,其中參數(shù)1是發(fā)送消息的名稱,參數(shù)2是發(fā)送消息的內容
第一段代碼中的這個就是監(jiān)聽到后接收到的消息,其中參數(shù)1{當中的onMessage方法的參數(shù)1Message為發(fā)送消息的內容,參數(shù)2pattern是發(fā)送消息的名稱} 參數(shù)2為監(jiān)聽指定的消息名稱(這個要和stringRedisTemplate.convertAndSend()中參數(shù)1的要保持一致)
listenerContainer.addMessageListener(new MessageListener() {
@Override
public void onMessage(Message message, byte[] pattern) {
}
}, new ChannelTopic(ChannelEnum.INSERTED.name()));以上就是使用Java代碼實現(xiàn)Redis和數(shù)據(jù)庫數(shù)據(jù)同步的詳細內容,更多關于Java Redis和數(shù)據(jù)庫同步的資料請關注腳本之家其它相關文章!
相關文章
淺析Bean?Searcher?與?MyBatis?Plus?區(qū)別介紹
Bean?Searcher號稱任何復雜的查詢都可以一行代碼搞定,但?Mybatis?Plus?似乎也有類似的動態(tài)查詢功能,最近火起的?Bean?Searcher?與?MyBatis?Plus?倒底有啥區(qū)別?帶著這個問題一起通過本文學習下吧2022-05-05
詳解spring boot實現(xiàn)多數(shù)據(jù)源代碼實戰(zhàn)
本篇文章主要介紹了詳解spring boot實現(xiàn)多數(shù)據(jù)源代碼實戰(zhàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07
Java命令行參數(shù)解析工具jcommander詳解
這篇文章主要為大家介紹了Java命令行參數(shù)解析工具jcommander命令詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09
Java實現(xiàn)貪吃蛇大作戰(zhàn)小游戲(附源碼)
今天給大家?guī)淼氖切№椖渴?nbsp;基于Java+Swing+IO流實現(xiàn) 的貪吃蛇大作戰(zhàn)小游戲。實現(xiàn)了界面可視化、基本的吃食物功能、死亡功能、移動功能、積分功能,并額外實現(xiàn)了主動加速和鼓勵機制,需要的可以參考一下2022-07-07
IDEA 創(chuàng)建一個Mybatis Maven項目的方法步驟(圖文)
這篇文章主要介紹了IDEA 創(chuàng)建一個Mybatis Maven項目的方法步驟(圖文),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03

