要实现搜索功能,需要搭建solr服务
、搜索服务工程
、搜索系统(表现层的工程)
solr是java开发的。
solr的安装文件。
推荐在Linux环境下使用Solr,需要安装环境Linux。
需要安装jdk。参考链接:https://www.cnblogs.com/chenmingjun/p/9931593.html
需要安装tomcat。
第一步:使用SecureCRT的SFTP功能,把solr-4.10.3.tgz.tgz
的压缩包上传到Linux系统。
第二步:解压缩solr
后,删除该安装包。
[root@itheima ~]# tar -zxvf solr-4.10.3.tgz.tgz
......
......
[root@itheima ~]# ll
总用量 146496
drwxr-xr-x. 8 root root 218 11月 20 17:07 solr-4.10.3
-rw-r--r--. 1 root root 150010621 9月 26 23:16 solr-4.10.3.tgz.tgz
[root@itheima ~]# rm -rf solr-4.10.3.tgz.tgz
[root@itheima ~]# ll
总用量 0
drwxr-xr-x. 8 root root 218 11月 20 17:07 solr-4.10.3
[root@itheima ~]#
第三步:使用SecureCRT的SFTP功能,把apache-tomcat-7.0.47.tar.gz
的压缩包上传到Linux系统,解压后删除安装包。
[root@itheima ~]# tar -zxvf apache-tomcat-7.0.47.tar.gz
[root@itheima ~]# # rm -rf apache-tomcat-7.0.47.tar.gz
第四步:创建solr存放的目录
,复制apache-tomcat-7.0.47目录
到/usr/local/solr/tomcat目录
下
[root@itheima ~]# mkdir /usr/local/solr
[root@itheima ~]# cp -r apache-tomcat-7.0.47/ /usr/local/solr/tomcat
第五步:把solr-4.10.3/dist/solr-4.10.3.war文件
部署(复制)到tomcat
目录下,并重命名为solr.war
。
[root@itheima ~]# cp solr-4.10.3/dist/solr-4.10.3.war /usr/local/solr/tomcat/webapps/solr.war
注意:复制目录(文件夹)的时候需要加-r
,复制文件的时候不需要加-r
。
第六步:解压缩solr.war包
。启动tomcat即可自动解压war包
,并查看tomcat启动日志
。
[root@itheima ~]# cd /usr/local/solr/tomcat/bin/
[root@itheima bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/solr/tomcat
Using CATALINA_HOME: /usr/local/solr/tomcat
Using CATALINA_TMPDIR: /usr/local/solr/tomcat/temp
Using JRE_HOME: /usr/local/java/jdk1.7.0_80/jre
Using CLASSPATH: /usr/local/solr/tomcat/bin/bootstrap.jar:/usr/local/solr/tomcat/bin/tomcat-juli.jar
[root@itheima bin]# cd ..
[root@itheima tomcat]# tail -f logs/catalina.out
十一月 20, 2018 5:23:24 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory /usr/local/solr/tomcat/webapps/host-manager
十一月 20, 2018 5:23:25 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory /usr/local/solr/tomcat/webapps/manager
十一月 20, 2018 5:23:25 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-bio-8080"]
十一月 20, 2018 5:23:25 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["ajp-bio-8009"]
十一月 20, 2018 5:23:25 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 11144 ms
第六步:关闭tomcat后,删除掉没用的solr.war包
。原则:没用的东西及时删掉。
注意:要是想删掉没用的solr.war
包,必须在关闭tomcat的情况
下,否则解压缩后的solr包也会一并删除掉。
[root@itheima tomcat]# bin/shutdown.sh
Using CATALINA_BASE: /usr/local/solr/tomcat
Using CATALINA_HOME: /usr/local/solr/tomcat
Using CATALINA_TMPDIR: /usr/local/solr/tomcat/temp
Using JRE_HOME: /usr/local/java/jdk1.7.0_80/jre
Using CLASSPATH: /usr/local/solr/tomcat/bin/bootstrap.jar:/usr/local/solr/tomcat/bin/tomcat-juli.jar
[root@itheima tomcat]# rm -rf webapps/solr.war
第七步:想要启动solr工程
,还需要添加solr的扩展服务包
。
把/root/solr-4.10.3/example/lib/ext
目录下的所有的jar包,添加到solr工程
中。
[root@itheima ext]# pwd
/root/solr-4.10.3/example/lib/ext
[root@itheima ext]# cp * /usr/local/solr/tomcat/webapps/solr/WEB-INF/lib/
第八步:创建一个solrhome
目录。
我们知道:/root/solr-4.10.3/example/solr
目录就是一个solrhome
目录。
复制此目录中所有内容到/usr/local/solr/solrhome
目录下
[root@itheima example]# pwd
/root/solr-4.10.3/example
[root@itheima example]# cp -r solr /usr/local/solr/solrhome
第九步:关联solr工程
及solrhome
。需要修改solr工程
的web.xml
文件。
[root@itheima ~]# cd /usr/local/solr/tomcat/webapps/solr/WEB-INF/
[root@itheima WEB-INF]# vim web.xml
修改如下图所示:
第九步:再次启动tomcat
[root@itheima ~]# cd /usr/local/solr/tomcat/
[root@itheima tomcat]# bin/startup.sh
第十步:修改防火墙配置
CentOS 7.X 默认的防火墙不是iptables,而是firewalld。我们可以试一下systemctl stop firewalld关闭防火墙,但是不推荐该方式。
CentOS 6.X 是iptables,可以使用vim /etc/sysconfig/iptables
修改配置即可。
本博主的是CentOS7,防火墙使用的是firewalld,我们使用命令的方式来添加端口(修改后需要重启firewalld服务):
[root@itheima ~]# cd /etc/firewalld/zones/
[root@itheima zones]# firewall-cmd --permanent --add-port=8080/tcp
success
[root@itheima zones]# service firewalld restart
Redirecting to /bin/systemctl restart firewalld.service
[root@itheima zones]#
第十一步:测试连接
访问地址:http://192.168.25.154:8080/solr/
其实和在windows下的配置完全一样。
浏览器界面如下:
点击按钮“collection1”
添加文档时必须有id域
,其他域必须在solr的schema.xml
中进行定义。 1、商品id(根据id查询商品描述页(详情页))
2、商品标题title
3、商品卖点sell_point
4、商品价格price
5、商品图片image
6、分类名称category_name(不是分类id,我们一般不会根据商品分类id去查询商品,而是根据商品分类名称去查)
7、商品描述tb_item_desc(商品详情)(实际开发中不需要搜索商品描述(商品详情),为了练习需要,我们也把该表加入索引库)
一共涉及到三张表:tb_item、tb_item_cat、tb_item_desc。
创建对应的业务域。同时需要指定中文分析器。
第一步:把中文分析器添加到solr工程中。
0、把文件夹IK Analyzer 2012FF_hf1
上传至linux中。
1、把IKAnalyzer2012FF_u1.jar
拷贝到solr工程的lib目录
下。
2、把扩展词词典
、停用词字典
、配置文件
拷贝到solr工程的WEB-INF/classes
目录下。(没有classes目录就先创建该目录)
[root@itheima IK Analyzer 2012FF_hf1]# pwd
/root/IK Analyzer 2012FF_hf1
[root@itheima IK Analyzer 2012FF_hf1]# cp IKAnalyzer2012FF_u1.jar /usr/local/solr/tomcat/webapps/solr/WEB-INF/lib/
[root@itheima IK Analyzer 2012FF_hf1]# mkdir /usr/local/solr/tomcat/webapps/solr/WEB-INF/classes
[root@itheima IK Analyzer 2012FF_hf1]# cp mydict.dic ext_stopword.dic IKAnalyzer.cfg.xml /usr/local/solr/tomcat/webapps/solr/WEB-INF/classes
[root@itheima IK Analyzer 2012FF_hf1]# ll /usr/local/solr/tomcat/webapps/solr/WEB-INF/classes
总用量 12
-rw-r--r--. 1 root root 168 11月 20 19:29 ext_stopword.dic
-rw-r--r--. 1 root root 419 11月 20 19:29 IKAnalyzer.cfg.xml
-rw-r--r--. 1 root root 34 11月 20 19:29 mydict.dic
[root@itheima IK Analyzer 2012FF_hf1]#
第二步:配置一个自定义的fieldType
,使用指定的中文分词器IKAnalyzer
。
修改solr工程下的schema.xml
文件,在文件末尾添加一个自定义的fieldType
,注意:要在标签
里面添加。
[root@itheima conf]# pwd
/usr/local/solr/solrhome/collection1/conf
[root@itheima conf]# vim schema.xml
添加内容如下:
第三步:配置自定义业务域,type指定使用自定义的业务域类型fieldType。
设置自定义业务域的field
......
......
注意:分类名称是不分词只建立索引。商品描述是分词但是不存储。
第四步:重启tomcat,测试我们自定义的业务域是否好使。
测试结果如下:
taotao-search(聚合工程pom)
|–taotao-search-interface(jar)
|–taotao-search-service(war)
这里不再赘图了。
目录结构如下:
/taotao-search/pom.xml
<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.0modelVersion>
<parent>
<groupId>com.taotaogroupId>
<artifactId>taotao-parentartifactId>
<version>0.0.1-SNAPSHOTversion>
parent>
<artifactId>taotao-searchartifactId>
<packaging>pompackaging>
<modules>
<module>taotao-search-interfacemodule>
<module>taotao-search-servicemodule>
modules>
<dependencies>
<dependency>
<groupId>com.taotaogroupId>
<artifactId>taotao-commonartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<configuration>
<port>8084port>
<path>/path>
configuration>
plugin>
plugins>
build>
project>
/taotao-search-interface/pom.xml
<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.0modelVersion>
<parent>
<groupId>com.taotaogroupId>
<artifactId>taotao-searchartifactId>
<version>0.0.1-SNAPSHOTversion>
parent>
<artifactId>taotao-search-interfaceartifactId>
<dependencies>
<dependency>
<groupId>com.taotaogroupId>
<artifactId>taotao-manager-pojoartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
dependencies>
project>
/taotao-search-service/pom.xml
<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.0modelVersion>
<parent>
<groupId>com.taotaogroupId>
<artifactId>taotao-searchartifactId>
<version>0.0.1-SNAPSHOTversion>
parent>
<artifactId>taotao-search-serviceartifactId>
<packaging>warpackaging>
<dependencies>
<dependency>
<groupId>com.taotaogroupId>
<artifactId>taotao-manager-daoartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.taotaogroupId>
<artifactId>taotao-search-interfaceartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
<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>com.alibabagroupId>
<artifactId>dubboartifactId>
<exclusions>
<exclusion>
<artifactId>springartifactId>
<groupId>org.springframeworkgroupId>
exclusion>
<exclusion>
<artifactId>nettyartifactId>
<groupId>org.jboss.nettygroupId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
dependency>
<dependency>
<groupId>com.github.sgroschupfgroupId>
<artifactId>zkclientartifactId>
dependency>
dependencies>
project>
由于搜索的数据涉及到3张表,所以需要自己定义mapper。
而mapper的使用,只在搜索服务工程中,所以mapper接口及映射文件需要放在taotao-search-service工程中。
applicationContext-dao.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<context:property-placeholder location="classpath:properties/*.properties" />
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.taotao.mapper" />
bean>
beans>
其他配置文件,参考taotao-content-service的配置。
使用solrJ可以实现索引库的增删改查操作。
第一步:把solrJ的jar包添加到工程中。在Maven工程中则是添加依赖。
在/taotao-search-service/pom.xml添加对solrj客户端的依赖,如下:
<dependency>
<groupId>org.apache.solrgroupId>
<artifactId>solr-solrjartifactId>
dependency>
第二步:创建一个SolrServer对象(抽象类),使用HttpSolrServer创建对象(连接单机版solr),使用CloudSolrServer创建对象(连接集群版solr)。
第三步:创建一个文档对象SolrInputDocument对象。
第四步:向文档中添加域。必须有id域,且域的名称必须在schema.xml中定义。
第五步:把文档对象添加到索引库中。
第六步:提交。
测试代码如下:
/**
* 向索引库中添加索引
* @throws Exception
*/
@Test
public void addDocumentTest() throws Exception {
// 第一步:把solrJ的jar包添加到工程中。在Maven工程中则是添加依赖。
// 第二步:创建一个SolrServer对象(抽象类),使用HttpSolrServer创建连接对象(连接单机版solr),使用CloudSolrServer创建连接对象(连接集群版solr)。
SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 默认是collection1,可写可不写
// 第三步:创建一个文档对象SolrInputDocument对象。
SolrInputDocument document = new SolrInputDocument();
// 第四步:向文档中添加域。必须有id域,且域的名称必须在schema.xml已中定义。
document.addField("id", "test001"); // 注意:id是字符串类型,如果是数值类型,会自动转为字符串
document.addField("item_title", "测试商品");
document.addField("item_price", 1999);
// 第五步:把文档对象添加到索引库中。
solrServer.add(document);
// 第六步:提交。
solrServer.commit();
}
(1)根据指定ID来删除索引
/**
* 根据指定ID来删除索引
* @throws Exception
*/
@Test
public void deleteIndexByIdTest() throws Exception {
// 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。
HttpSolrServer server = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 参数:是solr服务器的访问地址
// 2、根据指定ID来删除索引
server.deleteById("test001");
// 3、提交。
server.commit();
}
(2)根据指定条件删除索引
/**
* 根据指定条件来删除索引
* @throws Exception
*/
@Test
public void deleteIndexByConditionTest() throws Exception {
// 1、创建HttpSolrServer对象,通过它和solr服务器建立连接。
HttpSolrServer server = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 参数:是solr服务器的访问地址
// 2、根据指定条件来删除索引
server.deleteByQuery("id:test002");
// 删除全部(慎用)
// server.deleteByQuery("*:*");
// 3、提交。
server.commit();
}
/**
* 简单查询
* @throws Exception
*/
@Test
public void queryIndexTest01() throws Exception {
// 1、创建SolrServer对象,通过它和solr服务器建立连接。
SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 参数:是solr服务器的访问地址
// 2、创建SolrQuery对象
SolrQuery query = new SolrQuery();
// 设置查询条件,名称"q"是固定的且必须的!
// query.set("q", "item_category_name:手机"); // 等价于 query.setQuery("item_category_name:手机");
query.setQuery("item_category_name:手机");
// 3、调用solrServer的查询方法,查询索引库
QueryResponse response = solrServer.query(query);
// 4、获取查询结果
SolrDocumentList results = response.getResults();
// 5、处理查询结果
System.out.println("查询结果总数为:" + results.getNumFound());
// 6、遍历结果并打印,示例只打印2个字段
for (SolrDocument solrDocument : results) {
System.out.println(solrDocument.get("id"));
System.out.println(solrDocument.get("item_title"));
System.out.println(solrDocument.get("item_price"));
System.out.println("--------------------");
}
}
/**
* 复杂查询
* @throws Exception
*/
@Test
public void queryIndexTest02() throws Exception {
// 1、创建SolrServer对象,通过它和solr服务器建立连接。
SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr/collection1"); // 参数:是solr服务器的访问地址
// 2、创建SolrQuery对象
SolrQuery query = new SolrQuery();
// 设置查询条件
// query.set("q", "item_category_name:手机");
query.setQuery("item_category_name:手机");
// 设置过滤条件,如果设置多个过滤条件的话,需要使用query.addFilterQuery(fq);
// query.setFilterQueries("item_price:[1 TO 20]");
// 设置排序
query.setSort("item_price", ORDER.desc);
// 设置分页信息(使用默认的)
query.setStart(0);
query.setRows(10);
// 设置显示的field的域集合
query.setFields("id,item_title,item_sell_point,item_price,item_image,item_category_name");
// 设置默认搜素域
query.set("df", "item_keywords");
// 设置高亮信息
query.setHighlight(true);
query.addHighlightField("item_title");
query.setHighlightSimplePre("");
query.setHighlightSimplePost("");
// 3、调用solrServer的查询方法,查询索引库
QueryResponse response = solrServer.query(query);
// 4、获取查询结果
SolrDocumentList results = response.getResults();
// 5、处理查询结果
System.out.println("查询结果总数为:" + results.getNumFound());
// 获取高亮列表
Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
// 遍历结果并打印,示例打印所有的字段
for (SolrDocument solrDocument : results) {
System.out.println(solrDocument.get("id"));
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_sell_point"));
System.out.println(solrDocument.get("item_price"));
System.out.println(solrDocument.get("item_image"));
System.out.println(solrDocument.get("item_category_name"));
System.out.println("--------------------");
}
}
在schema.xml中定义以下业务域(已经定义好):
1、商品id(根据id查询商品描述页)
2、商品标题title
3、商品卖点sell_point
4、商品价格price
5、商品图片image
6、分类名称category_name(不是分类id,我们一般不会根据商品分类id去查询商品,而是根据商品分类名称去查)
7、商品描述tb_item_desc(实际开发中不需要搜索商品描述(商品详情))
需要从 tb_item、tb_item_cat、tb_item_desc表中查询数据。
我们先创建对应的业务域(已经创建好了)。同时需要指定中文分析器。
solr服务我们已经搭建好了,自定义的业务域我们也配置好了,现在我们要实现商品搜素功能,那么就需要有数据,需要把数据从数据库中导入索引库,之前我们可以使用dataimportHandler插件
,该插件可以将数据库中指定的sql语句的结果导入到solr索引库中
。现在我们需要通过我们网站后台来管理索引库
,而不是通过dataimportHandler插件了,而且我们要做solr集群
的话,插件dataimportHandler会有干扰。所以我们现在不推荐使用dataimportHandler插件。
所以我们在测试环境
下可以使用dataimportHandler插件,但是生产环境
下需要我们手工导入数据。
插件dataimportHandler,使用参考链接:https://www.cnblogs.com/chenmingjun/p/9887696.html#_label2_3
我们使用手工导入数据,需要我们先从数据库中把我们分析出来的业务域取出来,取出来之后,循环插入索引库中去,由于涉及到3张表的查询(多表查询),所以不能在使用逆向工程生成的Mapper代码了。需要我们手写Mapper代码。我们先把SQL语句写出来,如下:
SQL1:
SELECT
a.id,
a.title,
a.sell_point,
a.price,
a.image,
b. NAME AS category_name,
c.item_desc
FROM
tb_item a
LEFT JOIN tb_item_cat b ON a.cid = b.id
LEFT JOIN tb_item_desc c ON a.id = c.item_id
WHERE
a.`status` = 1
SQL2:
SELECT
a.id,
a.title,
a.sell_point,
a.price,
a.image,
b. NAME AS 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;
创建以下POJO用于存放从数据库中查询到的商品数据
和用于存放从索引库中搜索到的商品数据
,并放入taotao-common中。
/**
* 搜索商品数据使用的POJO,用于存放“从数据库中查询到的商品数据”和用于存放“从索引库中搜索到的商品数据”
* @author chenmingjun
* @date 2018年11月21日上午1:05:12
* @version 1.0
*/
public class SearchItem implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // 商品的id,我们使用文档的id域作为商品的id,文档的id域默认定义的是String类型
private String title; // 商品的标题
private String sell_point; // 商品的卖点
private Long price; // 商品的价格
private String image; // 商品的图片路径
private String category_name; // 商品的分类名称
private String item_desc; // 商品的描述
// getter和setter方法
}
**注意:**在我们schema.xml文件中,我们使用文档的id域作为商品的id,而文档的id域默认定义的是String类型,索引库会自动转换将数值类型转换为字符串进行存储,我们从索引库中取出数据,我们也使用字符串进行接收。
SearchItemMapper.java
/**
* 搜索商品的Mapper
* @author chenmingjun
* @date 2018年11月21日上午11:23:28
* @version 1.0
*/
public interface SearchItemMapper {
/**
* 查询所有商品数据。(注意:是从3张表中查,此商品非彼商品)
* @return
*/
List<SearchItem> getSearchItemList();
}
SearchItemMapper.xml
<mapper namespace="com.taotao.search.mapper.SearchItemMapper" >
<select id="getSearchItemList" resultType="com.taotao.common.pojo.SearchItem">
SELECT
a.id,
a.title,
a.sell_point,
a.price,
a.image,
b. NAME AS category_name,
c.item_desc
FROM
tb_item a
LEFT JOIN tb_item_cat b ON a.cid = b.id
LEFT JOIN tb_item_desc c ON a.id = c.item_id
WHERE
a.`status` = 1
select>
mapper>
参数:无
业务逻辑:
1、查询所有商品数据。
2、创建一个SolrServer对象(抽象类),使用HttpSolrServer创建连接对象(连接单机版solr),使用CloudSolrServer创建连接对象(连接集群版solr)。
3、为每个商品创建一个文档对象SolrInputDocument对象。
4、为文档添加域。必须有id域,且域的名称必须在schema.xml中定义。
5、把文档对象添加到索引库中。
6、提交修改。
7、返回TaotaoResult。
SolrServer我们使用spring容器生成后注入进来,需要在配置文件进行配置:
applicationContext-solr.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
<constructor-arg name="baseURL" value="http://192.168.25.154:8080/solr/collection1">constructor-arg>
bean>
beans>
接口放在taotao-search-interface中
/**
* 从数据库中查询到数据导入索引库
* @author chenmingjun
* @date 2018年11月21日下午2:38:41
* @version 1.0
*/
public interface SearchItemService {
/**
* 导入搜索的商品数据到索引库中
* @return
* @throws Exception
*/
TaotaoResult importSearchItemsToIndex();
}
要想注入SearchItemMapper成功,需要在taotao-search-service
的applicationContext-dao.xml
文件中进行配置Mapper映射文件的包扫描器
:
有两种配置方式:
方式一:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.taotao.mapper" />
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.taotao.search.mapper" />
bean>
方式二:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.taotao.mapper,com.taotao.search.mapper" />
bean>
本案例中我们使用方式二。
实现类代码如下:
/**
* 从数据库中查询到数据导入索引库
* @author chenmingjun
* @date 2018年11月21日下午2:42:11
* @version 1.0
*/
@Service
public class SearchItemServiceImpl implements SearchItemService {
// 注入SearchItemMapper,要能注入进来,需要配置Mapper映射文件的包扫描器
@Autowired
private SearchItemMapper searchItemMapper;
// 注入SolrServer,要能注入进来,需要配置一个bean是SolrServer
@Autowired
private SolrServer solrServer;
@Override
public TaotaoResult importSearchItemsToIndex() {
try {
// 1、查询数据库中所有商品数据(此为新的商品数据)。
List<SearchItem> searchItemList = searchItemMapper.getSearchItemList();
// 2、创建一个SolrServer对象(抽象类),使用HttpSolrServer创建连接对象(连接单机版solr),使用CloudSolrServer创建连接对象(连接集群版solr)。
// SolrServer我们使用spring容器生成后注入进来
for (SearchItem searchItem : searchItemList) {
// 3、为每个商品创建一个文档对象SolrInputDocument对象。
SolrInputDocument document = new SolrInputDocument();
// 4、为文档添加域。必须有id域,且域的名称必须在schema.xml中定义。
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);
}
// 6、提交修改。
solrServer.commit();
} catch (Exception e) {
e.printStackTrace();
return TaotaoResult.build(500, "数据导入失败");
}
// 7、返回TaotaoResult,数据导入成功。
return TaotaoResult.ok();
}
}
**特别注意:
**由于我们的dubbo和zooKeeper是安装在虚拟机CentOS 7.5 上的,CentOS 7.X 默认的防火墙不是iptables,而是firewalld。我们可以试一下systemctl stop firewalld关闭防火墙,但是不推荐该方式。CentOS 6.X 是iptables,可以使用vim /etc/sysconfig/iptables
修改配置即可。
本博主的是CentOS7,防火墙使用的是firewalld,我们使用命令的方式来添加端口20882(修改后需要重启firewalld服务):
[root@itheima ~]# cd /etc/firewalld/zones/
[root@itheima zones]# firewall-cmd --permanent --add-port=20882/tcp
success
[root@itheima zones]# service firewalld restart
Redirecting to /bin/systemctl restart firewalld.service
[root@itheima zones]#
由于把从数据库中查询到的新的商品数据导入到索引库中
属于后台功能
,所以我们在taotao-manager-web中引用服务。
在/taotao-manager-web/src/main/resources/spring/springmvc.xml中引用服务:
在taotao-manager-web工程中的pom.xml中添加如下:
由于把从数据库中查询到的新的商品数据导入到索引库中
属于后台功能
,所以我们在taotao-manager-web
的后台系统中做一个导入索引库的功能界面
。(例如:有个按钮,点击即可将从数据库中查询到的数据导入到索引库)。
业务逻辑:
1、点击按钮,表现层调用服务层的工程的导入索引库的方法。
2、服务层实现调用Mapper接口的方法查询所有的商品的数据。
3、将数据一条条添加到SolrInputDocument文档中。
4、将文档添加到索引库中。
5、提交,并返回导入成功即可。
添加如下代码到index.jsp中:
<li>
<span>网站前台搜索管理span>
<ul>
<li data-options="attributes:{'url':'import-index'}">导入索引库li>
ul>
li>
在taotao-manager-web中创建一个import-index.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() {
// 移除原有按钮
$('.l-btn-text').remove("span");
// 追加不可点击按钮
$('.l-btn-left').after('');
$.post("/index/importAll",null,function(data) {
// 移除不可点击按钮
$('#disabledButton').remove("input");
// 追加原有按钮
$('.l-btn-left').after('一键导入商品数据到索引库');
if (data.status==200) {
$.messager.alert('提示','商品数据导入索引库成功!');
} else {
$.messager.alert('提示','商品数据导入索引库失败!');
}
});
}
script>
请求的url:/index/importall
参数:无
返回值:json数据。TaotaoResult。
/**
* 索引库维护Controller
* @author chenmingjun
* @date 2018年11月21日下午4:02:43
* @version 1.0
*/
@Controller
public class SearchItemController {
@Autowired
private SearchItemService searchItemService;
@RequestMapping("/index/importAll")
@ResponseBody
public TaotaoResult importSearchItemsToIndex() {
try {
TaotaoResult result = searchItemService.importSearchItemsToIndex();
return result;
} catch (Exception e) {
e.printStackTrace();
return TaotaoResult.build(500, "商品数据一键导入索引库失败!");
}
}
}
测试之前我们先将索引库中的测试数据清空,否则会对我们测试有影响,方法如下:
测试出错,原因是:未将工程中新建的映射文件SearchItemMapper.xml发布到classpath中。错误截图如下:
由于maven发布代码和配置文件时,在src/main/java
下,maven只会将*.java
文件编译成*.class
文件发布到classpath下,对于*.xml
文件等,maven是不会理会的,所以我们需要配置maven扫描src/main/java下的*.xml
文件。但是又不能影响maven扫描src/main/resources下面的*.xml、*.properties
文件,所以我们需要在taotao-search-service中这样配置:
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
build>
浏览器页面展示结果:
可以参考taotao-portal-web的创建。
打包方式war。
taotao-search-web。
这里不再赘图了。
<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.0modelVersion>
<parent>
<groupId>com.taotaogroupId>
<artifactId>taotao-parentartifactId>
<version>0.0.1-SNAPSHOTversion>
parent>
<artifactId>taotao-search-webartifactId>
<packaging>warpackaging>
<dependencies>
<dependency>
<groupId>com.taotaogroupId>
<artifactId>taotao-commonartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.taotaogroupId>
<artifactId>taotao-search-interfaceartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
<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>jstlgroupId>
<artifactId>jstlartifactId>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jsp-apiartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<exclusions>
<exclusion>
<artifactId>springartifactId>
<groupId>org.springframeworkgroupId>
exclusion>
<exclusion>
<artifactId>nettyartifactId>
<groupId>org.jboss.nettygroupId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
dependency>
<dependency>
<groupId>com.github.sgroschupfgroupId>
<artifactId>zkclientartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<configuration>
<port>8085port>
<path>/path>
configuration>
plugin>
plugins>
build>
project>
目录结构如下:
<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-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.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-4.2.xsd">
<context:property-placeholder location="classpath:resource/resource.properties"/>
<context:component-scan base-package="com.taotao.search.controller" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
bean>
<dubbo:application name="taotao-search-web"/>
<dubbo:registry protocol="zookeeper" address="192.168.25.128:2181"/>
beans>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>taotao-search-webdisplay-name>
<welcome-file-list>
<welcome-file>index.jspwelcome-file>
welcome-file-list>
<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>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>taotao-search-webservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring/springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>taotao-search-webservlet-name>
<url-pattern>*.htmlurl-pattern>
servlet-mapping>
web-app>
将上面的搜索结果静态页面放入到taotao-search-web工程中
在首页的搜索框
中输入搜索条件,然后跳转到搜索结果页面
。搜索结果页面在taotao-search-web工程中(端口为8085)。
首页搜索框的点击按钮处理函数在:在taotao-portal-web工程首页的JS中,应当改成8085,如图:
请求的url:/search
以搜索手机为例:http://localhost:8085/search.html?q=手机
参数:
1、q,表示查询条件。
2、page,页码。默认为1。每页显示多少行,我们在controller中写死即可。比如:60。
返回值: String。(包括:新的商品列表信息、总页数、总记录数、数据回显)
业务逻辑:
1、接收查询条件。
2、创建一个SolrServer对象,需要注入。
3、创建一个SolrQuery对象。
4、需要设置查询条件、分页条件、设置默认搜索域、高亮设置。
5、执行查询,返回QueryResponse对象。
6、取返回结果,封装到List中。
7、返回查询结果的总记录数,计算查询结果的总页数。
8、得到查询结果,渲染jsp
访问索引库的类。定义一些通用的数据访问方法。
业务逻辑就是查询索引库。
参数:SolrQuery对象
业务逻辑:
1、根据Query对象进行查询。
2、返回查询结果。包括List
、查询结果的总记录数。
需要把返回结果封装到pojo中,至少包含两个属性:List
、Long recordCount(总记录数)
,
再包含一个总页数(Long pageCount)。
创建如下SearchResult对象,放入taotao-common中。
SearchResult.java
package com.taotao.common.pojo;
import java.io.Serializable;
import java.util.List;
/**
* 商品搜索的分页信息结果对象
* @author chenmingjun
* @date 2018年11月21日下午11:33:14
* @version 1.0
*/
public class SearchResult implements Serializable {
private static final long serialVersionUID = 1L;
private List<SearchItem> itemList; // 搜索的结果列表(列表中放的是新的商品数据!不是之前的Item)
private Long recordCount; // 总记录数
private Long pageCount; // 总页数
public List<SearchItem> getItemList() {
return itemList;
}
public void setItemList(List<SearchItem> itemList) {
this.itemList = itemList;
}
public Long getRecordCount() {
return recordCount;
}
public void setRecordCount(Long recordCount) {
this.recordCount = recordCount;
}
public Long getPageCount() {
return pageCount;
}
public void setPageCount(Long pageCount) {
this.pageCount = pageCount;
}
}
在Dao层,查询索引库的方式和处理查询结果的方式都是一样的,查询索引库的参数是SolrQuery对象。
在服务层,我们拼装不同的查询条件SolrQuery即可。
因为搜索功能只在搜索工程中用到,所以可以不写接口,只写实现类。返回值:SearchResult。
我们这里是为了方便,但是在实际工作中,我们不能偷懒,一定要是一个接口对应至少一个实现类。
在taotao-search-service中创建com.taotao.search.dao包,在包中SearchDao创建用于访问索引库。
代码如下:
/**
* 因为搜索功能只在搜索工程中用到,所以可以不写接口,只写实现类。但是实际工作中不推荐。
* @author chenmingjun
* @date 2018年11月22日上午1:02:03
* @version 1.0
*/
@Repository // @Service也可以,只是我们把Dao和Service层写在一起了
public class SearchDaoImpl {
// 注入SolrServer
@Autowired
private SolrServer solrServer;
public SearchResult search(SolrQuery query) throws Exception {
// 1、根据SolrServer对象查询索引库
QueryResponse response = solrServer.query(query);
// 2、取出查询结果
SolrDocumentList solrDocumentList = response.getResults();
// 3、处理查询结果(即把取出的查询结果进行封装,即设置值)
SearchResult result = new SearchResult();
// 1) 取出总记录数放到SearchResult中去
Long recordCount = solrDocumentList.getNumFound();
result.setRecordCount(recordCount);
// 2) 取出新的商品列表放到SearchResult中去(注意:新的商品=>SearchItem,要与之前的商品Item区分开)
List<SearchItem> searchItemList = new ArrayList<>();
// 获取高亮列表
Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
for (SolrDocument solrDocument : solrDocumentList) {
SearchItem searchItem = new SearchItem();
searchItem.setId((String) solrDocument.get("id"));
searchItem.setSell_point((String) solrDocument.get("item_sell_point"));
searchItem.setPrice((Long) solrDocument.get("item_price"));
/*
// 取第一张图片地址存储进索引库
String image = (String) solrDocument.get("item_image");
if (StringUtils.isNotBlank(image)) {
image = image.split(",")[0];
}
searchItem.setImage(image);
*/
searchItem.setImage((String) solrDocument.get("item_image"));
searchItem.setCategory_name((String) solrDocument.get("item_category_name"));
// 取出高亮显示的内容
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");
}
searchItem.setTitle(itemTitle);
// 将新的商品添加到商品列表
searchItemList.add(searchItem);
}
// 将新的商品列表放到SearchResult中去
result.setItemList(searchItemList);
// 4、返回结果
return result;
}
}
参数:
queryString:查询条件
page:页码
rows:每页显示的记录数。
业务逻辑:
1、创建一个SolrQuery对象。
2、设置主查询条件。
3、设置分页条件。
4、需要指定默认的搜索域。
5、设置高亮。
6、执行查询,调用SearchDao。得到SearchResult
7、需要计算总页数。
8、返回SearchResult。
/**
* 网站前台根据搜索条件进行搜索
* @author chenmingjun
* @date 2018年11月21日下午2:38:41
* @version 1.0
*/
public interface SearchService {
/**
* 根据查询条件搜索
* @param queryString 页面传过来的查询条件
* @param page 页码
* @param rows 每页显示的记录数
* @return
*/
SearchResult search(String queryString, Integer page, Integer rows);
}
代码如下:
/**
* 网站前台搜索功能实现类
* @author chenmingjun
* @date 2019年1月2日
* @version V1.0
*/
public class SearchServiceImpl implements SearchService {
// 注入SearchDaoImpl
@Autowired
private SearchDaoImpl searchDaoImpl;
@Override
public SearchResult search(String queryString, Integer page, Integer rows) {
// 1、创建一个SolrQuery对象。
SolrQuery query = new SolrQuery();
// 2、设置主查询条件。
if (StringUtils.isNotBlank(queryString)) {
query.setQuery(queryString); // 按传递过来的条件进行查询
} else {
query.setQuery("*:*"); // 查询所有
}
// 3、设置过滤条件:分页、默认搜索域、高亮等等
// 1) 设置分页
if (page == null) {
page = 1;
}
if (rows == null) {
rows = 60;
}
query.setStart((page - 1) * rows);
query.setRows(rows);
// 2) 设置默认的搜索域
query.set("df", "item_title");
// 3) 设置高亮显示
query.setHighlight(true);
query.addHighlightField("item_title");
query.setHighlightSimplePre("");
query.setHighlightSimplePost("");
// 4、调用solr服务Dao的实现类方法,执行搜索,返回的是SearchResult,该返回值里面只包含了"总记录数"和"新的商品列表"
SearchResult result = null;
try {
result = searchDaoImpl.search(query);
// 5、设置总页数,需要先计算出总页数
Long recordCount = result.getRecordCount();
Long pageCount = recordCount / rows;
if (recordCount % rows > 0) {
pageCount++;
}
result.setPageCount(pageCount); // 把总页数设置到SearchResult
// 6、返回SearchResult
return result;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
在taotao-search-service工程applicationContext-service.xml文件中发布服务:
要想让扫描组件扫描到SearchDaoImpl,需要修改组件扫描的配置:
该功能在taotao-search-web中实现。
在taotao-search-web工程springmvc.xml文件中引用服务:
请求的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) {
// 1、引用服务
// 2、注入searchService
// 3、调用方法
// 对请求参数进行转码处理
try {
queryString = new String(queryString.getBytes("iso8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
SearchResult result = searchService.search(queryString, page, ITEM_ROWS);
// 4、设置数据传递到jsp中进行回显
model.addAttribute("query", queryString);
model.addAttribute("page", page);
model.addAttribute("totalPages", result.getPageCount());
model.addAttribute("itemList", result.getItemList());
// 5、返回逻辑视图:search.jsp
return "search";
}
}
搜索的结果页面中显示的每页的行数,我们查询到数据进行回显,每页显示多少条数据由我们决定。
文件存放在taotao-search-web中的resource目录下
还需要配置属性文件加载:在taotao-search-web的springmvc.xml中
1、测试发现有乱码,是GET请求乱码
,需要对get请求的参数进行转码处理:
方式一:在Controller中改
方式二:修改tomcat的配置文件,修改tomcat的默认字符集,但是我们使用的tomcat插件,根本不知道配置文件在哪!!!
对于方式二,如果是集群的话,会将该工程部署到不同的tomcat中,需要每一个tomcat都要改,麻烦,不推荐方式二!
2、翻页处理:在taotao-search-web工程中:
/taotao-search-web/src/main/webapp/js/search_main.js,修改如下:
数据库中保存的图片是以逗号分隔的url列表,我们显示只需要展示第一张图片即可。
方法1:
1、向索引库中添加(导入)文档时,只取第一张图片的地址写入索引库。
2、从文档列表转换为商品列表时可以取一张。
3、在jsp中对列表拆分,只取一张展示。
方法2:
可以在SearchItem中添加一个getImages()方法,用于页面获取经过处理的pojo的字段数据:
在jsp中取属性:
我的GitHub地址:https://github.com/heizemingjun
我的博客园地址:https://www.cnblogs.com/chenmingjun
我的蚂蚁笔记博客地址:https://blog.leanote.com/chenmingjun
Copyright ©2018~2019 黑泽君
【转载文章务必保留出处和署名,谢谢!】