二十七、商城 - 搜索解决方案-Solr(15)【1】

目录

  • 一、Solr 安装与配置
    • 1.1 什么是 Solr
    • 1.2 Solr 安装
    • 1.3 中文分析器IK Analyzer
      • 1.3.1 IK Analyzer简介
      • 1.3.2 IK Analyzer配置
    • 1.4 配置域
      • 1.4.1 域
      • 1.4.2 复制域
      • 1.4.3 动态域
  • 二、Spring Data Solr入门
    • 2.1 Spring Data Solr简介
    • 2.2 Spring Data Solr 入门小 Demo
      • 2.2.1 搭建工程
      • 2.2.2 @Field 注解
      • 2.2.3 增加(修改)
      • 2.2.4 按主键查询
      • 2.2.5 按主键删除
      • 2.2.6 分页查询
      • 2.2.7 条件查询
      • 2.2.8 删除全部数据
  • 三、优乐选-批量数据导入
    • 3.1 需求分析
    • 3.2 查询商品数据列表
      • 3.2.1 工程搭建
      • 3.2.2 数据导入Solr索引库
      • 3.2.3 代码编写 导入solr
    • 3.4 规格导入动态域
      • 3.4.1 @Dynamic注解
      • 3.4.2 修改导入工具
  • 四、优乐选-关键字搜索
    • 4.1 需求分析
    • 4.2 后端代码
      • 4.2.1 服务接口层
      • 4.2.2 服务实现层
      • 4.2.3 控制层
    • 4.3 前端代码
      • 4.3.1 拷贝资源
      • 4.3.2 服务层
      • 4.3.3 控制层
      • 4.3.4 页面

一、Solr 安装与配置

1.1 什么是 Solr

二十七、商城 - 搜索解决方案-Solr(15)【1】_第1张图片

  • 大多数搜索引擎应用都必须具有某种搜索功能,问题是搜索功能往往是巨大的资源消耗,并且它们会由于沉重的数据库加载而拖垮你的应用性能。
  • 这就是为什么转移负载到一个外部的搜索服务器的主要原因,Apache Solr是一个流行的开源搜索服务器,它通过使用类似REST的HTTP API,确保你能从几乎任何编程语言来使用solr。
  • Solr是一个开源搜索平台,用于构建搜索应用程序。 它建立在 Lucene (全文搜索引擎)之上。Solr是企业级的,快速的,高度可扩展的。
  • 为了在CNET网络的公司网站上添加搜索功能,Yonik Seely于2004年创建了Solr。并在2006年1月,它成为Apache软件基金会下的一个开源项目。并于2016年发布最新版本Solr 6.0,支持并行SQL查询的执行。
  • Solr可以和Hadoop一起使用。由于Hadoop处理大量数据,Solr帮助我们从这么大的源中找到所需的信息。不仅限于搜索,Solr也可以用于存储目的。像其他NoSQL数据库一样,它是一种非关系数据存储和处理技术。
  • 总之,Solr是一个可扩展的,可部署,搜索 / 存储引擎,优化搜索大量以文本为中心的数据。

1.2 Solr 安装

获取 solr

注意:需要提前配置好linux下的java环境

  1. 上传压缩包至 linux,并解压到/usr/local/solr目录下(软件\solr\solr-7.2.1.tgz)

二十七、商城 - 搜索解决方案-Solr(15)【1】_第2张图片
二十七、商城 - 搜索解决方案-Solr(15)【1】_第3张图片
二十七、商城 - 搜索解决方案-Solr(15)【1】_第4张图片

  1. 进入解压目录,进入bin目录,启动:
./solr  start  -force     //root用户启动需要增加 -force

二十七、商城 - 搜索解决方案-Solr(15)【1】_第5张图片

上述正常可直接跳转4,创建核心库

  1. 访问:Solr服务的默认服务端口是8983,此刻访问你的 http://IP:8983 , 应该可以看到Solr的控制面板了。

例如中级项目为:http://192.168.188.180:8983

二十七、商城 - 搜索解决方案-Solr(15)【1】_第6张图片

访问 8983端口 连接失败,原因可能有两个:

(1)Solr 服务没有启动,启动即可,可以通过命令查看Solr的当前状态

cd /usr/local/solr/bin

./solr status

(2)把防火墙相关端口打开:

firewall-cmd --add-port=8983/tcp --permanent

firewall-cmd --reload
  1. 创建core:core是solr的特有概念,每个core是一个查询数据、索引等的集合体,你可以把它想象成一个独立数据库,我们创建一个新core:名字[collection1]
cd /usr/solr/bin

./solr create -c collection1 -force  // -c 指定要创建的Core名称 root用户启动需要增加 -force

二十七、商城 - 搜索解决方案-Solr(15)【1】_第7张图片

创建成功刷新页面显示:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第8张图片

1.3 中文分析器IK Analyzer

1.3.1 IK Analyzer简介

IK Analyzer 是一个开源的,基于 java 语言开发的轻量级的中文分词工具包。从 2006年 12 月推出 1.0 版开始, IKAnalyzer 已经推出了 4 个大版本。最初,它是以开源项目Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。从 3.0 版本开始,IK 发展为面向 Java 的公用分词组件,独立 Lucene 项目,同时提供了对 Lucene 的默认优化实现。在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化。

1.3.2 IK Analyzer配置

步骤:

  1. 下载 IKAnalyzer for solr5 的源码包,然后使用Maven编译,得到一个文件IKAnalyzer-5.0.jar
  1. 上传ik jar包到/usr / local / solr / server / solr-webapp / webapp / WEB-INF / lib目录中

在这里插入图片描述

  1. 修改/usr / local / solr / server / solr / collection1 / conf / managed-schema,添加fieldType内容:

(注:先安装连接 Notepad++ 五、Notepad++)


  	 	
  		

二十七、商城 - 搜索解决方案-Solr(15)【1】_第9张图片

然后,重启 solr

./solr restart -force

二十七、商城 - 搜索解决方案-Solr(15)【1】_第10张图片

1、刷新网页测试分词:登录Solr管理控制台,选择collection1,点击Analyse 进入分词界面

选择分词类型 FileType : text_ik
在Field Value (Index) 输入要测试的中文语句,Field Value (Query) 输入要检索的关键词:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第11张图片

1.4 配置域

(建议到 Notepad++ 中操作)

域相当于数据库的表字段,用户存放数据,因此用户根据业务需要去定义相关的Field(域),一般来说,每一种对应着一种数据,用户对同一种数据进行相同的操作。

域的常用属性:

  • name:指定域的名称
  • type:指定域的类型
  • indexed:是否索引
  • stored:是否存储
  • required:是否必须
  • multiValued:是否多值

1.4.1 域

修改 /usr / local / solr / server / solr / collection1 / conf / managed-schema,设置业务系统 Field
删除多余的field,保留id,version,_text_这三个field
















二十七、商城 - 搜索解决方案-Solr(15)【1】_第12张图片

1.4.2 复制域

复制域的作用在于将某一个Field中的数据复制到另一个域中










在这里插入图片描述

1.4.3 动态域

当我们需要动态扩充字段时,就需要使用动态域。对于优乐选,规格的值是不确定的,所以我们需要使用动态域来实现。如:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第13张图片

配置:


在这里插入图片描述

保存,重启 solr !

在这里插入图片描述

二、Spring Data Solr入门

2.1 Spring Data Solr简介

虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr的应用集成到Spring中?可以,Spring Data Solr就是为了方便Solr的开发所研制的一个框架,其底层是对SolrJ(官方API)的封装。

2.2 Spring Data Solr 入门小 Demo

2.2.1 搭建工程

(1)创建maven jar 工程 spring-data-solr ,并且在pom.xml中引入依赖

二十七、商城 - 搜索解决方案-Solr(15)【1】_第14张图片

<dependencies>
    <dependency>
        <groupId>org.springframework.datagroupId>
        <artifactId>spring-data-solrartifactId>
        <version>1.5.5.RELEASEversion>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-testartifactId>
        <version>4.2.4.RELEASEversion>
    dependency>
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.12version>
    dependency>
dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.pluginsgroupId>
            <artifactId>maven-compiler-pluginartifactId>
            <version>3.7.0version>
            <configuration>
                <source>1.8source>
                <target>1.8target>
                <encoding>UTF-8encoding>
            configuration>
        plugin>
    plugins>
build>

(2)在src/main/resources下创建 spring / spring_solr.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:solr="http://www.springframework.org/schema/data/solr"
       xsi:schemaLocation="http://www.springframework.org/schema/data/solr
  		http://www.springframework.org/schema/data/solr/spring-solr.xsd
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd">

    
    <solr:solr-server id="solrServer" url="http://192.168.188.180:8983/solr/collection1" />

    
    <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg ref="solrServer" />
    bean>

beans>

2.2.2 @Field 注解

创建 com.zql.pojo 包,将优乐选的TbItem实体类拷入本工程 ,属性使用@Field注解标识 。 如果属性与solr配置文件定义的域名称不一致,需要在注解中指定域名称。

package com.zql.pojo;

import org.apache.solr.client.solrj.beans.Field;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

public class TbItem implements Serializable {

    private Long id;

    @Field("item_title")
    private String title;

    private String sellPoint;
    @Field("item_price")
    private BigDecimal price;

    private Integer stockCount;

    private Integer num;

    private String barcode;

    @Field("item_image")
    private String image;

    private Long categoryid;

    private String status;

    private Date createTime;

    @Field("item_updatetime")
    private Date updateTime;

    private String itemSn;

    private BigDecimal costPirce;

    private BigDecimal marketPrice;

    private String isDefault;

    @Field("item_goodsid")
    private Long goodsId;

    private String sellerId;

    private String cartThumbnail;
    @Field("item_category")
    private String category;
    @Field("item_brand")
    private String brand;

    private String spec;

    @Field("item_seller")
    private String seller;

    private static final long serialVersionUID = 1L;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title == null ? null : title.trim();
    }

    public String getSellPoint() {
        return sellPoint;
    }

    public void setSellPoint(String sellPoint) {
        this.sellPoint = sellPoint == null ? null : sellPoint.trim();
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Integer getStockCount() {
        return stockCount;
    }

    public void setStockCount(Integer stockCount) {
        this.stockCount = stockCount;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public String getBarcode() {
        return barcode;
    }

    public void setBarcode(String barcode) {
        this.barcode = barcode == null ? null : barcode.trim();
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image == null ? null : image.trim();
    }

    public Long getCategoryid() {
        return categoryid;
    }

    public void setCategoryid(Long categoryid) {
        this.categoryid = categoryid;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status == null ? null : status.trim();
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getItemSn() {
        return itemSn;
    }

    public void setItemSn(String itemSn) {
        this.itemSn = itemSn == null ? null : itemSn.trim();
    }

    public BigDecimal getCostPirce() {
        return costPirce;
    }

    public void setCostPirce(BigDecimal costPirce) {
        this.costPirce = costPirce;
    }

    public BigDecimal getMarketPrice() {
        return marketPrice;
    }

    public void setMarketPrice(BigDecimal marketPrice) {
        this.marketPrice = marketPrice;
    }

    public String getIsDefault() {
        return isDefault;
    }

    public void setIsDefault(String isDefault) {
        this.isDefault = isDefault == null ? null : isDefault.trim();
    }

    public Long getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Long goodsId) {
        this.goodsId = goodsId;
    }

    public String getSellerId() {
        return sellerId;
    }

    public void setSellerId(String sellerId) {
        this.sellerId = sellerId == null ? null : sellerId.trim();
    }

    public String getCartThumbnail() {
        return cartThumbnail;
    }

    public void setCartThumbnail(String cartThumbnail) {
        this.cartThumbnail = cartThumbnail == null ? null : cartThumbnail.trim();
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category == null ? null : category.trim();
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand == null ? null : brand.trim();
    }

    public String getSpec() {
        return spec;
    }

    public void setSpec(String spec) {
        this.spec = spec == null ? null : spec.trim();
    }

    public String getSeller() {
        return seller;
    }

    public void setSeller(String seller) {
        this.seller = seller == null ? null : seller.trim();
    }
}

测试:

2.2.3 增加(修改)

创建测试类TestSolr.java

package com.zql;

import com.zql.pojo.TbItem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.math.BigDecimal;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring_solr.xml")
public class TestSolr {

    @Autowired
    private SolrTemplate solrTemplate;

    @Test
   public void  testAdd(){

        TbItem item = new TbItem();

        // 主键相同,即修改
        item.setId(5L);
        item.setBrand("大话");
        item.setCategory("手抓");
        item.setGoodsId(1L);
        item.setSeller("专卖店");
        item.setTitle("米Mate9");
        item.setPrice(new BigDecimal(4500));

        solrTemplate.saveBean(item);
        solrTemplate.commit();

    }
}

浏览器输入:http://192.168.188.180:8983/

运行结果如下:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第15张图片

去看看:访问solr控制台–找到对应core—查找

  • q:查询关键字:必须的,如果查询所有使用*

二十七、商城 - 搜索解决方案-Solr(15)【1】_第16张图片

  • fq:(filter query)过虑查询:作用:在q查询符合结果中同时是fq查询符合的
    如:过滤查询价格从1到20的记录,使用 item_price:[0 TO 4000]
    也可以使用“*”表示无限,例如:
    20以上:price:[20 TO ]
    20以下:price:[
    TO 20]

二十七、商城 - 搜索解决方案-Solr(15)【1】_第17张图片
二十七、商城 - 搜索解决方案-Solr(15)【1】_第18张图片

  • sort:排序:格式:sort=+[,+]… 。
    示例:product_price desc 按照价格从高到低进行排序
  • product_price asc 按照价格从低到高进行排序

二十七、商城 - 搜索解决方案-Solr(15)【1】_第19张图片

  • start, rows:行的索引,从0开始,[start, rows]
  • fl:指定返回那些字段内容:用逗号或空格分隔多个,不写默认返回全部配置的。

二十七、商城 - 搜索解决方案-Solr(15)【1】_第20张图片

  • df:指定一个默认搜索Field:一般默认
  • wt:(writer type)指定输出格式:可以有xml, json, csv, python, php等格式
  • hl:是否高亮:设置高亮Field,设置格式前缀和后缀。

二十七、商城 - 搜索解决方案-Solr(15)【1】_第21张图片

2.2.4 按主键查询

2.2.5 按主键删除

2.2.6 分页查询

2.2.7 条件查询

2.2.8 删除全部数据

package com.zql;

import com.zql.pojo.TbItem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring_solr.xml")
public class TestSolr {

    @Autowired
    private SolrTemplate solrTemplate;

    @Test
    public void  testAdd(){

        TbItem item = new TbItem();

        // 主键相同,即修改
        item.setId(5L);
        item.setBrand("大话");
        item.setCategory("手抓");
        item.setGoodsId(1L);
        item.setSeller("专卖店");
        item.setTitle("米Mate9");
        item.setPrice(new BigDecimal(4500));

        solrTemplate.saveBean(item);
        solrTemplate.commit();

    }


    //按主键查询
    @Test
    public void  testFindOne(){

        TbItem byId = solrTemplate.getById(5, TbItem.class);

        System.out.println(byId.getBrand());
    }


    //按主键删除
    @Test
    public void  deleteByKey(){

        solrTemplate.deleteById("5");

        solrTemplate.commit();
    }

    //首先循环插入100条测试数据分页查询
    @Test
    public void testAddList(){
        List<TbItem> list=new ArrayList();
        for(int i=1;i<101;i++){
            TbItem item=new TbItem();
            item.setId(Long.valueOf(i));
            item.setBrand("华为");
            item.setCategory("手机");
            item.setGoodsId(1L);
            item.setSeller("华为"+i+"号专卖店");
            item.setTitle("华为Mate"+i);
            item.setPrice(new BigDecimal(2000+i));
            list.add(item);
        }
        solrTemplate.saveBeans(list);
        solrTemplate.commit();
    }

    //分页查询测试
    @Test
    public void pageTestSolr(){

        Query query = new SimpleQuery("*:*");
        query.setOffset(10);// 开始索引(默认0)
        query.setRows(20);	// 每页记录数(默认10)
        ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
        System.out.println("总记录数:" + page.getTotalElements());
        List<TbItem> list = page.getContent();

        for (TbItem item : list) {
            System.out.println(item.getTitle() + item.getPrice());
        }
    }

    //条件查询
    @Test
    public void testPageQueryMutil(){

        Query query = new SimpleQuery("*:*");

        Criteria criteria = new Criteria("item_title").contains("2");
        criteria = criteria.and("item_price").greaterThan(2020);

        query.addCriteria(criteria);

        Sort s = new Sort(Sort.Direction.DESC, "item_price");
        query.addSort(s);

        // query.setOffset(10); //开始索引(默认0)
        // query.setRows(100); //每页记录数(默认10)
        ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);

        System.out.println("总记录数:" + page.getTotalElements());
        List<TbItem> list = page.getContent();

        for (TbItem item : list) {
            System.out.println(item.getTitle() + "," + item.getPrice());
        }
    }


    //删除全部数据
    @Test
    public void testDeleteAll(){

        SimpleQuery query = new SimpleQuery("*:*");

       solrTemplate.delete(query);

       solrTemplate.commit();
    }

}

Criteria 用于对条件的封装:

运行分别如下:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第22张图片
二十七、商城 - 搜索解决方案-Solr(15)【1】_第23张图片
二十七、商城 - 搜索解决方案-Solr(15)【1】_第24张图片
二十七、商城 - 搜索解决方案-Solr(15)【1】_第25张图片

案例源码

三、优乐选-批量数据导入

3.1 需求分析

编写专门的导入程序,将商品数据导入到Solr系统中。上线前,或测试时手动数据导入,真正上线后,会实时自动同步。

3.2 查询商品数据列表

3.2.1 工程搭建

(1)创建子模块 youlexuan_solr_util(jar)模块, 引入youlexuan_dao 以及spring 相关依赖

二十七、商城 - 搜索解决方案-Solr(15)【1】_第26张图片
pom.xml

<dependencies>
    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-contextartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-beansartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-jdbcartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-aspectsartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-context-supportartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-testartifactId>
    dependency>

        <dependency>
            <groupId>com.zqlgroupId>
            <artifactId>youlexuan_daoartifactId>
            <version>1.0version>
        dependency>
    dependencies>

(2)src/main/resources下创建 spring / applicationContext_solr.xml配置文件


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:solr="http://www.springframework.org/schema/data/solr"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/data/solr
  		http://www.springframework.org/schema/data/solr/spring-solr.xsd
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.zql.solrutil"/>

    
    <solr:solr-server id="solrServer" url="http://192.168.188.180:8983/solr/collection1" />

    
    <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg ref="solrServer" />
    bean>

beans>

3.2.2 数据导入Solr索引库

(1)将solr入门 demo工程 中添加了@Field注解的实体类拷贝到youlexuan_pojo中

package com.zql.pojo;

import org.apache.solr.client.solrj.beans.Field;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

public class TbItem implements Serializable {

    private Long id;

    @Field("item_title")
    private String title;

    private String sellPoint;
    @Field("item_price")
    private BigDecimal price;

    private Integer stockCount;

    private Integer num;

    private String barcode;

    @Field("item_image")
    private String image;

    private Long categoryid;

    private String status;

    private Date createTime;

    @Field("item_updatetime")
    private Date updateTime;

    private String itemSn;

    private BigDecimal costPirce;

    private BigDecimal marketPrice;

    private String isDefault;

    @Field("item_goodsid")
    private Long goodsId;

    private String sellerId;

    private String cartThumbnail;
    @Field("item_category")
    private String category;
    @Field("item_brand")
    private String brand;

    private String spec;

    @Field("item_seller")
    private String seller;

    private static final long serialVersionUID = 1L;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title == null ? null : title.trim();
    }

    public String getSellPoint() {
        return sellPoint;
    }

    public void setSellPoint(String sellPoint) {
        this.sellPoint = sellPoint == null ? null : sellPoint.trim();
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Integer getStockCount() {
        return stockCount;
    }

    public void setStockCount(Integer stockCount) {
        this.stockCount = stockCount;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public String getBarcode() {
        return barcode;
    }

    public void setBarcode(String barcode) {
        this.barcode = barcode == null ? null : barcode.trim();
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image == null ? null : image.trim();
    }

    public Long getCategoryid() {
        return categoryid;
    }

    public void setCategoryid(Long categoryid) {
        this.categoryid = categoryid;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status == null ? null : status.trim();
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getItemSn() {
        return itemSn;
    }

    public void setItemSn(String itemSn) {
        this.itemSn = itemSn == null ? null : itemSn.trim();
    }

    public BigDecimal getCostPirce() {
        return costPirce;
    }

    public void setCostPirce(BigDecimal costPirce) {
        this.costPirce = costPirce;
    }

    public BigDecimal getMarketPrice() {
        return marketPrice;
    }

    public void setMarketPrice(BigDecimal marketPrice) {
        this.marketPrice = marketPrice;
    }

    public String getIsDefault() {
        return isDefault;
    }

    public void setIsDefault(String isDefault) {
        this.isDefault = isDefault == null ? null : isDefault.trim();
    }

    public Long getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Long goodsId) {
        this.goodsId = goodsId;
    }

    public String getSellerId() {
        return sellerId;
    }

    public void setSellerId(String sellerId) {
        this.sellerId = sellerId == null ? null : sellerId.trim();
    }

    public String getCartThumbnail() {
        return cartThumbnail;
    }

    public void setCartThumbnail(String cartThumbnail) {
        this.cartThumbnail = cartThumbnail == null ? null : cartThumbnail.trim();
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category == null ? null : category.trim();
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand == null ? null : brand.trim();
    }

    public String getSpec() {
        return spec;
    }

    public void setSpec(String spec) {
        this.spec = spec == null ? null : spec.trim();
    }

    public String getSeller() {
        return seller;
    }

    public void setSeller(String seller) {
        this.seller = seller == null ? null : seller.trim();
    }
}

(2)在youlexuan_pojo中引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.datagroupId>
        <artifactId>spring-data-solrartifactId>
        <version>1.5.5.RELEASEversion>
    dependency>
dependencies>

3.2.3 代码编写 导入solr

创建com.zql.solrutil 包,创建类SolrUtil,实现商品数据的查询(已审核商品)

package com.zql.solrutil;

import com.zql.mapper.TbItemMapper;
import com.zql.pojo.TbItem;
import com.zql.pojo.TbItemExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@Component
public class SolrUtil {

    @Autowired
    private TbItemMapper itemMapper;
    @Autowired
    private SolrTemplate solrTemplate;

    public void importItemData(){

        TbItemExample example = new TbItemExample();

        TbItemExample.Criteria criteria = example.createCriteria();

        criteria.andStatusEqualTo("1");

        List<TbItem> itemList = itemMapper.selectByExample(example);

        System.out.println("商品列表");

        for (TbItem tbItem : itemList) {

            System.out.println(tbItem.getTitle()+"\t"+tbItem.getPrice());

        }

        solrTemplate.saveBeans(itemList);

        solrTemplate.commit();

        System.out.println("导入成功");


    }

    //删除
    public void delete(){

        SimpleQuery query = new SimpleQuery("*:*");

        solrTemplate.delete(query);

        solrTemplate.commit();

    }


    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext_*.xml");

        SolrUtil solrUtil = (SolrUtil) context.getBean("solrUtil");

		 //solrUtil.delete();
        solrUtil.importItemData();
    }
}

测试运行后台显示:
二十七、商城 - 搜索解决方案-Solr(15)【1】_第27张图片

浏览器效果:http://192.168.188.180:8983

二十七、商城 - 搜索解决方案-Solr(15)【1】_第28张图片

3.4 规格导入动态域

3.4.1 @Dynamic注解

修改工程 youlexuan_pojo 里面的TbItem.java ,添加属性(还要getter setter方法)

@Dynamic
@Field("item_spec_*") //Notepad++加入得那一条动态域
private Map<String,String> specMap;

public Map<String, String> getSpecMap() {
    return specMap;
}

public void setSpecMap(Map<String, String> specMap) {
    this.specMap = specMap;
}

3.4.2 修改导入工具

修改youlexuan_solr_util 的 SolrUtil.java ,先引入fastJSON依赖
引入中文转化依赖

<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>fastjsonartifactId>
dependency>
<dependency>
    <groupId>com.github.promeggroupId>
    <artifactId>tinypinyinartifactId>
    <version>2.0.3version>
dependency>

注意:

  1. solr 5.x后,安装方式从 tomcat 中独立出来,且键不支持中文了。因此,itme_spec_网络 的动态属性,会保存为itme_spec___ 形式的下划线。
  2. 解决方案:将中文转为拼音。

二十七、商城 - 搜索解决方案-Solr(15)【1】_第29张图片

SolrUtil.java 完整代码:

package com.zql.solrutil;

import com.alibaba.fastjson.JSON;
import com.github.promeg.pinyinhelper.Pinyin;
import com.zql.mapper.TbItemMapper;
import com.zql.pojo.TbItem;
import com.zql.pojo.TbItemExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@Component
public class SolrUtil {

    @Autowired
    private TbItemMapper itemMapper;
    @Autowired
    private SolrTemplate solrTemplate;

    public void importItemData(){

        TbItemExample example = new TbItemExample();

        TbItemExample.Criteria criteria = example.createCriteria();

        criteria.andStatusEqualTo("1");

        List<TbItem> itemList = itemMapper.selectByExample(example);

        System.out.println("商品列表");
        //遍历全部通过审核商品列表数据
        for (TbItem tbItem : itemList) {

            System.out.println(tbItem.getTitle()+"\t"+tbItem.getPrice());
            //读取规格数据,字符串,转换成json对象
            Map<String,String> specMap = JSON.parseObject(tbItem.getSpec(), Map.class);
            /**① solr显示:两个_ _
             * "item_spec___":"联通3G",
             * "item_spec_____":"16G",
             */
            //创建一个新map集合存储拼音
           Map<String, String> pinyinMap = new HashMap<>();
            //遍历map,替换key从汉字变为拼音
            for (String key : specMap.keySet()) {

                pinyinMap.put(Pinyin.toPinyin(key,"").toLowerCase(),specMap.get(key));

                /**
                 * ② solr显示:  大写字母,转小写使用:toLowerCase()
                 *  "item_spec_WANGLUO":"联通3G",
                 *   "item_spec_JISHENNEICUN":"16G",
                 *
                 *   变为小写如下
                 *   "item_spec_jishenneicun":"16G",
                 *   "item_spec_wangluo":"联通3G",
                 */

            }
            tbItem.setSpecMap(pinyinMap);

        }
        //保存集合数据到solr
        solrTemplate.saveBeans(itemList);

        solrTemplate.commit();

        System.out.println("导入成功");


    }

    //删除
    public void delete(){

        SimpleQuery query = new SimpleQuery("*:*");

        solrTemplate.delete(query);

        solrTemplate.commit();

    }


    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext_*.xml");

        SolrUtil solrUtil = (SolrUtil) context.getBean("solrUtil");

        // solrUtil.delete();
          solrUtil.importItemData();

    }
}

显示一:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第30张图片

显示二:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第31张图片

最终优化:

二十七、商城 - 搜索解决方案-Solr(15)【1】_第32张图片

四、优乐选-关键字搜索

4.1 需求分析

打开搜索页面,在搜索框输入要搜索的关键字,点击搜索按钮即可进行搜索,展示搜索结果

在这里插入图片描述

4.2 后端代码

4.2.1 服务接口层

(1)创建youlexuan_search_interface模块(搜索服务接口),依赖youlexuan_pojo

二十七、商城 - 搜索解决方案-Solr(15)【1】_第33张图片

<dependencies>
    <dependency>
        <groupId>com.zqlgroupId>
        <artifactId>youlexuan_pojoartifactId>
        <version>1.0version>
    dependency>
dependencies>

(2)创建com.zql.search.service包,创建业务接口 ItemSearchService

package com.zql.search.service;

import java.util.Map;

/**
 * @Author:Daniel
 * @Version 1.0
 * 搜索
 */
public interface ItemSearchService {

    public Map<String,Object> search(Map searchMap);
}

4.2.2 服务实现层

(1)创建war工程youlexuan_search_service,pom参考其它服务工程,如youlexuan_content_service:

  • 去掉对dao的依赖,查询走solr索引库
  • 引入youlexuan_search_interface依赖
  • tomcat端口9003

二十七、商城 - 搜索解决方案-Solr(15)【1】_第34张图片
pom.xml

<packaging>warpackaging>
<properties>
    <webVersion>3.0webVersion>
properties>
<dependencies>
    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-contextartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-beansartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-jdbcartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-aspectsartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-jmsartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-context-supportartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-testartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>dubboartifactId>
    dependency>
    <dependency>
        <groupId>org.apache.zookeepergroupId>
        <artifactId>zookeeperartifactId>
    dependency>
    <dependency>
        <groupId>org.apache.curatorgroupId>
        <artifactId>curator-recipesartifactId>
    dependency>
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
    dependency>
    <dependency>
        <groupId>javassistgroupId>
        <artifactId>javassistartifactId>
    dependency>
    <dependency>
        <groupId>commons-codecgroupId>
        <artifactId>commons-codecartifactId>
    dependency>
    <dependency>
        <groupId>javax.servletgroupId>
        <artifactId>servlet-apiartifactId>
        <scope>providedscope>
    dependency>
    <dependency>
        <groupId>com.zqlgroupId>
        <artifactId>youlexuan_commonartifactId>
        <version>1.0version>
    dependency>

    <dependency>
        <groupId>com.zqlgroupId>
        <artifactId>youlexuan_search_interfaceartifactId>
        <version>1.0version>
    dependency>

    <dependency>
        <groupId>com.github.pagehelpergroupId>
        <artifactId>pagehelperartifactId>
    dependency>
dependencies>
<build>
    <plugins>
        
        <plugin>
            <groupId>org.apache.tomcat.mavengroupId>
            <artifactId>tomcat7-maven-pluginartifactId>
            <configuration>
                <path>/path>
                <port>9003port>
            configuration>
        plugin>
    plugins>
build>

(2)添加web.xml ,参考其它服务工程,如youlexuan_content_service


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    
    <context-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath*:spring/applicationContext_*.xmlparam-value>
    context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
    listener>
web-app>

(3)在src/main/resources下配置文件,参见其它服务工程,如 youlexuan_content_service:

  • 对事务控制的 service.xml 可以删除
  • dubbo端口20883,应用名,包名,然后在youlexuan_search_service下面创建包
    com.zql.search.service.impl

applicationContext_service.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <dubbo:protocol name="dubbo" port="20883">dubbo:protocol>
    <dubbo:application name="youlexuan_search_service"/>
    <dubbo:registry address="zookeeper://192.168.188.180:2181"/>
    <dubbo:annotation package="com.zql.search.service.impl" />
beans>

(4)在src/main/resources下,复制youlexuan-solr-util 的 applicationContext_solr.xml 并且删掉扫描包

applicationContext_solr.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:solr="http://www.springframework.org/schema/data/solr"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/data/solr
  		http://www.springframework.org/schema/data/solr/spring-solr.xsd
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd">

    
    <solr:solr-server id="solrServer" url="http://192.168.188.180:8983/solr/collection1" />

    
    <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg ref="solrServer" />
    bean>

beans>

二十七、商城 - 搜索解决方案-Solr(15)【1】_第35张图片

(5)在包下创建并编写服务实现类 ItemSearchServiceImpl.java

package com.zql.search.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.zql.pojo.TbItem;
import com.zql.search.service.ItemSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@Service(timeout = 3000)
public class ItemSearchServiceImpl implements ItemSearchService {

    @Autowired
    private SolrTemplate solrTemplate;

    @Override
    public Map<String, Object> search(Map searchMap) {

        Map<String, Object> map = new HashMap<>();

        SimpleQuery query = new SimpleQuery();

        // is:基于分词后的结果 和 传入的参数匹配
        Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keyWords"));

        // 添加查询条件
        query.addCriteria(criteria);

        ScoredPage<TbItem> tbItems = solrTemplate.queryForPage(query, TbItem.class);

        List<TbItem> itemList = tbItems.getContent();

        long total = tbItems.getTotalElements();
        
        map.put("rows",itemList);

        map.put("total",total);

        return map;
    }
}

4.2.3 控制层

(1)创建子工程 youlexuan_search_web 的 war工程

二十七、商城 - 搜索解决方案-Solr(15)【1】_第36张图片

pom依赖参见其它web模块,如:youlexuan_portal_web

  • 依赖 youlexuan_search_interface
  • tomcat 端口 9104
<packaging>warpackaging>
<properties>
    <webVersion>3.0webVersion>
properties>
<dependencies>
    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-contextartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-beansartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-jdbcartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-aspectsartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-jmsartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-context-supportartifactId>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-testartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>dubboartifactId>
    dependency>
    <dependency>
        <groupId>org.apache.zookeepergroupId>
        <artifactId>zookeeperartifactId>
    dependency>
    <dependency>
        <groupId>org.apache.curatorgroupId>
        <artifactId>curator-recipesartifactId>
    dependency>
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
    dependency>
    <dependency>
        <groupId>javassistgroupId>
        <artifactId>javassistartifactId>
    dependency>
    <dependency>
        <groupId>commons-codecgroupId>
        <artifactId>commons-codecartifactId>
    dependency>
    <dependency>
        <groupId>javax.servletgroupId>
        <artifactId>servlet-apiartifactId>
        <scope>providedscope>
    dependency>

    <dependency>
        <groupId>com.zqlgroupId>
        <artifactId>youlexuan_search_interfaceartifactId>
        <version>1.0version>
    dependency>

    
    <dependency>
        <groupId>com.github.pagehelpergroupId>
        <artifactId>pagehelperartifactId>
    dependency>
    <dependency>
        <groupId>org.mybatisgroupId>
        <artifactId>mybatisartifactId>
    dependency>

dependencies>
<build>
    <plugins>
        
        <plugin>
            <groupId>org.apache.tomcat.mavengroupId>
            <artifactId>tomcat7-maven-pluginartifactId>
            <configuration>
                <path>/path>
                <port>9104port>
            configuration>
        plugin>
    plugins>
build>

(2)添加web.xml,参见其它web工程,如:youlexuan_portal_web


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>springmvcservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:spring/springmvc.xmlparam-value>
        init-param>
    servlet>
    <servlet-mapping>
        <servlet-name>springmvcservlet-name>
        <url-pattern>*.dourl-pattern>
    servlet-mapping>
    <context-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:spring/spring*.xmlparam-value>
    context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        listener-class>
    listener>
    <filter>
        <filter-name>characterEncodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>UTF-8param-value>
        init-param>
        <init-param>
            <param-name>forceEncodingparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>characterEncodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

web-app>

(3)添加配置文件,参见其它web工程,如:youlexuan_portal_web
spring_mvc.xml修改:应用名,包名


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
		http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <context:component-scan base-package="com.zql"/>

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes" value="application/json"/>
                <property name="features">
                    <array>
                        <value>WriteMapNullValuevalue>
                        <value>WriteDateUseDateFormatvalue>
                    array>
                property>
            bean>
        mvc:message-converters>
    mvc:annotation-driven>

    
    <dubbo:application name="youlexuan_search_web" />
    <dubbo:registry address="zookeeper://192.168.188.180:2181"/>
    <dubbo:annotation package="com.zql" />
beans>

(4)创建包com.zql.search.controller 编写控制器类 ItemSearchController.java

package com.zql.search.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.zql.search.service.ItemSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@RestController
@RequestMapping("/itemSearch")
public class ItemSearchController {

    @Reference
    private ItemSearchService itemSearchService;
    //@Reference是注入的分布式中的远程服务对象,需要dubbo的配置;
    // @Resource和@Autowired是注入本地spring容器中的对象

    @RequestMapping("/search")
    public Map<String, Object> search(@RequestBody Map searchMap){

        return itemSearchService.search(searchMap);
    }
}

测试后端可参见postman工具 八、postman的使用

http://localhost:9104/itemSearch/search.do

{'keyWords':'手机'}

二十七、商城 - 搜索解决方案-Solr(15)【1】_第37张图片

4.3 前端代码

4.3.1 拷贝资源

将 资源 \ 静态原型 \ 网站前台,所需资源拷贝至youlexuan_search_web \ webapp 下面

二十七、商城 - 搜索解决方案-Solr(15)【1】_第38张图片
拷贝base.js到js文件夹,并在js文件夹下建立service、controller目录

二十七、商城 - 搜索解决方案-Solr(15)【1】_第39张图片

4.3.2 服务层

youlexuan_search_web工程创建 searchService.js

app.service('searchService',function ($http) {

        this.search = function (searchMap) {

            return $http.post("itemSearch/search.do",searchMap);
        }
});

4.3.3 控制层

youlexuan_search_web 工程 searchController.js

app.controller('searchController',function ($scope,$controller,searchService) {

    $controller('baseController',{$scope:$scope});//继承

        $scope.search=function () {

           searchService.search($scope.searchMap).success(function (response) {


               $scope.resultMap = response; //搜索返回的结果

           })
        }
});

4.3.4 页面

youlexuan_search_web工程search.html

引入js、指定控制器

二十七、商城 - 搜索解决方案-Solr(15)【1】_第40张图片

前台测试显示查看

二十七、商城 - 搜索解决方案-Solr(15)【1】_第41张图片循环显示数据、绑定搜索框二十七、商城 - 搜索解决方案-Solr(15)【1】_第42张图片

测试:

  1. 安装youlexuan_search_interface
  2. 启动youlexuan_search_service
  3. 启动youlexuan_search_web

测试:http://localhost:9104/search.html

二十七、商城 - 搜索解决方案-Solr(15)【1】_第43张图片

附完整 search.html

DOCTYPE html>
DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
		<title>产品列表页title>
		<link rel="icon" href="assets/img/favicon.ico">

		<link rel="stylesheet" type="text/css" href="css/webbase.css" />
		<link rel="stylesheet" type="text/css" href="css/pages-list.css" />
		<link rel="stylesheet" type="text/css" href="css/widget-cartPanelView.css" />

		<script type="text/javascript" src="plugins/angularjs/angular.min.js">script>
		<script type="text/javascript" src="js/base.js">script>
		<script type="text/javascript" src="js/service/searchService.js">script>
		<script type="text/javascript" src="js/controller/baseController.js">script>
		<script type="text/javascript" src="js/controller/searchController.js">script>

		<style type="text/css" >
			.hot-list .list-wrap {
				box-sizing:border-box;
				padding-left:20px;
			}
		style>
	head>

	<body ng-app="youlexuan" ng-controller="searchController">
		
		
		<div id="nav-bottom">
			
			<div class="nav-top">
				<div class="top">
					<div class="py-container">
						<div class="shortcut">
							<ul class="fl">
								<li class="f-item">优乐选欢迎您!li>
								<li class="f-item"><a href="login.html" target="_blank">登录a> <span><a href="register.html" target="_blank">免费注册a>span>li>
							ul>
							<ul class="fr">
								<li class="f-item">我的订单li>
								<li class="f-item space">li>
								<li class="f-item">
									<a href="home.html" target="_blank">我的优乐选a>
								li>
								<li class="f-item space">li>
								<li class="f-item">优乐选会员li>
								<li class="f-item space">li>
								<li class="f-item">企业采购li>
								<li class="f-item space">li>
								<li class="f-item">关注优乐选li>
								<li class="f-item space">li>
								<li class="f-item" id="service">
									<span>客户服务span>
									<ul class="service">
										<li>
											<a href="cooperation.html" target="_blank">合作招商a>
										li>
										<li>
											<a href="shoplogin.html" target="_blank">商家后台a>
										li>
										<li>
											<a href="cooperation.html" target="_blank">合作招商a>
										li>
										<li>
											<a href="#">商家后台a>
										li>
									ul>
								li>
								<li class="f-item space">li>
								<li class="f-item">网站导航li>
							ul>
						div>
					div>
				div>

				
				<div class="header">
					<div class="py-container">
						<div class="yui3-g Logo">
							<div class="yui3-u Left logoArea">
								<a class="logo-bd" title="优乐选" href="JD-index.html" target="_blank">a>
							div>
							<div class="yui3-u Center searchArea">
								<div class="search">
									<form action="" class="sui-form form-inline">
										
										<div class="input-append">
											<input type="text" id="autocomplete" ng-model="searchMap.keyWords" type="text" class="input-error input-xxlarge" />
											<button class="sui-btn btn-xlarge btn-danger" ng-click="search()" type="button">搜索button>
										div>
									form>
								div>
								<div class="hotwords">
									<ul>
										<li class="f-item">优乐选首发li>
										<li class="f-item">亿元优惠li>
										<li class="f-item">9.9元团购li>
										<li class="f-item">每满99减30li>
										<li class="f-item">亿元优惠li>
										<li class="f-item">9.9元团购li>
										<li class="f-item">办公用品li>

									ul>
								div>
							div>
							<div class="yui3-u Right shopArea">
								<div class="fr shopcar">
									<div class="show-shopcar" id="shopcar">
										<span class="car">span>
										<a class="sui-btn btn-default btn-xlarge" href="cart.html" target="_blank">
											<span>我的购物车span>
											<i class="shopnum">0i>
										a>
										<div class="clearfix shopcarlist" id="shopcarlist" style="display:none">
											<p>"啊哦,你的购物车还没有商品哦!"p>
											<p>"啊哦,你的购物车还没有商品哦!"p>
										div>
									div>
								div>
							div>
						div>

						<div class="yui3-g NavList">
							<div class="yui3-u Left all-sort">
								<h4>全部商品分类h4>
							div>
							<div class="yui3-u Center navArea">
								<ul class="nav">
									<li class="f-item">服装城li>
									<li class="f-item">美妆馆li>
									<li class="f-item">品优超市li>
									<li class="f-item">全球购li>
									<li class="f-item">闪购li>
									<li class="f-item">团购li>
									<li class="f-item">有趣li>
									<li class="f-item">
										<a href="seckill-index.html" target="_blank">秒杀a>
									li>
								ul>
							div>
							<div class="yui3-u Right">div>
						div>
					div>
				div>
			div>
		div>


	
	<div class="main">
		<div class="py-container">
			
			<div class="bread">
				<ul class="fl sui-breadcrumb">
					<li>
						<a href="#">全部结果 {{resultMap.total}}a>
					li>
					<li class="active"> 智能手机li>
				ul>
				<ul class="tags-choose">
					<li class="tag">全网通<i class="sui-icon icon-tb-close">i>li>
					<li class="tag">63G<i class="sui-icon icon-tb-close">i>li>
				ul>
				<form class="fl sui-form form-dark">
					<div class="input-control control-right">
						<input type="text" />
						<i class="sui-icon icon-touch-magnifier">i>
					div>
				form>
				<div class="clearfix">div>
			div>
			
			<div class="clearfix selector">
				<div class="type-wrap">
					<div class="fl key">商品分类div>
					<div class="fl value">
						<a href="#">手机a>  <a href="#">电视a>
					div>
					<div class="fl ext">div>
				div>
				<div class="type-wrap logo">
					<div class="fl key brand">品牌div>
					<div class="value logos">
						<ul class="logo-list">
							<li><img src="img/_/phone01.png" />li>
							<li><img src="img/_/phone02.png" />li>
							<li><img src="img/_/phone03.png" />li>
							<li><img src="img/_/phone04.png" />li>
							<li><img src="img/_/phone05.png" />li>
							<li><img src="img/_/phone06.png" />li>
							<li><img src="img/_/phone07.png" />li>
							<li><img src="img/_/phone08.png" />li>
							<li><img src="img/_/phone09.png" />li>
							<li><img src="img/_/phone10.png" />li>
							<li><img src="img/_/phone11.png" />li>
							<li><img src="img/_/phone12.png" />li>
							<li><img src="img/_/phone13.png" />li>
							<li><img src="img/_/phone14.png" />li>
							<li><img src="img/_/phone05.png" />li>
							<li><img src="img/_/phone06.png" />li>
							<li><img src="img/_/phone07.png" />li>
							<li><img src="img/_/phone02.png" />li>
						ul>
					div>
					<div class="ext">
						<a href="javascript:void(0);" class="sui-btn">多选a>
						<a href="javascript:void(0);">更多a>
					div>
				div>
				<div class="type-wrap">
					<div class="fl key">网络制式div>
					<div class="fl value">
						<ul class="type-list">
							<li>
								<a>GSM(移动/联通2G)a>
							li>
							<li>
								<a>电信2Ga>
							li>
							<li>
								<a>电信3Ga>
							li>
							<li>
								<a>移动3Ga>
							li>
							<li>
								<a>联通3Ga>
							li>
							<li>
								<a>联通4Ga>
							li>
							<li>
								<a>电信3Ga>
							li>
							<li>
								<a>移动3Ga>
							li>
							<li>
								<a>联通3Ga>
							li>
							<li>
								<a>联通4Ga>
							li>
						ul>
					div>
					<div class="fl ext">div>
				div>
				<div class="type-wrap">
					<div class="fl key">显示屏尺寸div>
					<div class="fl value">
						<ul class="type-list">
							<li>
								<a>4.0-4.9英寸a>
							li>
							<li>
								<a>4.0-4.9英寸a>
							li>
						ul>
					div>
					<div class="fl ext">div>
				div>
				<div class="type-wrap">
					<div class="fl key">摄像头像素div>
					<div class="fl value">
						<ul class="type-list">
							<li>
								<a>1200万以上a>
							li>
							<li>
								<a>800-1199万a>
							li>
							<li>
								<a>1200-1599万a>
							li>
							<li>
								<a>1600万以上a>
							li>
							<li>
								<a>无摄像头a>
							li>
						ul>
					div>
					<div class="fl ext">div>
				div>
				<div class="type-wrap">
					<div class="fl key">价格div>
					<div class="fl value">
						<ul class="type-list">
							<li>
								<a>0-500元a>
							li>
							<li>
								<a>500-1000元a>
							li>
							<li>
								<a>1000-1500元a>
							li>
							<li>
								<a>1500-2000元a>
							li>
							<li>
								<a>2000-3000元 a>
							li>
							<li>
								<a>3000元以上a>
							li>
						ul>
					div>
					<div class="fl ext">
					div>
				div>
				<div class="type-wrap">
					<div class="fl key">更多筛选项div>
					<div class="fl value">
						<ul class="type-list">
							<li>
								<a>特点a>
							li>
							<li>
								<a>系统a>
							li>
							<li>
								<a>手机内存 a>
							li>
							<li>
								<a>单卡双卡a>
							li>
							<li>
								<a>其他a>
							li>
						ul>
					div>
					<div class="fl ext">
					div>
				div>
			div>
			
			<div class="details">
				<div class="sui-navbar">
					<div class="navbar-inner filter">
						<ul class="sui-nav">
							<li class="active">
								<a href="#">综合a>
							li>
							<li>
								<a href="#">销量a>
							li>
							<li>
								<a href="#">新品a>
							li>
							<li>
								<a href="#">评价a>
							li>
							<li>
								<a href="#">价格a>
							li>
						ul>
					div>
				div>
				<div class="goods-list">
					<ul class="yui3-g">
						
						<li class="yui3-u-1-5" ng-repeat="item in resultMap.rows">
							<div class="list-wrap">
								<div class="p-img">
									<a href="item.html" target="_blank"><img src="{{item.image}}" />a>
								div>
								<div class="price">
									<strong>
											<em>¥em>
											<i>{{item.price}}i>
										strong>
								div>
								<div class="attr">
									<em>{{item.title}}em>
								div>
								<div class="cu">
									<em>em>
								div>
								<div class="commit">
									<i class="command">已有2000人评价i>
								div>
								<div class="operate">
									<a href="success-cart.html" target="_blank" class="sui-btn btn-bordered btn-danger">加入购物车a>
									<a href="javascript:void(0);" class="sui-btn btn-bordered">对比a>
									<a href="javascript:void(0);" class="sui-btn btn-bordered">关注a>
								div>
							div>
						li>
					ul>
				div>
				<div class="fr page">
					<div class="sui-pagination pagination-large">
						<ul>
							<li class="prev disabled">
								<a href="#">«上一页a>
							li>
							<li class="active">
								<a href="#">1a>
							li>
							<li>
								<a href="#">2a>
							li>
							<li>
								<a href="#">3a>
							li>
							<li>
								<a href="#">4a>
							li>
							<li>
								<a href="#">5a>
							li>
							<li class="dotted"><span>...span>li>
							<li class="next">
								<a href="#">下一页»a>
							li>
						ul>
						<div><span>共10页 span><span>
      到第
      <input type="text" class="page-num"><button class="page-confirm" onclick="alert(1)">确定button>span>div>
					div>
				div>
			div>
			
			<div class="clearfix hot-sale">
				<h4 class="title">热卖商品h4>
				<div class="hot-list">
					<ul class="yui3-g">
						<li class="yui3-u-1-4">
							<div class="list-wrap">
								<div class="p-img">
									<img src="img/xg/h02.png" />
								div>
								<div class="attr">
									<em>Apple苹果iPhone 6s (A1699)em>
								div>
								<div class="price">
									<strong>
											<em>¥em>
											<i>4088.00i>
										strong>
								div>
								<div class="commit">
									<i class="command">已有700人评价i>
								div>
							div>
						li>
						<li class="yui3-u-1-4">
							<div class="list-wrap">
								<div class="p-img">
								<img src="img/xg/h05.png" />
								div>
								<div class="attr">
									<em>金属A面,360°翻转,APP下单省300!em>
								div>
								<div class="price">
									<strong>
											<em>¥em>
											<i>4088.00i>
										strong>
								div>
								<div class="commit">
									<i class="command">已有700人评价i>
								div>
							div>
						li>
						<li class="yui3-u-1-4">
							<div class="list-wrap">
								<div class="p-img">
									<img src="img/xg/h04.png" />
								div>
								<div class="attr">
									<em>256SSD商务大咖,完爆职场,APP下单立减200em>
								div>
								<div class="price">
									<strong>
											<em>¥em>
											<i>4068.00i>
										strong>
								div>
								<div class="commit">
									<i class="command">已有20人评价i>
								div>
							div>
						li>
						<li class="yui3-u-1-4">
							<div class="list-wrap">
								<div class="p-img">
									<img src="img/xg/h03.png" />
								div>
								<div class="attr">
									<em>Apple苹果iPhone 6s (A1699)em>
								div>
								<div class="price">
									<strong>
											<em>¥em>
											<i>4088.00i>
										strong>
								div>
								<div class="commit">
									<i class="command">已有700人评价i>
								div>
							div>
						li>
					ul>
				div>
			div>
		div>
	div>
	
	
	<div class="clearfix footer">
		<div class="py-container">
			<div class="footlink">
				<div class="Mod-service">
					<ul class="Mod-Service-list">
						<li class="grid-service-item intro  intro1">

							<i class="serivce-item fl">i>
							<div class="service-text">
								<h4>正品保障h4>
								<p>正品保障,提供发票p>
							div>

						li>
						<li class="grid-service-item  intro intro2">

							<i class="serivce-item fl">i>
							<div class="service-text">
								<h4>正品保障h4>
								<p>正品保障,提供发票p>
							div>

						li>
						<li class="grid-service-item intro  intro3">

							<i class="serivce-item fl">i>
							<div class="service-text">
								<h4>正品保障h4>
								<p>正品保障,提供发票p>
							div>

						li>
						<li class="grid-service-item  intro intro4">

							<i class="serivce-item fl">i>
							<div class="service-text">
								<h4>正品保障h4>
								<p>正品保障,提供发票p>
							div>

						li>
						<li class="grid-service-item intro intro5">

							<i class="serivce-item fl">i>
							<div class="service-text">
								<h4>正品保障h4>
								<p>正品保障,提供发票p>
							div>

						li>
					ul>
				div>
				<div class="clearfix Mod-list">
					<div class="yui3-g">
						<div class="yui3-u-1-6">
							<h4>购物指南h4>
							<ul class="unstyled">
								<li>购物流程li>
								<li>会员介绍li>
								<li>生活旅行/团购li>
								<li>常见问题li>
								<li>购物指南li>
							ul>

						div>
						<div class="yui3-u-1-6">
							<h4>配送方式h4>
							<ul class="unstyled">
								<li>上门自提li>
								<li>211限时达li>
								<li>配送服务查询li>
								<li>配送费收取标准li>
								<li>海外配送li>
							ul>
						div>
						<div class="yui3-u-1-6">
							<h4>支付方式h4>
							<ul class="unstyled">
								<li>货到付款li>
								<li>在线支付li>
								<li>分期付款li>
								<li>邮局汇款li>
								<li>公司转账li>
							ul>
						div>
						<div class="yui3-u-1-6">
							<h4>售后服务h4>
							<ul class="unstyled">
								<li>售后政策li>
								<li>价格保护li>
								<li>退款说明li>
								<li>返修/退换货li>
								<li>取消订单li>
							ul>
						div>
						<div class="yui3-u-1-6">
							<h4>特色服务h4>
							<ul class="unstyled">
								<li>夺宝岛li>
								<li>DIY装机li>
								<li>延保服务li>
								<li>优乐选E卡li>
								<li>优乐选通信li>
							ul>
						div>
						<div class="yui3-u-1-6">
							<h4>帮助中心h4>
							<img src="img/xg/erweima.jpg">
						div>
					div>
				div>
				<div class="Mod-copyright">
					<ul class="helpLink">
						<li>关于我们<span class="space">span>li>
						<li>联系我们<span class="space">span>li>
						<li>关于我们<span class="space">span>li>
						<li>商家入驻<span class="space">span>li>
						<li>营销中心<span class="space">span>li>
						<li>友情链接<span class="space">span>li>
						<li>关于我们<span class="space">span>li>
						<li>营销中心<span class="space">span>li>
						<li>友情链接<span class="space">span>li>
						<li>关于我们li>
					ul>
					<p>地址:北京市朝阳区五方桥基地 邮编:100096 电话:400-650-7353 传真:010-88888100p>
					<p>京ICP备10218183号-88 京公网安备11010802020723号p>
				div>
			div>
		div>
	div>
	
	
	<div class="J-global-toolbar">
		<div class="toolbar-wrap J-wrap">
			<div class="toolbar">
				<div class="toolbar-panels J-panel">

					
					<div style="visibility: hidden;" class="J-content toolbar-panel tbar-panel-cart toolbar-animate-out">
						<h3 class="tbar-panel-header J-panel-header">
						<a href="" class="title"><i>i><em class="title">购物车em>a>
						<span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('cart');" >span>
					h3>
						<div class="tbar-panel-main">
							<div class="tbar-panel-content J-panel-content">
								<div id="J-cart-tips" class="tbar-tipbox hide">
									<div class="tip-inner">
										<span class="tip-text">还没有登录,登录后商品将被保存span>
										<a href="#none" class="tip-btn J-login">登录a>
									div>
								div>
								<div id="J-cart-render">
									
									<div id="cart-list" class="tbar-cart-list">
									div>
								div>
							div>
						div>
						
						<div id="cart-footer" class="tbar-panel-footer J-panel-footer">
							<div class="tbar-checkout">
								<div class="jtc-number"> <strong class="J-count" id="cart-number">0strong>件商品 div>
								<div class="jtc-sum"> 共计:<strong class="J-total" id="cart-sum">¥0strong> div>
								<a class="jtc-btn J-btn" href="#none" target="_blank">去购物车结算a>
							div>
						div>
					div>

					
					<div style="visibility: hidden;" data-name="follow" class="J-content toolbar-panel tbar-panel-follow">
						<h3 class="tbar-panel-header J-panel-header">
						<a href="#" target="_blank" class="title"> <i>i> <em class="title">我的关注em> a>
						<span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('follow');">span>
					h3>
						<div class="tbar-panel-main">
							<div class="tbar-panel-content J-panel-content">
								<div class="tbar-tipbox2">
									<div class="tip-inner"> <i class="i-loading">i> div>
								div>
							div>
						div>
						<div class="tbar-panel-footer J-panel-footer">div>
					div>

					
					<div style="visibility: hidden;" class="J-content toolbar-panel tbar-panel-history toolbar-animate-in">
						<h3 class="tbar-panel-header J-panel-header">
						<a href="#" target="_blank" class="title"> <i>i> <em class="title">我的足迹em> a>
						<span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('history');">span>
					h3>
						<div class="tbar-panel-main">
							<div class="tbar-panel-content J-panel-content">
								<div class="jt-history-wrap">
									<ul>
										
									ul>
									<a href="#" class="history-bottom-more" target="_blank">查看更多足迹商品 >>a>
								div>
							div>
						div>
						<div class="tbar-panel-footer J-panel-footer">div>
					div>

				div>

				<div class="toolbar-header">div>

				
				<div class="toolbar-tabs J-tab">
					<div onclick="cartPanelView.tabItemClick('cart')" class="toolbar-tab tbar-tab-cart" data="购物车" tag="cart">
						<i class="tab-ico">i>
						<em class="tab-text">em>
						<span class="tab-sub J-count " id="tab-sub-cart-count">0span>
					div>
					<div onclick="cartPanelView.tabItemClick('follow')" class="toolbar-tab tbar-tab-follow" data="我的关注" tag="follow">
						<i class="tab-ico">i>
						<em class="tab-text">em>
						<span class="tab-sub J-count hide">0span>
					div>
					<div onclick="cartPanelView.tabItemClick('history')" class="toolbar-tab tbar-tab-history" data="我的足迹" tag="history">
						<i class="tab-ico">i>
						<em class="tab-text">em>
						<span class="tab-sub J-count hide">0span>
					div>
				div>

				<div class="toolbar-footer">
					<div class="toolbar-tab tbar-tab-top">
						<a href="#"> <i class="tab-ico  ">i> <em class="footer-tab-text">顶部em> a>
					div>
					<div class="toolbar-tab tbar-tab-feedback">
						<a href="#" target="_blank"> <i class="tab-ico">i> <em class="footer-tab-text ">反馈em> a>
					div>
				div>

				<div class="toolbar-mini">div>

			div>

			<div id="J-toolbar-load-hook">div>

		div>
	div>
	
	<script type="text/template" id="tbar-cart-item-template">
		<div class="tbar-cart-item">
			<div class="jtc-item-promo">
				<em class="promo-tag promo-mz">满赠<i class="arrow"></i></em>
				<div class="promo-text">已购满600元,您可领赠品</div>
			</div>
			<div class="jtc-item-goods">
				<span class="p-img"><a href="#" target="_blank"><img src="{2}" alt="{1}" height="50" width="50" /></a></span>
				<div class="p-name">
					<a href="#">{1}</a>
				</div>
				<div class="p-price"><strong>¥{3}</strong>×{4} </div>
				<a href="#none" class="p-del J-del">删除</a>
			</div>
		</div>
	script>
	
		<script type="text/javascript" src="js/plugins/jquery/jquery.min.js">script>
		<script type="text/javascript">
			$(function() {
				$("#service").hover(function() {
					$(".service").show();
				}, function() {
					$(".service").hide();
				});
				$("#shopcar").hover(function() {
					$("#shopcarlist").show();
				}, function() {
					$("#shopcarlist").hide();
				});

			})
		script>
		<script type="text/javascript" src="js/model/cartModel.js">script>
		<script type="text/javascript" src="js/czFunction.js">script>
		<script type="text/javascript" src="js/plugins/jquery.easing/jquery.easing.min.js">script>
		<script type="text/javascript" src="js/plugins/sui/sui.min.js">script>
		<script type="text/javascript" src="js/widget/cartPanelView.js">script>
	body>

html>

当前 youlexuan 所有完整代码

你可能感兴趣的:(#,计算机(Java中级)中级,阶段,solr,lucene,搜索引擎)