springboot篇】二十一. 基于springboot电商项目 四 商品同步索引库和搜索列表实现

中国加油,武汉加油!

篇幅较长,配合目录观看

案例准备

  1. 本案例基于springboot篇】二十一. 基于springboot电商项目 三 整合docker配置fastdfs和solr
  2. gitee地址 https://gitee.com/springboot-dubbo/nz1904-springboot-shop-04

1. 商品同步到索引库中

1.1 shop-service-api编写Service接口

package com.wpj.service;

import com.wpj.entity.Goods;

import java.util.List;

public interface ISearchService {
    public List<Goods> searchGoodsListByKey(String key);
}

1.2 shop-service-iml新建search-service(module-springboot)

  1. spring boot devtools
  2. spring data for apache solr

1.3 导相关依赖

<dependency>
     <groupId>com.alibaba.boot</groupId>
     <artifactId>dubbo-spring-boot-starter</artifactId>
     <version>0.2.0</version>
 </dependency>

 <dependency>
     <groupId>com.wpj</groupId>
     <artifactId>shop-service-api</artifactId>
     <version>1.0-SNAPSHOT</version>
 </dependency>

1.4 编写ServiceImpl

package com.wpj.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.wpj.entity.Goods;
import com.wpj.service.ISearchService;
import org.apache.solr.client.solrj.SolrClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Service
public class SearchServiceImpl implements ISearchService {

    @Autowired
    private SolrClient solrClient;

    @Override
    public List<Goods> searchGoodsListByKey(String key) {        
    	System.out.println("SearchServiceImpl.searchGoodsListByKey" + key);
        return null;
    }
}

1.5 编写yml

dubbo:
  registry:
    address: zookeeper://192.168.1.114:2181
  application:
    name: search-service
  protocol:
    port: -1

spring:
  data:
    solr:
      host: http://192.168.1.114:8983/solr/mycollection

1.6 修改程序入口

package com.wpj;

import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(scanBasePackages = "com.wpj", exclude = DataSourceAutoConfiguration.class)
@DubboComponentScan(basePackages = "com.wpj.service")
public class SearchServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(SearchServiceApplication.class, args);
    }

}

1.7 shop-web下的shop-search导包

<dependency>
    <groupId>com.wpj</groupId>
    <artifactId>search-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>0.2.0</version>
</dependency>

1.8 修改yml

server:
  port: 8082

dubbo:
  registry:
    address: zookeeper://192.168.1.114:2181
  application:
    name: shop-service
  protocol:
    port: -1
  consumer:
    check: false
    retries: 3

1.9 修改Controller

package com.wpj.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.wpj.entity.Goods;
import com.wpj.service.ISearchService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/search")
public class SearchController {

    @Reference
    private ISearchService searchService;

    @RequestMapping("/searchGoods")
    @ResponseBody
    public String searchGoods(String key) {
        System.out.println("SearchController.searchGoods" + key);
        List<Goods> goodsList = searchService.searchGoodsListByKey(key);
        return "ok";
    }
}

1.10 修改程序入口

package com.wpj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(scanBasePackages = "com.wpj", exclude = DataSourceAutoConfiguration.class)
public class ShopSearchApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShopSearchApplication.class, args);
    }
}

1.11 启动程序入口

在这里插入图片描述

1.12 访问

在这里插入图片描述
在这里插入图片描述

1.13 search-service测试同步

package com.wpj;

import com.alibaba.dubbo.config.annotation.Reference;
import com.wpj.entity.Goods;
import com.wpj.service.IGoodService;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.common.SolrInputDocument;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@SpringBootTest
@RunWith(SpringRunner.class)
class SearchServiceApplicationTests {

    @Autowired
    private SolrClient solrClient;
    @Reference
    private IGoodService goodService;

    @Test
    public void testSyncGoods() throws Exception{
        // 查询所有的商品
        List<Goods> list = goodService.getList();
        for (Goods goods : list) {
            SolrInputDocument document = new SolrInputDocument();
            // 把商品添加到索引库
            document.addField("gname",goods.getGname());
            document.addField("id",goods.getId());
            document.addField("gdesc",goods.getGdesc());
            document.addField("gpic",goods.getGpic());
            document.addField("gprice",goods.getGprice().toString());
            solrClient.add(document);
        }
        solrClient.commit();
    }
}

在这里插入图片描述

1.14 shop-service-iml的GoodsServiceImpl重写insert方法

@Reference
private ISearchService searchService;

@Override
public int insert(Goods goods) {
    int insert = super.insert(goods);
    searchService.addGoods(goods);
    return insert;
}

1.14 shop-service-api定义方法

package com.wpj.service;

import com.wpj.entity.Goods;

import java.util.List;

public interface ISearchService {
    public List<Goods> searchGoodsListByKey(String key);

    public void addGoods(Goods goods);
}

1.16 search-service重写方法

@Override
public void addGoods(Goods goods) {
    SolrInputDocument document = new SolrInputDocument();
    document.addField("id",goods.getId());
    document.setField("gname", goods.getGname());
    document.setField("gdesc", goods.getGdesc());
    document.setField("gpic", goods.getGpic());
    document.setField("gprice", goods.getGprice().toString());
    try {
        solrClient.add(document);
        solrClient.commit();
    } catch (SolrServerException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2. 实现搜索列表

2.1 search-service的ServiceImpl的方法完成业务

@Override
public List<Goods> searchGoodsListByKey(String key) {
    List<Goods> goodsList = new ArrayList<>();
    // 1.设置查询条件
    SolrQuery solrQuery = new SolrQuery();
    if (!StringUtils.isEmpty(key)) {
        solrQuery.setQuery(String.format("gname:%s || gdesc:%s", key, key));
        // 开启高亮
        solrQuery.setHighlight(true);
        // 设置高亮的字段
        solrQuery.addHighlightField("gname");
        // 设置高亮字段的字体颜色
        solrQuery.setHighlightSimplePre("<font color ='red'>");
        solrQuery.setHighlightSimplePost("</font>");
    } else {
        solrQuery.setQuery("gname:* || gdesc:*");
    }
    try {
        // 2.到索引库查询
        QueryResponse queryResponse = solrClient.query(solrQuery);
        // 3.得到结果(gname或者gdesc里面有匹配的结果)
        SolrDocumentList solrDocumentList = queryResponse.getResults();
        // 得到高亮的结果(gname)
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
        for (SolrDocument document : solrDocumentList) {
            Goods goods = new Goods();
            String id = document.get("id").toString();
            goods.setId(Integer.parseInt(id));
            goods.setGname(document.get("gname").toString());
            goods.setGdesc(document.get("gdesc").toString());
            goods.setGpic(document.get("gpic").toString());
            Double gPrice = Double.valueOf(document.get("gprice").toString());
            goods.setGprice(BigDecimal.valueOf(gPrice));
            if (highlighting != null) {
                // 先判断当前商品中是否存在高亮
                Map<String, List<String>> map = highlighting.get(id);
                if (map != null) {
                    // 覆盖掉前面没有高亮的字段
                    List<String> gnameList = map.get("gname");
                    if (gnameList != null) {
                        goods.setGname(gnameList.get(0));
                    }
                }
            }
            goodsList.add(goods);
        }
    } catch (SolrServerException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return goodsList;
}

2.2 导入静态资源

2.3 编写searchGoodList.html

2.4 shop-search的Controller编写方法

package com.wpj.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.wpj.entity.Goods;
import com.wpj.service.ISearchService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/search")
public class SearchController {
    @Reference
    private ISearchService searchService;
    @RequestMapping("/searchGoods")
    @ResponseBody
    public String searchGoods(String key, ModelMap map) {
        System.out.println("SearchController.searchGoods" + key);
        List<Goods> goodsList = searchService.searchGoodsListByKey(key);
        map.put("goodsList",goodsList);
        return "searchGoodsList";
    }
}

2.5 启动程序入口访问

在这里插入图片描述
在这里插入图片描述

2.6 修改页面死数据为动态获取的数据

在这里插入图片描述

2.7 高光显示

在这里插入图片描述
在这里插入图片描述

发布了126 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/TheNew_One/article/details/105165205