使用Java代码实现Redis和数据库数据同步

 更新时间:2024年06月03日 08:39:38   作者:浮夸的小白菜  
这篇文章主要介绍了使用Java代码实现Redis和数据库数据同步问题,文中通过代码示例给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

这里我用到了Redis当中的发布订阅模式实现(JAVA代码实现)

先看图示 

下面为代码实现

首先将RedisMessageListenerContainer交给Spring管理.

@Configuration
public class redisConfig {
    @Autowired
    RedisConnectionFactory redisConnectionFactory;
 
    @Autowired
    @Qualifier("carServiceDb")
    private CarService carService;//操作数据库
    @Bean
    public RedisMessageListenerContainer listenerContainer(){
        //创建一个Redis消息监听器容器对象
        RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
         //设置Redis连接工厂对象
        listenerContainer.setConnectionFactory(redisConnectionFactory);
 
        //向监听器容器中添加一个监听器,该监听器的主题为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()));
 
        //向监听器容器中添加一个监听器,该监听器的主题为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()));
 
        //向监听器容器中添加一个监听器,该监听器的主题为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();就是发送消息的,其中参数1是发送消息的名称,参数2是发送消息的内容

@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)) {
            //存在当前用户的购物车信息,那么获取原有的数据
            String carMapJson = opsForHash.get(CAR_KEY, userCarKey);
 
            CarMap = JSONObject.parseObject(carMapJson, new TypeReference<Map<String, Car>>() {
            });
 
            //检测当前购物车信息中是否包含新添加上的商品,如果包含则更新数量,如果不包含才新增
            if (CarMap.containsKey(car.getBookId())) {
                //获取原先商品的数量
                Integer BeforeNumber = CarMap.get(car.getBookId()).getNumber();
                log.info("BeforeNumber==============>{}", BeforeNumber);
                Integer nowNumber = car.getNumber(); //前端传过来现在的
                log.info("nowNumber==============>{}", nowNumber);
                CarMap.get(car.getBookId()).setNumber(BeforeNumber + nowNumber);
 
                flag = false; //存在商品
                //修改
 
                //包含才新增 图书的数量 在原有的基础上新增图书的数量
            } 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中获取用户对应的购物车数据
        String carJsonStr = forHash.get(CAR_KEY, userCarKey);
        //修改指定商品的数量
        Map<String,Car> carMap = JSONObject.parseObject(carJsonStr, new TypeReference<Map<String,Car>>() {
        });
        for(String bookId : bookIds){
            carMap.remove(bookId);
        }
 
        //将修改后的数据重新添加到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();就是发送消息的,其中参数1是发送消息的名称,参数2是发送消息的内容

第一段代码中的这个就是监听到后接收到的消息,其中参数1{当中的onMessage方法的参数1Message为发送消息的内容,参数2pattern是发送消息的名称}    参数2为监听指定的消息名称(这个要和stringRedisTemplate.convertAndSend()中参数1的要保持一致)

listenerContainer.addMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message, byte[] pattern) {
                
            }
        }, new ChannelTopic(ChannelEnum.INSERTED.name()));

以上就是使用Java代码实现Redis和数据库数据同步的详细内容,更多关于Java Redis和数据库同步的资料请关注脚本之家其它相关文章!

相关文章

  • Java简单模拟实现一个线程池

    Java简单模拟实现一个线程池

    本文主要介绍了Java简单模拟实现一个线程池,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01
  • 浅析Bean Searcher 与 MyBatis Plus 区别介绍

    浅析Bean Searcher 与 MyBatis Plus 区别介绍

    Bean Searcher号称任何复杂的查询都可以一行代码搞定,但 Mybatis Plus 似乎也有类似的动态查询功能,最近火起的 Bean Searcher 与 MyBatis Plus 倒底有啥区别?带着这个问题一起通过本文学习下吧
    2022-05-05
  • 详解spring boot实现多数据源代码实战

    详解spring boot实现多数据源代码实战

    本篇文章主要介绍了详解spring boot实现多数据源代码实战,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Java的RTTI和反射机制代码分析

    Java的RTTI和反射机制代码分析

    这篇文章主要涉及了Java的RTTI和反射机制代码分析的相关内容,在介绍运行时类型识别的同时,又向大家展示了其实例以及什么时候会用到反射机制,内容丰富,需要的朋友可以参考下。
    2017-09-09
  • Json转化为Java对象的实例详解

    Json转化为Java对象的实例详解

    这篇文章主要介绍了Json转化为Java对象的实例详解的相关资料,前后端数据交互的情况经常会遇到Json串与java 对象的相互转换方便操作,需要的朋友可以参考下
    2017-08-08
  • 理解HashSet里为什么value不是null

    理解HashSet里为什么value不是null

    你有没有想过Java中HashSet的Value为什么要存PRESENT而不是Null?带着这个疑问来看下边的文章寻找答案吧
    2021-09-09
  • Java命令行参数解析工具jcommander详解

    Java命令行参数解析工具jcommander详解

    这篇文章主要为大家介绍了Java命令行参数解析工具jcommander命令详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Java JSch远程执行Shell命令的方法

    Java JSch远程执行Shell命令的方法

    本文主要介绍了Java JSch远程执行Shell命令,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Java实现贪吃蛇大作战小游戏(附源码)

    Java实现贪吃蛇大作战小游戏(附源码)

    今天给大家带来的是小项目是 基于Java+Swing+IO流实现 的贪吃蛇大作战小游戏。实现了界面可视化、基本的吃食物功能、死亡功能、移动功能、积分功能,并额外实现了主动加速和鼓励机制,需要的可以参考一下
    2022-07-07
  • IDEA 创建一个Mybatis Maven项目的方法步骤(图文)

    IDEA 创建一个Mybatis Maven项目的方法步骤(图文)

    这篇文章主要介绍了IDEA 创建一个Mybatis Maven项目的方法步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论