【实战】电商实战-淘淘商城-缓存搭建(第六天)

  1. 课程计划

第六天:

  1. Solrj使用测试
  2. 把数据库中的数据导入索引库
  3. 搜索功能的实现

 

  1. 使用solrJ管理索引库

使用SolrJ可以实现索引库的增删改查操作。

 

    1. 添加文档

第一步:把solrJ的jar包添加到工程中。

第二步:创建一个SolrServer,使用HttpSolrServer创建对象。

第三步:创建一个文档对象SolrInputDocument对象。

第四步:向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。

第五步:把文档添加到索引库中。

第六步:提交。

@Test

public void addDocument() throws Exception {

// 第一步:把solrJ的jar包添加到工程中。

// 第二步:创建一个SolrServer,使用HttpSolrServer创建对象。

SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");

// 第三步:创建一个文档对象SolrInputDocument对象。

SolrInputDocument document = new SolrInputDocument();

// 第四步:向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。

document.addField("id", "test001");

document.addField("item_title", "测试商品");

document.addField("item_price", "199");

// 第五步:把文档添加到索引库中。

solrServer.add(document);

// 第六步:提交。

solrServer.commit();

}

 

    1. 删除文档
      1. 根据id删除

第一步:创建一个SolrServer对象。

第二步:调用SolrServer对象的根据id删除的方法。

第三步:提交。

@Test

public void deleteDocumentById() throws Exception {

// 第一步:创建一个SolrServer对象。

SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");

// 第二步:调用SolrServer对象的根据id删除的方法。

solrServer.deleteById("1");

// 第三步:提交。

solrServer.commit();

}

 

      1. 根据查询删除

@Test

public void deleteDocumentByQuery() throws Exception {

SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");

solrServer.deleteByQuery("title:change.me");

solrServer.commit();

}

 

    1. 查询索引库

查询步骤:

第一步:创建一个SolrServer对象

第二步:创建一个SolrQuery对象。

第三步:向SolrQuery中添加查询条件、过滤条件。。。

第四步:执行查询。得到一个Response对象。

第五步:取查询结果。

第六步:遍历结果并打印。

 

      1. 简单查询

@Test

public void queryDocument() throws Exception {

// 第一步:创建一个SolrServer对象

SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");

// 第二步:创建一个SolrQuery对象。

SolrQuery query = new SolrQuery();

// 第三步:向SolrQuery中添加查询条件、过滤条件。。。

query.setQuery("*:*");

// 第四步:执行查询。得到一个Response对象。

QueryResponse response = solrServer.query(query);

// 第五步:取查询结果。

SolrDocumentList solrDocumentList = response.getResults();

System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());

// 第六步:遍历结果并打印。

for (SolrDocument solrDocument : solrDocumentList) {

System.out.println(solrDocument.get("id"));

System.out.println(solrDocument.get("item_title"));

System.out.println(solrDocument.get("item_price"));

}

}

 

      1. 带高亮显示

@Test

public void queryDocumentWithHighLighting() throws Exception {

// 第一步:创建一个SolrServer对象

SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");

// 第二步:创建一个SolrQuery对象。

SolrQuery query = new SolrQuery();

// 第三步:向SolrQuery中添加查询条件、过滤条件。。。

query.setQuery("测试");

//指定默认搜索域

query.set("df", "item_keywords");

//开启高亮显示

query.setHighlight(true);

//高亮显示的域

query.addHighlightField("item_title");

query.setHighlightSimplePre("<em>");

query.setHighlightSimplePost("</em>");

// 第四步:执行查询。得到一个Response对象。

QueryResponse response = solrServer.query(query);

// 第五步:取查询结果。

SolrDocumentList solrDocumentList = response.getResults();

System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());

// 第六步:遍历结果并打印。

for (SolrDocument solrDocument : solrDocumentList) {

System.out.println(solrDocument.get("id"));

//取高亮显示

Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");

String itemTitle = null;

if (list != null && list.size() > 0) {

itemTitle = list.get(0);

} else {

itemTitle = (String) solrDocument.get("item_title");

}

System.out.println(itemTitle);

System.out.println(solrDocument.get("item_price"));

}

}

 

  1. 把商品数据导入到索引库中
    1. 功能分析

schema.xml中定义

  1. 商品Id
  2. 商品标题
  3. 商品卖点
  4. 商品价格
  5. 商品图片
  6. 分类名称
  7. 商品描述

 

需要从tb_item, tb_item_cat, tb_item_desc表中查询数据。

Sql1:

SELECT

a.id,

a.title,

a.sell_point,

a.price,

a.image,

b. NAME category_name,

c.item_desc

FROM

tb_item a,

tb_item_cat b,

tb_item_desc c

WHERE

a.cid = b.id

AND a.id = c.item_id

AND a.`status` = 1;

 

Sql2:

SELECT

a.id,

a.title,

a.sell_point,

a.price,

a.image,

b. NAME category_name,

c.item_desc

FROM

tb_item a

JOIN tb_item_cat b ON a.cid = b.id

JOIN tb_item_desc c ON a.id = c.item_id

WHERE

a.`status` = 1

 

参数:无

业务逻辑:taotao-search中实现

  1. 查询所有商品数据。
  2. 创建一个SolrServer对象。
  3. 为每个商品创建一个SolrInputDocument对象。
  4. 为文档添加域
  5. 向索引库中添加文档。
  6. 返回TaotaoResult。

 

在taotao-manager-web中调用服务。实现数据导入功能。

    1. Dao层

返回一个pojo对应查询的sql语句。

public class SearchItem implements Serializable{

 

private String id;

private String title;

private String sell_point;

private long price;

private String image;

private String category_name;

private String item_desc;

}

放到taotao-common中。

 

接口的返回值:List<SearchItem>

 

接口定义:

public interface SearchItemMapper {

 

List<SearchItem> getItemList();

}

 

Mapper映射文件:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.taotao.search.mapper.SearchItemMapper" >

 

<select id="getItemList" resultType="com.taotao.common.pojo.SearchItem">

SELECT

a.id,

a.title,

a.sell_point,

a.price,

a.image,

b. NAME category_name,

c.item_desc

FROM

tb_item a

JOIN tb_item_cat b ON a.cid = b.id

JOIN tb_item_desc c ON a.id = c.item_id

WHERE

a.status = 1

</select>

</mapper>

 

    1. Service层

参数:无

业务逻辑:taotao-search中实现

1、查询所有商品数据。

2、创建一个SolrServer对象。

3、为每个商品创建一个SolrInputDocument对象。

4、为文档添加域

5、向索引库中添加文档。

6、返回TaotaoResult。

在 applicationContext-solr.xml中配置SolrServer对象。

uploading.4e448015.gif转存失败重新上传取消

@Service

public class SearchItemServiceImpl implements SearchItemService {

 

@Autowired

private SearchItemMapper searchItemMapper;

@Autowired

private SolrServer solrServer;

 

@Override

public TaotaoResult importAllItems() throws Exception{

// 1、查询所有商品数据。

List<SearchItem> itemList = searchItemMapper.getItemList();

// 2、创建一个SolrServer对象。

// 3、为每个商品创建一个SolrInputDocument对象。

for (SearchItem searchItem : itemList) {

SolrInputDocument document = new SolrInputDocument();

// 4、为文档添加域

document.addField("id", searchItem.getId());

document.addField("item_title", searchItem.getTitle());

document.addField("item_sell_point", searchItem.getSell_point());

document.addField("item_price", searchItem.getPrice());

document.addField("item_image", searchItem.getImage());

document.addField("item_category_name", searchItem.getCategory_name());

document.addField("item_desc", searchItem.getItem_desc());

// 5、向索引库中添加文档。

solrServer.add(document);

}

//提交修改

solrServer.commit();

// 6、返回TaotaoResult。

return TaotaoResult.ok();

}

 

}

 

      1. 发布服务

uploading.4e448015.gif转存失败重新上传取消

 

    1. 表现层
      1. 引用服务

在taotao-manager-web中引用服务。

uploading.4e448015.gif转存失败重新上传取消

uploading.4e448015.gif转存失败重新上传取消

      1. Controller

请求的url:/index/importall

参数:无

返回值:json数据。TaotaoResult。

@Controller

public class SearchItemController {

 

@Autowired

private SearchItemService searchItemService;

 

@RequestMapping("/index/importall")

@ResponseBody

public TaotaoResult importAllItems() {

try {

TaotaoResult result = searchItemService.importAllItems();

return result;

} catch (Exception e) {

e.printStackTrace();

return TaotaoResult.build(500, "导入数据失败");

}

}

}

 

      1. Jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<div>

<a href="javascript:void(0)" class="easyui-linkbutton" onclick="importAll()">一键导入商品数据到索引库</a>

</div>

<script type="text/javascript">

 

function importAll() {

$.post("/index/importall",null,function(data){

if (data.status==200) {

$.messager.alert('提示','商品数据导入成功!');

} else {

 

$.messager.alert('提示','商品数据导入失败!');

}

 

});

}

</script>

taotao-search-service工程的pom文件中添加如下配置:

<!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉。 -->

<build>

<resources>

            <resource>

                <directory>src/main/java</directory>

                <includes>

                    <include>**/*.properties</include>

                    <include>**/*.xml</include>

                </includes>

                <filtering>false</filtering>

            </resource>

            <!-- 如果没有此节点,src/main/resources目录下的配置文件将被忽略 -->

            <resource>

                <directory>src/main/resources</directory>

                <includes>

                    <include>**/*.properties</include>

                    <include>**/*.xml</include>

                </includes>

                <filtering>false</filtering>

            </resource>

        </resources>

</build>

 

  1. 商品搜索功能实现
    1. 搜索表现层工程搭建

搜索结果页面的展示。

可以参考taotao-manager-web创建。

打包方式war。

Taotao-search-web

uploading.4e448015.gif转存失败重新上传取消

      1. Pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>com.taotao</groupId>

<artifactId>taotao-parent</artifactId>

<version>0.0.1-SNAPSHOT</version>

</parent>

<groupId>com.taotao</groupId>

<artifactId>taotao-search-web</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>war</packaging>

<dependencies>

<dependency>

<groupId>com.taotao</groupId>

<artifactId>taotao-search-interface</artifactId>

<version>0.0.1-SNAPSHOT</version>

</dependency>

<!-- Spring -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aspects</artifactId>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jms</artifactId>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

</dependency>

<!-- JSP相关 -->

<dependency>

<groupId>jstl</groupId>

<artifactId>jstl</artifactId>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>servlet-api</artifactId>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>jsp-api</artifactId>

<scope>provided</scope>

</dependency>

<!-- dubbo相关 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>dubbo</artifactId>

<!-- 排除依赖 -->

<exclusions>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring</artifactId>

</exclusion>

<exclusion>

<groupId>org.jboss.netty</groupId>

<artifactId>netty</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.apache.zookeeper</groupId>

<artifactId>zookeeper</artifactId>

</dependency>

<dependency>

<groupId>com.github.sgroschupf</groupId>

<artifactId>zkclient</artifactId>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

</dependency>

</dependencies>

<!-- 配置tomcat插件 -->

<build>

<plugins>

<plugin>

<groupId>org.apache.tomcat.maven</groupId>

<artifactId>tomcat7-maven-plugin</artifactId>

<configuration>

<port>8085</port>

<path>/</path>

</configuration>

</plugin>

</plugins>

</build>

</project>

 

      1. 框架整合

uploading.4e448015.gif转存失败重新上传取消

 

    1. 搜索功能分析

在首页的搜索框中输入搜索条件,然后跳转到搜索结果页面。搜索结果页面在taotao-search-web工程中。

uploading.4e448015.gif转存失败重新上传取消

 

请求的url:/search

参数:

1、q 查询条件。

2、page 页码。默认为1

返回值:

逻辑视图,返回值。String。

 

业务逻辑:

  1. 接收查询条件。
  2. 创建一个SolrServer对象,需要注入。
  3. 创建一个SolrQuery对象。
  4. 需要设置查询条件、分页条件、设置默认搜索域、高亮设置。
  5. 执行查询,返回QueryResponse对象。
  6. 取返回结果,封装到List<SearchItem>中。
  7. 返回查询结果的总记录数,计算查询结果的总页数。
  8. 得到查询结果,渲染jsp

 

    1. Dao层

访问索引库的类。定义一些通用的数据访问方法。

业务逻辑就是查询索引库。

参数:SolrQuery对象

业务逻辑:

  1. 根据Query对象进行查询。
  2. 返回查询结果。List<SearchItem>、查询结果的总记录数。

需要把返回结果封装到pojo中,至少包含两个属性:List<SearchItem>、Long recordCount

再包含一个总页数。

public class SearchResult implements Serializable {

 

private List<SearchItem> itemList;

private long recordCount;

private long pageCount;

 

}

 

返回值:SearchResult

@Repository

public class SearchDao {

 

@Autowired

private SolrServer solrServer;

 

public SearchResult search(SolrQuery query) throws Exception {

//根据query对象查询索引库

QueryResponse response = solrServer.query(query);

//取商品列表

SolrDocumentList solrDocumentList = response.getResults();

//商品列表

List<SearchItem> itemList = new ArrayList<>();

for (SolrDocument solrDocument : solrDocumentList) {

SearchItem item = new SearchItem();

item.setId((String) solrDocument.get("id"));

item.setCategory_name((String) solrDocument.get("item_category_name"));

item.setImage((String) solrDocument.get("item_image"));

item.setPrice((long) solrDocument.get("item_price"));

item.setSell_point((String) solrDocument.get("item_sell_point"));

//取高亮显示

Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");

String itemTitle = "";

//有高亮显示的内容时。

if (list != null && list.size() > 0) {

itemTitle = list.get(0);

} else {

itemTitle = (String) solrDocument.get("item_title");

}

item.setTitle(itemTitle);

//添加到商品列表

itemList.add(item);

}

SearchResult result = new SearchResult();

//商品列表

result.setItemList(itemList);

//总记录数

result.setRecordCount(solrDocumentList.getNumFound());

 

return result;

}

}

 

    1. Service层

参数:queryString:查询条件

      Page:页码

      Rows:每页显示的记录数。

业务逻辑:

  1. 创建一个SolrQuery对象。
  2. 设置查询条件
  3. 设置分页条件
  4. 需要指定默认搜索域。
  5. 设置高亮
  6. 执行查询,调用SearchDao。得到SearchResult
  7. 需要计算总页数。
  8. 返回SearchResult

返回值:SearchResult

@Service

public class SearchServiceImpl implements SearchService {

 

@Autowired

private SearchDao searchDao;

 

@Override

public SearchResult search(String queryString, int page, int rows) throws Exception {

// 1、创建一个SolrQuery对象。

SolrQuery query = new SolrQuery();

// 2、设置查询条件

query.setQuery(queryString);

// 3、设置分页条件

query.setStart((page - 1) * rows);

query.setRows(rows);

// 4、需要指定默认搜索域。

query.set("df", "item_title");

// 5、设置高亮

query.setHighlight(true);

query.addHighlightField("item_title");

query.setHighlightSimplePre("<em style=\"color:red\">");

query.setHighlightSimplePost("</em>");

// 6、执行查询,调用SearchDao。得到SearchResult

SearchResult result = searchDao.search(query);

// 7、需要计算总页数。

long recordCount = result.getRecordCount();

long pageCount = recordCount / rows;

if (recordCount % rows > 0) {

pageCount++;

}

result.setPageCount(pageCount);

// 8、返回SearchResult

return result;

}

 

}

 

      1. 发布服务

uploading.4e448015.gif转存失败重新上传取消

    1. 表现层

需要taotao-search-web中实现。引用服务

uploading.4e448015.gif转存失败重新上传取消

请求的url:/search

参数:

1、q 查询条件。

2、page 页码。默认为1

返回值:

逻辑视图,返回值。String。

 

业务逻辑:

  1. 接收参数
  2. 调用服务查询商品列表
  3. 把查询结果传递给页面。需要参数回显。

@Controller

public class SearchController {

 

@Value("${ITEM_ROWS}")

private Integer ITEM_ROWS;

 

@Autowired

private SearchService searchService;

 

@RequestMapping("/search")

public String search(@RequestParam("q")String queryString,

@RequestParam(defaultValue="1")Integer page, Model model) throws Exception {

 

SearchResult result = searchService.search(queryString, page, ITEM_ROWS);

//传递给页面

model.addAttribute("query", queryString);

model.addAttribute("totalPages", result.getPageCount());

model.addAttribute("itemList", result.getItemList());

model.addAttribute("page", page);

 

//返回逻辑视图

return "search";

 

}

}

 

需要对请求参数进行转码处理:

uploading.4e448015.gif转存失败重新上传取消

 

翻页处理:

uploading.4e448015.gif转存失败重新上传取消

 

    1. 图片显示处理

数据库中保存的图片是以逗号分隔的url列表,只需要展示第一张图片即可。

方法:

  1. 向索引库中添加文档时,只取第一张写入索引库
  2. 从文档列表转换为商品列表时可以取一张。
  3. 在jsp中对列表拆分,只取一张展示。

 

可以在SearchItem中添加一个getImages方法:

uploading.4e448015.gif转存失败重新上传取消

在jsp中取属性:

uploading.4e448015.gif转存失败重新上传取消

 

 

  1. 全局异常处理
    1. uploading.4e448015.gif转存失败重新上传取消处理思路

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    1. 创建全局异常处理器

 

public class GlobalExceptionReslover implements HandlerExceptionResolver {

 

Logger logger = LoggerFactory.getLogger(GlobalExceptionReslover.class);

 

@Override

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,

Exception ex) {

//写日志文件

logger.error("系统发生异常", ex);

//发邮件、发短信

//Jmail:可以查找相关的资料

//需要在购买短信。调用第三方接口即可。

//展示错误页面

ModelAndView modelAndView = new ModelAndView();

modelAndView.addObject("message", "系统发生异常,请稍后重试");

modelAndView.setViewName("error/exception");

return modelAndView;

}

 

}

 

    1. Springmvc中配置异常处理器

uploading.4e448015.gif转存失败重新上传取消

发布了237 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/ZGL_cyy/article/details/105306145
今日推荐