1、maven配置
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>4.0.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>7.7.2</version>
</dependency>
2、application-solr.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/solr
https://www.springframework.org/schema/data/solr/spring-solr.xsd">
<solr:solr-client id="solrClient" url="${solr.url}" />
<solr:repositories base-package="com.zhi.demo.**.repository" />
<bean name="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg name="solrClient" ref="solrClient" />
<!-- 根据Indexed注解创建不存在的字段 -->
<property name="schemaCreationFeatures">
<list>
<value>CREATE_MISSING_FIELDS</value>
</list>
</property>
</bean>
</beans>
注意schemaCreationFeatures选择,如果有CREATE_MISSING_FIELDS选择,Spring会在启动时根据Indexed注解在solr中创建没定义的field。关键代码:
3、创建Bean
Dept.java
package com.zhi.demo.dept.model;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;
import org.springframework.data.solr.core.mapping.SolrDocument;
/**
* 部门信息,collection为对应的core名称,Indexed注解会自动在solr添加对应的field
*
* @author zhi
* @time 2016年12月22日09:55:08
*
*/
@SolrDocument(collection = "dept")
public class Dept {
/**
* 部门ID
*/
@Id
@Indexed
private String id;
/**
* 部门名称
*/
@Indexed(type = "text_ik")
private String name;
/**
* 创建时间
*/
@Indexed(name = "createTime", type = "pdate")
private Date createTime;
/**
* 备注
*/
@Indexed(type = "text_ik")
private String remark;
public Dept() {
super();
}
public Dept(String id, String name, Date createTime, String remark) {
super();
this.id = id;
this.name = name;
this.createTime = createTime;
this.remark = remark;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
知识兔View CodePerson.java
package com.zhi.demo.person.model;
import java.io.Serializable;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;
/**
* 人员信息
*
* @author 张远志
* @time 2016年12月22日09:55:42
*
*/
@SuppressWarnings("serial")
public class Person implements Serializable {
/**
* 主键
*/
@Id
@Indexed
private String id;
/**
* 人员名称
*/
@Indexed
private String name;
/**
* 地址
*/
@Indexed
private String addr;
/**
* 年龄
*/
private Integer age;
/**
* 部门ID
*/
private String deptId;
/**
* 是否可用
*/
private boolean usable;
/**
* 创建时间
*/
private Date createTime;
/**
* 备注
*/
private String remark;
public Person() {
super();
}
public Person(String id, String name, String addr, Integer age, String deptId, boolean usable, Date createTime,
String remark) {
super();
this.id = id;
this.name = name;
this.addr = addr;
this.age = age;
this.deptId = deptId;
this.usable = usable;
this.createTime = createTime;
this.remark = remark;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getDeptId() {
return deptId;
}
public void setDeptId(String deptId) {
this.deptId = deptId;
}
public boolean isUsable() {
return usable;
}
public void setUsable(boolean usable) {
this.usable = usable;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
知识兔View Code4、使用Repository方式进行CRUD操作
创建DeptRepository.java
package com.zhi.demo.dept.repository;
import java.util.List;
import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;
import com.zhi.demo.dept.model.Dept;
/**
* 部门增删改查操作
*
* @author zhi
* @since 2019年9月27日14:05:15
*
*/
public interface DeptRepository extends SolrCrudRepository<Dept, String> {
@Query("name:?0 OR remark:?0")
List<Dept> findList(String text);
}
知识兔View Code定义Dept操作接口和实现
package com.zhi.demo.dept.service;
import java.util.List;
import com.zhi.demo.dept.model.Dept;
/**
* 部门操作接口
*
* @author zhi
* @since 2019年9月27日13:12:26
*
*/
public interface IDeptService {
/**
* 保存
*
* @param model
* @return
*/
Dept save(Dept model);
/**
* 批量保存
*
* @param models
* @return
*/
List<Dept> saveBatch(List<Dept> models);
Dept findById(String id);
List<Dept> list(String text);
}
知识兔View Codepackage com.zhi.demo.dept.service.impl;
import java.util.List;
import java.util.Optional;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zhi.demo.dept.model.Dept;
import com.zhi.demo.dept.repository.DeptRepository;
import com.zhi.demo.dept.service.IDeptService;
/**
* 部门操作接口实现
*
* @author zhi
* @since 2019年9月27日13:12:26
*
*/
@Service
public class DeptServiceImpl implements IDeptService {
@Autowired
private DeptRepository deptRepository;
@Override
public Dept save(Dept model) {
deptRepository.save(model);
return model;
}
@Override
public List<Dept> saveBatch(List<Dept> models) {
deptRepository.saveAll(models);
return models;
}
@Override
public Dept findById(String id) {
Optional<Dept> optional = deptRepository.findById(id);
if (optional.isPresent()) {
return optional.get();
}
return null;
}
@Override
public List<Dept> list(String text) {
if (StringUtils.isEmpty(text)) {
return IteratorUtils.toList(deptRepository.findAll().iterator());
} else {
return deptRepository.findList(text);
}
}
}
知识兔View CodeJunit测试
package com.zhi.test;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.zhi.demo.dept.model.Dept;
import com.zhi.demo.dept.service.IDeptService;
/**
* Solr部门测试
*
* @author zhi
* @since 2019年9月29日15:06:06
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application.xml", "classpath*:application-*.xml" })
public class DeptTest {
private Logger logger = LogManager.getLogger(this.getClass());
@Autowired
private IDeptService deptService;
@Test
public void saveBatch() {
try {
deptService.saveBatch(ModelData.getDeptData());
logger.info("保存成功");
} catch (Exception e) {
logger.error("保存出错", e);
}
}
@Test
public void findOne() {
try {
Dept dept = deptService.findById("01");
if (dept == null) {
logger.info("根据ID未查询到记录");
} else {
logger.info("查询结果:id={},name={},remark{}", dept.getId(), dept.getName(), dept.getRemark());
}
} catch (Exception e) {
logger.error("查询出错", e);
}
}
@Test
public void list() {
try {
List<Dept> list = deptService.list("公司");
logger.info("查询到的数据长度:{}", list.size());
for (Dept dept : list) {
logger.info("id={},name={},remark{}", dept.getId(), dept.getName(), dept.getRemark());
}
} catch (Exception e) {
logger.error("查询出错", e);
}
}
}
知识兔View Code5、使用SolrTemplate进行CRUD删除
定义接口和实现
package com.zhi.demo.person.service;
import java.util.List;
import com.zhi.demo.person.model.Person;
/**
* 人员操作接口
*
* @author zhi
* @since 2019年9月27日11:33:31
*
*/
public interface IPersonService {
/**
* 保存人员,
*
* @param model
* @return
*/
Person save(Person model);
/**
* 批量保存人员
*
* @param models
* @return
*/
List<Person> saveBatch(List<Person> models);
/**
* 根据ID查询人员信息
*
* @param id
* @return
*/
Person findById(String id);
/**
* 根据关键字查询人员列表
*
* @param text 与name和addr字段匹配
* @return 列表长度由solr默认分页长度决定
*/
List<Person> list(String text);
/**
* 根据可用状态查找人员列表
*
* @param usable 与usable字段匹配
* @return 列表长度由solr默认分页长度决定
*/
List<Person> usable(Boolean usable);
}
知识兔View Codepackage com.zhi.demo.person.service.impl;
import java.time.Duration;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
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.SimpleStringCriteria;
import org.springframework.stereotype.Service;
import com.zhi.demo.person.model.Person;
import com.zhi.demo.person.service.IPersonService;
/**
* 人员操作接口实现
*
* @author zhi
* @since 2019年9月27日11:33:31
*
*/
@Service
public class PersonServiceImpl implements IPersonService {
@Autowired
private SolrTemplate solrTemplate;
@Override
public Person save(Person model) {
solrTemplate.saveBean("person", model);
solrTemplate.commit("person"); // 手工提交数据
return model;
}
@Override
public List<Person> saveBatch(List<Person> models) {
solrTemplate.saveBeans("person", models, Duration.ofSeconds(2)); // 自动提交
return models;
}
public Person findById(String id) {
Criteria criteria = new Criteria("id");
criteria.is(id);
Optional<Person> optional = solrTemplate.queryForObject("person", new SimpleQuery(criteria), Person.class);
return optional.isPresent() ? optional.get() : null;
}
@Override
public List<Person> list(String text) {
SimpleQuery query = new SimpleQuery();
if (!StringUtils.isEmpty(text)) {
Criteria criteria = new SimpleStringCriteria("name:" + text + " OR addr:" + text);
query.addCriteria(criteria);
}
Page<Person> page = solrTemplate.query("person", query, Person.class);
return page.getContent();
}
@Override
public List<Person> usable(Boolean usable) {
SimpleQuery query = new SimpleQuery();
if (usable != null) {
Criteria criteria = new Criteria("usable");
criteria.is(usable);
query.addCriteria(criteria);
}
Page<Person> page = solrTemplate.query("person", query, Person.class);
return page.getContent();
}
}
知识兔View CodeJunit测试
package com.zhi.test;
import java.util.Date;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.zhi.demo.person.model.Person;
import com.zhi.demo.person.service.IPersonService;
import com.zhi.demo.utils.TimerUtil;
/**
* Solr人员操作测试
*
* @author 张远志
* @since 2019年9月29日15:34:55
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application.xml", "classpath*:application-*.xml" })
public class PersonTest {
private Logger logger = LogManager.getLogger(this.getClass());
@Autowired
private IPersonService personService;
@Test
public void saveBatch() {
try {
personService.saveBatch(ModelData.getPersonData());
logger.info("保存成功");
} catch (Exception e) {
logger.error("保存出错", e);
}
}
@Test
public void findOne() {
try {
Person model = personService.findById("01");
if (model == null) {
logger.info("根据ID未查询到记录");
} else {
logger.info("查询结果:id={},name={},addr={}", model.getId(), model.getName(), model.getAddr());
}
} catch (Exception e) {
logger.error("查询出错", e);
}
}
@Test
public void list() {
try {
List<Person> list = personService.list("武汉");
logger.info("查询到的数据长度:{}", list.size());
for (Person item : list) {
logger.info("id={},name={},addr={}", item.getId(), item.getName(), item.getAddr());
}
} catch (Exception e) {
logger.error("查询出错", e);
}
}
@Test
public void usable() {
try {
List<Person> list = personService.usable(false);
logger.info("查询到的数据长度:{}", list.size());
for (Person item : list) {
logger.info("id={},name={},addr={}", item.getId(), item.getName(), item.getAddr());
}
} catch (Exception e) {
logger.error("查询出错", e);
}
}
@Test
public void pressure() {
Date start = new Date();
for (int i = 0; i < 10000; i++) {
personService.list("武汉");
}
logger.info(TimerUtil.format(start));
}
}
知识兔View Code