在我的Spring Data Solr教程的上一部分中,我们学习了如何配置Spring Data Solr。 现在该迈出一步,了解我们如何管理Solr实例中存储的信息。 此博客文章描述了我们如何向Solr索引添加新文档,如何更新现有文档的信息以及如何从索引中删除文档。
通过执行以下步骤,我们可以对示例应用程序进行必要的修改:
- 创建一个文档类,其中包含存储在Solr索引中的信息。
- 为我们的Spring Data Solr存储库创建一个存储库接口。
- 创建一个使用创建的存储库的服务。
- 使用创建的服务。
以下各节将更详细地描述这些步骤。
注意 :这些博客条目提供了其他信息,可帮助我们理解此博客条目中描述的概念:
创建文档类
第一步是创建一个文档类,其中包含添加到Solr索引中的信息。 文档类基本上只是一个POJO,它通过遵循以下规则来实现:
- @Field批注用于在POJO的字段和Solr文档的字段之间创建链接。
- 如果Bean的字段名称与文档的字段名称不同,则必须以@Field批注的值给出文档的字段名称。
- @Field批注可以应用于字段或setter方法。
- Spring Data Solr默认情况下假设文档的id字段的名称为'id'。 我们可以通过使用@Id注释对id字段进行注释来覆盖此设置。
- Spring Data Solr(版本1.0.0.RC1)要求文档ID的类型为String 。
更多信息 :
让我们继续创建我们的文档类。
在我的Spring Data Solr教程的第一部分中,我们了解到必须将每个todo条目的id , 描述和标题存储到Solr索引中。
因此,我们可以按照以下步骤为待办事项创建文档类:
- 创建一个名为TodoDocument的类。
- id字段添加到TodoDocument类,并与@Field注解注释字段。 用@Id注释对字段进行注释(由于id字段的名称为'id',所以这不是必需的,但我想在此处演示其用法)。
- 说明字段添加到TodoDocument类,并与@Field注解注释这一领域。
- 标题字段添加到TodoDocument并与@Field注解注释这一领域。
- 在TodoDocument类的字段中创建getter方法。
- 创建一个静态内部类,该内部类用于构建新的TodoDocument对象。
- 将静态getBuilder()方法添加到TodoDocument类。 此方法的实现返回一个新的TodoDocument.Builder对象。
TodoDocument类的源代码如下所示:
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;
public class TodoDocument {
@Id
@Field
private String id;
@Field
private String description;
@Field
private String title;
public TodoDocument() {
}
public static Builder getBuilder(Long id, String title) {
return new Builder(id, title);
}
//Getters are omitted
public static class Builder {
private TodoDocument build;
public Builder(Long id, String title) {
build = new TodoDocument();
build.id = id.toString();
build.title = title;
}
public Builder description(String description) {
build.description = description;
return this;
}
public TodoDocument build() {
return build;
}
}
}
创建存储库界面
Spring Data Solr存储库的基本接口是SolrCrudRepository <T,ID>接口,每个存储库接口都必须扩展此接口。
当扩展SolrCrudRepository <T,ID>接口时,我们必须提供两个类型参数,下面将对其进行描述:
- T type参数表示我们的文档类的类型。
- ID类型参数表示文档ID的类型。 Spring Data Solr(版本1.0.0.RC1)要求文档的ID为String 。
我们可以按照以下步骤创建存储库接口:
- 创建一个名为TodoDocumentRepository的接口。
- 扩展SolrCrudRepository接口,并提供我们的文档类的类型及其ID作为类型参数。
TodoDocumentRepository接口的源代码如下所示:
import org.springframework.data.solr.repository.SolrCrudRepository;
public interface TodoDocumentRepository extends SolrCrudRepository<TodoDocument, String> {
}
创建服务
下一步是创建使用已创建的Solr存储库的服务。 我们可以按照以下步骤创建此服务:
- 创建服务接口。
- 实现创建的接口。
下面将更详细地描述这些步骤。
创建服务接口
我们的服务接口声明了以下两种方法:
- void addToIndex(Todo todoEntry)方法将todo条目添加到索引。
- void deleteFromIndex(Long id)方法从索引中删除待办事项。
注意:我们可以使用addToIndex()方法将新的待办事项添加到Solr索引中,并更新现有待办事项的信息。 如果现有文档的ID与新文档的ID相同,则将删除旧文档,并将新文档的信息保存到Solr索引(有关更多详细信息 ,请参见SchemaXML @ Solr Wiki )。
TodoIndexService接口的源代码如下所示:
public interface TodoIndexService {
public void addToIndex(Todo todoEntry);
public void deleteFromIndex(Long id);
}
实施创建的接口
通过执行以下步骤,我们可以实现服务接口:
- 创建我们的服务类的框架实现。
- 实现用于将文档添加到Solr索引的方法。
- 实现用于从Solr索引中删除文档的方法。
下面将更详细地描述这些步骤。
创建服务类的框架实现
通过执行以下步骤,我们可以创建服务接口的框架实现:
- 创建一个名为RepositoryTodoIndexService的类,并使用@Service注释对该类进行注释。 该注释将该类标记为服务,并确保在类路径扫描期间将检测到该类。
- 将TodoDocumentRepository字段添加到RepositoryTodoIndexService类,并使用@Resource注释对该字段进行注释。 该注释指示Spring IoC容器将实际的存储库实现注入服务的存储库字段。
我们的虚拟服务实现的源代码如下所示:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service
public class RepositoryTodoIndexService implements TodoIndexService {
@Resource
private TodoDocumentRepository repository;
//Add methods here
}
将文档添加到Solr索引
我们可以按照以下步骤创建将新文档添加到Solr索引的方法:
- 将addToIndex()方法添加到RepositoryTodoIndexService类中,并使用@Transactional注释对该方法进行注释。 这确保了我们的Spring Data Solr存储库将参与Spring托管的事务 。
- 通过使用生成器模式创建一个新的TodoDocument对象。 设置创建的文档的id , 标题和描述 。
- 通过调用TodoDocumentRepository接口的save()方法将文档添加到Solr索引中。
创建的方法的源代码如下所示:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service
public class RepositoryTodoIndexService implements TodoIndexService {
@Resource
private TodoDocumentRepository repository;
@Transactional
@Override
public void addToIndex(Todo todoEntry) {
TodoDocument document = TodoDocument.getBuilder(todoEntry.getId(), todoEntry.getTitle())
.description(todoEntry.getDescription())
.build();
repository.save(document);
}
//Add deleteFromIndex() method here
}
从Solr索引中删除文档
我们可以按照以下步骤创建一种从Solr索引中删除文档的方法:
- 将deleteFromIndex()方法添加到RepositoryTodoDocumentService类,并使用@Transactional注释对该方法进行注释。 这确保了我们的Spring Data Solr存储库将参与Spring托管的事务 。
- 通过调用TodoDocumentRepository接口的delete()方法从Solr索引中删除文档。
创建的方法的源代码如下所示:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service
public class RepositoryTodoIndexService implements TodoIndexService {
@Resource
private TodoDocumentRepository repository;
//Add addToIndex() method here
@Transactional
@Override
public void deleteFromIndex(Long id) {
repository.delete(id.toString());
}
}
使用创建的服务
我们的最后一步是使用我们先前创建的服务。 我们可以通过对RepositoryTodoService类进行以下修改来做到这一点:
- 将TodoIndexService字段添加到RepositoryTodoService类,并使用@Resource注释对该字段进行注释。 该注释指示Spring IoC容器将创建的RepositoryTodoIndexService对象注入到服务的indexService字段中。
- 调用在RepositoryTodoService类的add()方法的TodoIndexService接口的addToIndex()方法。
- 调用在RepositoryTodoService类的deleteById()方法TodoIndexService接口的deleteFromIndex()方法。
- 调用在RepositoryTodoService类的update()方法的TodoIndexService接口的addToIndex()方法。
RepositoryTodoService的源代码如下所示:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
@Service
public class RepositoryTodoService implements TodoService {
@Resource
private TodoIndexService indexService;
@Resource
private TodoRepository repository;
@PreAuthorize("hasPermission('Todo', 'add')")
@Transactional
@Override
public Todo add(TodoDTO added) {
Todo model = Todo.getBuilder(added.getTitle())
.description(added.getDescription())
.build();
Todo persisted = repository.save(model);
indexService.addToIndex(persisted);
return persisted;
}
@PreAuthorize("hasPermission('Todo', 'delete')")
@Transactional(rollbackFor = {TodoNotFoundException.class})
@Override
public Todo deleteById(Long id) throws TodoNotFoundException {
Todo deleted = findById(id);
repository.delete(deleted);
indexService.deleteFromIndex(id);
return deleted;
}
@PreAuthorize("hasPermission('Todo', 'update')")
@Transactional(rollbackFor = {TodoNotFoundException.class})
@Override
public Todo update(TodoDTO updated) throws TodoNotFoundException {
Todo model = findById(updated.getId());
model.update(updated.getDescription(), updated.getTitle());
indexService.addToIndex(model);
return model;
}
}
摘要
我们已经成功创建了一个将文档添加到Solr索引并从中删除文档的应用程序。 这篇博客文章告诉我们以下内容:
- 我们了解了如何创建文档类。
- 我们了解到,可以通过扩展SolrCrudRepository接口来创建Spring Data Solr存储库。
- 我们了解到,Spring Data Solr默认情况下假设文档的id字段的名称为'id'。 但是,我们可以通过使用@Id注释对id字段进行注释来覆盖此设置。
- 我们了解到,目前Spring Data Solr(版本1.0.0.RC1)期望文档的ID为String 。
- 我们了解了如何将文档添加到Solr索引并从中删除文档。
- 我们了解到,Spring Data Solr存储库可以参与Spring托管的事务。
我的Spring Data Solr教程的下一部分描述了如何使用查询方法从Solr索引中搜索信息 。
PS此博客条目的示例应用程序可从Github获得 。
翻译自: https://www.javacodegeeks.com/2013/05/spring-data-solr-tutorial-crud-almost.html