导入solr索引库需要先在Linux中安装solr并且配置solr
这是在Linux中配置solr的详细步骤地址
模块划分
SearchItemServiceImpl.java代码实现
/**
* 商品数据索引库Service
*/
@Service
public class SearchItemServiceImpl implements SearchItemService {
@Autowired
private ItemMapper itemMapper;
@Autowired
private SolrServer solrServer;
/**
* 将删商品数据导入索引库
* @return
*/
@Override
public E3Result importItems() {
try {
//查询商品列表
List<SearchItem> itemList = itemMapper.getItemList();
//导入到索引库
for (SearchItem item :itemList) {
//创建文档对象
SolrInputDocument document=new SolrInputDocument();
//向文档添加域
document.addField("id",item.getId());
document.addField("item_title",item.getTitle());
document.addField("item_sell_point",item.getSell_point());
document.addField("item_price",item.getPrice());
document.addField("item_image",item.getImage());
document.addField("item_category_name",item.getCategory_name());
//写入索引库
solrServer.add(document);
}
//提交
solrServer.commit();
//返回成功
return E3Result.ok();
}catch (Exception e){
e.printStackTrace();
return E3Result.build(500,"商品导入失败!");
}
}
}
Controller代码
/**
* solr导入
*/
@Controller
public class SearchItemController {
@Autowired
private SearchItemService searchItemService;
@RequestMapping("/index/item/import")
@ResponseBody
public E3Result importItemList(){
E3Result result = searchItemService.importItems();
return result;
}
然而我们在添加商品的时候solr库没有添加到该商品的索引,导致我们在搜索时搜索不到该商品的信息,想要同步只有每次添加一个商品,我们就只有去调用点击后台的一键导入solr库才可以将该商品添加到solr库中。这样就感觉很麻烦而且效率非常的低,可用性较差。我们就可以使用activemq消息的方式来解决该方法实现自动同步的效果。每次添加一个商品发送一个消息在添加该商品的信息到solr库中。
实现功能的代码。
需要修改其中商品管理模块的步骤
添加一个applicationConten-activemq.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.128:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!-- 配置生产者 -->
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!--这个是队列目的地,点对点的 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>spring-queue</value>
</constructor-arg>
</bean>
<!--这个是主题目的地,一对多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="itemAddTopic" />
</bean>
</beans>
2.修改添加实现类中的方法在插入商品信息到数据库中的时候我们就发送一个消息
//发送一个商品添加信息
jmsTemplate.send(topicDestination, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
//设置消息内容为商品id值需要转换一下类型为字符串
TextMessage textMessage = session.createTextMessage(itemId+"");
return textMessage;
}
});
搜索模块
添加一个监听器监听随时监听随时接收消息
ItemAddMessageListener.java
/**
* 监听添加商品信息,接收消息后,向索引库中添加相应的索引(同步)
*/
public class ItemAddMessageListener implements MessageListener {
@Autowired
private ItemMapper itemMapper;
@Autowired
private SolrServer solrServer;
@Override
public void onMessage(Message message) {
try {
//从消息中取出商品id
TextMessage textMessage= (TextMessage) message;
//取出消息中的信息
String text=textMessage.getText();
//将取出的信息类型转换成商品id的类型
Long id= Long.valueOf(text);
//解决事物没有提交然而消息先到了然后就去数据库中查询数据,
// 发生找不到数据的错误所以我们在这里选择等待一会等待事物提交成功后我们在去查避免查不到数据
Thread.sleep(1000);
//根据商品id取商品信息
SearchItem searchItem = itemMapper.getItemById(id);
//创建一个文档对象
SolrInputDocument document = new SolrInputDocument();
//向文档对象中添加域
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());
//将文档导入到索引库中
solrServer.add(document);
//提交
solrServer.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
添加applicationConten-activemq.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.128:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!--这个是队列目的地,点对点的 -->
<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg>
<value>spring-queue</value>
</constructor-arg>
</bean>
<!--这个是主题目的地,一对多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="itemAddTopic" />
</bean>
<!-- 接收消息 -->
<!-- 配置监听器 -->
<bean id="myMessageListener" class="com.e3mall.search.activemq.listener.MyMessageListener" />
<!-- 消息监听容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueDestination" />
<property name="messageListener" ref="myMessageListener" />
</bean>
<!-- 配置监听器 -->
<bean id="itemAddMessageListener" class="com.e3mall.search.activemq.listener.ItemAddMessageListener" />
<!-- 消息监听容器监听商品添加消息同步索引库 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<!--设置我需要的发送消息方式-->
<property name="destination" ref="topicDestination" />
<property name="messageListener" ref="itemAddMessageListener" />
</bean>
</beans>
applicationContent-service.xml发布服务