zoukankan      html  css  js  c++  java
  • e3mall_day09

    一.添加商品同步索引库-MessageListener

      1.search-service的spring中需配置connenction工厂,destination的两个对象,监听器,监听容器

      1.在search-service下书写一个SearchItemMessageListener实现接口MessageListener,它的重写方法onmessage完成查询目标商品并更新到索引库,并交付给spring管理;代码如下:

    public class SearchItemListener implements MessageListener {
    
        @Autowired
        private ItemMapper itemMapper;
        @Autowired
        private SolrServer solrServer;
        
        public void onMessage(Message message) {
            
            TextMessage itemId = (TextMessage) message;
            
            try {
                //获取id
                String id_str = itemId.getText();
                
                long id = Long.parseLong(id_str);
                
                //根据id查询商品
                SearchItem item = itemMapper.getItemById(id);
                //创建文档
                SolrInputDocument document = new SolrInputDocument();
                //添加域
                document.addField("id", item.getId());
                document.addField("price", item.getPrice());
                document.addField("image", item.getImage());
                
                //添加文档
                solrServer.add(document);
                
                //提交
                solrServer.commit();
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    二.添加商品同步索引库-发送消息

      1.可以添加发送信息代码的地方有两处:

        》在manager-service的addItem方法结尾添加;该方案有个缺点,即在事务没有完成提交就已经把消息发送出来了,最坏的情况是没有提交同步到数据库时,另一端就已经先收到消息并查询数据库,导致查询结果为空

        》在manager-web调用manager-service的addItem方法完成后添加;该方案相对靠谱点,在manager-service的addItem方法结束,必定事务已经完成,此时发送消息,另一端接收并查询就能保证查到

      2.在manager-web配置connection工厂,生产者jmstemplate,destination两个对象(一般使用topic会比较多,因为除了同步索引库,还要缓存等待也需要消息);

      3.完成发送消息代码:

        public @ResponseBody E3Result addItem(TbItem item,String desc) {
            
            //添加单个商品
            E3Result result = itemService.addItem(item, desc);
            
            //发送信息
            jmsTemplate.send(destination, new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {
                    
                    TextMessage message = session.createTextMessage();
                    
                    message.setText("hello world activemq");
                    
                    return message;
                }
            });
            
            return result;
        }

     三.商品详情页面工程搭建

      》建立表现层工程item_web,目录结构参照其他表现层

    四.商品详情页面展示分析

      》由于页面涉及到商品的images这个属性,恰巧逆向工程生成的TbItem没有images属性,我们在item-web工程创建一个pojo为Item继承于TbItem,添加images属性即可

      》Item类只用于item-web,所以也不需要实现序列化接口

     1 public class Item extends TbItem{
     2     
     3     public Item(TbItem tbItem) {
     4         
     5         this.setId( tbItem.getId() );
     6         this.setTitle(tbItem.getTitle());
     7         this.setStatus(tbItem.getStatus());
     8     }
     9     
    10     //获取属性images
    11     public String[] getImages() {
    12         
    13         String image = this.getImage();
    14         
    15         if( image != null && !image.equals("") ) {
    16             
    17             return image.split(",");
    18         }
    19         return null;
    20     }
    21 
    22 }

    四.商品详情页面展示-代码实现

      》item-web要调用manager-service的ItemService根据id查询商品和商品描述

      》item-web的controller:

    public class ItemController {
    
        @Autowired
        private ItemService itemService;
        
        @RequestMapping("/item/{itemId}")
        public String showItemInfo(@PathVariable("itemId") long itemId,Model model) {
            
            //查询商品
            TbItem tbItem = itemService.getItemById(itemId);
            
            //转换TbItem成Item
            Item item = new Item(tbItem);
            
            //查询商品描述
            TbItemDesc desc = itemService.getItemDescById(itemId);
            
            //添加到model
            model.addAttribute("item",item);
            model.addAttribute("itemDesc",desc);
            
            //返回逻辑视图
            return "item.jsp";
            
        }
        
    }

      》manager-service的service:

    public interface ItemService {
        
        //按ID查询商品
        public TbItem getItemById(long itemId);
        
        //获取商品列表
        public EasyUiDataGridResult getItemList(Integer page,Integer rows);
        
        //添加商品
        public E3Result addItem(TbItem item,String desc);
        
        //按ID查询商品描述
        public TbItemDesc getItemDescById(long itemId);
    }

    五.商品信息添加缓存-分析

      》考虑到商品详情页面在普通的互联网项目,并发量是挺高的,我们需要给manager-service查询商品和描述添加缓存

      》给商品详情添加缓存时还得考虑一点,有的页面是访问流很小的,这种长期缓存在内存中是十分浪费的,所以计划每一次的缓存数据设置过期时间(时间视商品情况而定),适当得减少数据库的压力,又可以减少内存的消耗

      》数据类型得采用String,不用hash的原因是hash的key设置不了过期时间;使用String类型最好加前缀甚至后缀来 区分不同分类的数据:

     六.向业务逻辑中添加缓存

      》添加缓存时一定得加try-catch,避免redis出现异常导致数据库操作失败

      》查询完数据马上缓存,不要等返回数据才缓存

        public TbItem getItemById(long itemId) {
            String redis_item = "";
            try {
                redis_item = jedisClient.get("ITEM-INFO"+itemId+"BASE");
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            //判断是否缓存
            if( redis_item != null && !redis_item.equals("") ) {
                return (TbItem) JSONUtils.parse(redis_item);
            }
            
            //按条件对象查询
            TbItemExample example = new TbItemExample();
            
            Criteria criteria = example.createCriteria();
            
            criteria.andIdEqualTo(itemId);
            
            List<TbItem> list = itemMapper.selectByExample(example);
            
            //缓存数据
            try {
                if( list.size() > 0 && list != null  ) {
                    
                    jedisClient.set("ITEM-INFO"+itemId+"BASE", itemId+"");
                    
                    jedisClient.expire("ITEM-INFO"+itemId+"BASE", 3600);
                }
                return list.get(0);
            } catch (Exception e) {
                // TODO: handle exception
            }
            
            return null;
        }

     七.删除重复记录

  • 相关阅读:
    mysql 查询优化 ~ select count 知多少
    mongodb 案例 ~ 经典故障案例
    printk 驱动调试
    21天学通C++学习笔记(七):函数
    OPC UA
    MQTT
    分库分表
    水平、垂直权限问题(横向越权与纵向越权)
    数据库中的行转列和列转行
    面试知识点
  • 原文地址:https://www.cnblogs.com/ibcdwx/p/13549648.html
Copyright © 2011-2022 走看看