依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
属性文件
# 应用名称
spring.application.name=mysolr
# 应用服务 WEB 访问端口
server.port=8080
#solr服务器
spring.data.solr.host=http://169.254.140.100:8983/solr/solrhome
业务类
package com.hr.mysolr.service.impl;
import com.hr.mysolr.entity.Product;
import com.hr.mysolr.service.ProductService;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @Classname ProductServiceImpl
* @Description TODO
* @Date 2022-02-18 8:37
* @Created by 汤永红
*/
@Service
public class ProductServiceImpl implements ProductService {
//1.创建Solr客户端, 为了查询query
@Resource
private SolrClient solrClient;
@Override
public List<Product> seachSolr(String field, String keywords, int start, int end) throws Exception {
//2.创建查询条件
SolrQuery query = new SolrQuery();
query.setQuery(field + ":" + keywords);// q 查询条件
query.setHighlight(true);//打开高亮
query.setParam("hl.fl", field);//必须写!!!
query.addFacetField(field);
query.setHighlightSimplePre("<span style='color:red;'>");//设置前缀
query.setHighlightSimplePost("</span>");//设置后缀
query.setQuery(field + ":" + keywords);// q 查询条件
//3.执行
QueryResponse queryResponse = solrClient.query(query);
//将下面带高亮的内容替换掉上面的
//4.得到结果集
SolrDocumentList results = queryResponse.getResults();
//5.得到高亮
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
//6.如果有结果,并且有数据,就装
List<Product> products = new ArrayList<>();
if (results != null && results.getNumFound() > 0) {
for (SolrDocument doc : results) {
//把doc中的内容拿出来放到Product中----可用工具类中的方法代替-----
Product product = new Product();
product.setPid(Integer.parseInt(doc.get("id") + ""));
product.setName(doc.get("product_name") + "");
product.setCatalog(Integer.parseInt(doc.get("product_catalog") + ""));
product.setCatalog_name(doc.get("product_catalog_name") + "");
product.setPrice(Double.parseDouble(doc.get("product_price") + ""));
product.setDescription(doc.get("product_description") + "");
product.setPicture(doc.get("product_picture") + "");
//---------------------------------------------------------------
//拿高亮的内容
String key = doc.getFieldValue("id") + "";
Map<String, List<String>> map = highlighting.get(key);
List<String> value = map.get(field);
String highlightingField = "";
if (value != null && value.size() > 0) {
highlightingField = value.get(0);
}
product.setName(highlightingField);
products.add(product);
product = null;
}
}
return products;
}
}
package com.hr.mysolr.web;
import com.hr.mysolr.entity.Product;
import com.hr.mysolr.service.ProductService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
/**
* @Classname ProductController
* @Description TODO
* @Date 2022-02-18 9:38
* @Created by 汤永红
*/
@Controller
@RequestMapping("/")
public class ProductController {
@Resource
private ProductService productService;
@RequestMapping("/query")
@ResponseBody
public List<Product> query(@RequestParam("name") String name, @RequestParam("keyWord") String keyWord) {
List<Product> products = null;
try {
products = productService.seachSolr(name, keyWord, 0, 10);
} catch (Exception e) {
e.printStackTrace();
}
return products;
}
先测试Web
再用Vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>显示</title>
<style>
table, th, tr, td {
border: 1px solid red;
border-collapse: collapse;
}
</style>
<script src="js/axios.min.js"></script>
<script src="js/jquery.js"></script>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<table>
<tr>
<th>流水号</th>
<th>product_name</th>
<th>操作</th>
</tr>
<tr v-for="(pro,index) in dataProduct">
<td>{{index}}</td>
<td>
<div v-html="pro.name"></div>
</td>
<td>编号|删除</td>
</tr>
</table>
<script>
new Vue({
el: '#app',
data: {
dataProduct: []
}, methods: {
findAll() {
var url = 'http://localhost:8080/query?name=product_name&keyWord=%E6%B0%B4%E6%99%B6%E7%90%83';
axios.get(url).then(res => {
this.dataProduct = res.data;
})
}
}, created() {
this.findAll();
}
});
</script>
</div>
</body>
</html>
效果
工具类(实体和数据库列一致)
package com.example.demo.util;
import org.apache.solr.common.SolrDocument;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
class MyUtil {
/**
* SolrDocument与实体类转换
*
* @param document SolrDocument对象
* @param clzz 泛型类
* @return <T>
*/
public static <T> T solrDocumentToPojo(SolrDocument document, Class<T> clzz) {
if (null != document) {
try {
Object obj = clzz.newInstance();
Method m = null;
Class<?> fieldType = null;
for (String fieldName : document.getFieldNames()) {
//需要说明的是返回的结果集中的FieldNames()比类属性多
Field[] filedArrays = clzz.getDeclaredFields(); //获取类中所有属性
for (Field f : filedArrays) {
//如果实体属性名和查询返回集中的字段名一致,填充对应的set方法
/*if(fieldName.equals("_id")){
fieldName="id";
}*/
if (f.getName().equals(fieldName)) {
//获取到的属性名
f = clzz.getDeclaredField(fieldName);
//属性类型
fieldType = f.getType();
//构造set方法名 setId
String dynamicSetMethod = dynamicMethodName(f.getName(), "set");
//获取方法
m = clzz.getMethod(dynamicSetMethod, fieldType);
//获取到的值
// 如果是 int, float等基本类型,则需要转型
if (fieldType.equals(Integer.TYPE)) {
fieldType = Integer.class;
} else if (fieldType.equals(Float.TYPE)) {
fieldType = Float.class;
} else if (fieldType.equals(Double.TYPE)) {
fieldType = Double.class;
} else if (fieldType.equals(Boolean.TYPE)) {
fieldType = Boolean.class;
} else if (fieldType.equals(Short.TYPE)) {
fieldType = Short.class;
} else if (fieldType.equals(Long.TYPE)) {
fieldType = Long.class;
} else if (fieldType.equals(String.class)) {
fieldType = String.class;
} else if (fieldType.equals(Collection.class)) {
fieldType = Collection.class;
}
m.invoke(obj, fieldType.cast(document.getFieldValue(fieldName)));
}
}
}
return clzz.cast(obj);
} catch (ClassCastException e) {
// 请检查schema.xml中的各个field的数据类型与PO类的是否一致
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
//请检查PO类中的field对应的各个setter和getter是否存在
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
//请检查schema中的field是否不存在于PO类中
e.printStackTrace();
}
}
return null;
}
//动态构造getXxx setXxx
public static String dynamicMethodName(String name, String setOrGet) {
String setMethodName = setOrGet
+ name.substring(0, 1).toUpperCase()
+ name.substring(1);
return setMethodName;
}
}