我的Spring Data Solr教程的前一部分教我们如何使用查询方法创建静态查询。 自然而然的下一步将是描述如何使用Spring Data Solr创建动态查询。 但是,在继续讨论该主题之前,我们必须了解如何将自定义方法添加到单个存储库。 这篇博客文章将帮助我们了解如何完成。 在此博客条目期间,我们将修改示例应用程序 ,以使用称为部分更新的技术将todo条目的信息更新为Solr索引。 让我们从仔细研究Solr的部分更新功能开始。
注意:这些博客条目提供了其他信息,有助于我们理解此博客条目中描述的概念:
- 使用Maven运行Solr
- Spring Data Solr教程:Solr简介
- Spring Data Solr教程:配置
- Spring Data Solr教程CRUD(几乎)
什么是部分更新?
Solr 4.0中引入了部分更新功能,它使我们可以选择要更新的字段。 如果索引整个文档的内容很慢,这将非常有用。
但是,部分更新功能有其局限性。 如果要使用部分更新功能,则必须存储文档的所有字段,这会增加Solr索引的大小。 这样做的原因是不可能对Lucene索引进行部分更新。 Lucene总是在索引新文档之前删除旧文档。 这意味着,如果不存储未更新的字段,则在对文档进行部分更新时,这些字段的值会丢失。
决定哪个对我们更重要是我们的工作:速度或索引的大小。
通过查看以下资源,我们可以获得有关部分更新的更多信息:
- Solr 4.0:部分文档更新
- Solr –文档的部分更新@ StackOverflow
- Solr –将新字段更新为现有文档@ StackOverflow
让我们继续学习如何将自定义方法添加到单个Spring Data Solr存储库中。
将自定义方法添加到单个存储库
我们可以按照以下步骤将自定义方法添加到单个存储库中:
- 创建一个自定义接口,该接口声明自定义方法。
- 实现自定义界面。
- 修改存储库接口以扩展定制接口。
在以下小节中将更详细地描述这些步骤。
创建自定义界面
首先,我们必须创建一个接口并在其中声明自定义方法。 我们可以按照以下步骤进行操作:
- 创建一个名为PartialUpdateRepository的接口。
- 声明自定义方法。
因为我们只需要声明一个用于更新待办事项信息的自定义方法,所以PartialUpdateRepository接口的源代码如下所示:
public interface PartialUpdateRepository {public void update(Todo todoEntry);
}
实施自定义界面
其次,我们必须实现PartialUpdateRepository接口。 存储库基础结构尝试使用以下规则自动检测实现自定义存储库接口的类:
- 必须从与定制接口相同的包中找到定制存储库接口的实现。
- 必须使用以下公式来创建实现自定义存储库接口的类的名称 : [实际存储库接口的名称] [存储库实现后缀] 。
存储库实现后缀的默认值为“ Impl”。 我们可以使用以下方法之一覆盖默认值:
- 如果使用Java配置,则可以通过将首选后缀设置为@EnableSolrRepositories批注的repositoryImplementationPostfix属性的值来配置使用的后缀。
- 如果使用XML配置,则可以通过将首选postfix设置为repository名称空间元素的repository-impl-postfix属性的值来配置使用的postfix。
此博客条目的示例应用程序使用默认配置。 因此,我们可以按照以下步骤实现PartialUpdateRepository接口:
- 创建一个名为TodoDocumentRepositoryImpl的类。
- 用@Repository批注对类进行批注。
- 将SolrTemplate字段添加到类中,并使用@Resource注释对该字段进行注释。
- 实现update()方法。
让我们仔细看看update()方法的实现。 我们可以通过执行以下步骤来实现此方法:
- 创建一个新的PartialUpdate对象。 将文档的id字段的名称及其值设置为构造函数参数。
- 将已更新字段的名称和值设置为创建的对象。
- 通过调用SolrTemplate类的saveBean()方法进行部分更新。
- 通过调用SolrTemplate类的commit()方法来提交更改。
TodoRepositoryImpl类的源代码如下所示:
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.PartialUpdate;
import org.springframework.stereotype.Repository;import javax.annotation.Resource;@Repository
public class TodoDocumentRepositoryImpl implements PartialUpdateRepository {@Resourceprivate SolrTemplate solrTemplate;@Overridepublic void update(Todo todoEntry) {PartialUpdate update = new PartialUpdate("id", todoEntry.getId().toString());update.add("description", todoEntry.getDescription());update.add("title", todoEntry.getTitle());solrTemplate.saveBean(update);solrTemplate.commit();}
}
修改存储库界面
通过扩展PartialUpdateRepository接口,我们可以使自定义update()方法对存储库的用户可见。 TodoDocumentRepository接口的源代码如下所示:
import org.springframework.data.solr.repository.SolrCrudRepository;public interface TodoDocumentRepository extends PartialUpdateRepository, SolrCrudRepository<TodoDocument, String> {//Query methods are omitted.
}
让我们继续前进,了解如何使用我们的新存储库方法。
使用自定义方法
我们可以通过对示例应用程序进行以下更改来使用自定义update()方法:
- 将update()方法添加到TodoIndexService接口。
- 实现update()方法。
- 修改RepositoryTodoService类的update()方法以使用新方法。
在以下小节中将更详细地描述这些步骤。
向TodoIndexService接口添加新方法
我们记得, TodoIndexRepository接口声明了一些方法,这些方法用于向Solr索引添加信息,从Solr索引中搜索信息并从索引中删除文档。
我们必须向该接口添加新方法。 此方法称为update() ,它将更新的Todo对象作为方法参数。 TodoIndexRepository接口的源代码如下所示:
public interface TodoIndexService {//Other methods are omitted.public void update(Todo todoEntry);
}
实施添加的方法
通过执行以下步骤,我们可以实现TodoIndexService接口的update()方法:
- 将update()方法添加到RepositoryIndexService类,并使用@Transactional注释对方法进行注释。 这确保了我们的Spring Data Solr存储库将参与Spring托管的事务 。
- 调用update()存储库方法,并将更新的Todo对象作为方法参数传递。
RepositoryTodoIndexService类的源代码如下所示:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;@Service
public class RepositoryTodoIndexService implements TodoIndexService {@Resourceprivate TodoDocumentRepository repository;//Other fields and methods are omitted.@Transactional@Overridepublic void update(Todo todoEntry) {repository.update(todoEntry);}
}
修改RepositoryTodoService类
我们的最后一步是修改RepositoryTodoService类的update()方法,以使用在TodoIndexService接口中声明的新update()方法。 RepositoryTodoService类的相关部分如下所示:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;@Service
public class RepositoryTodoService implements TodoService {@Resourceprivate TodoIndexService indexService;@Resourceprivate TodoRepository repository;//Other methods are omitted.@PreAuthorize("hasPermission('Todo', 'update')")@Transactional(rollbackFor = {TodoNotFoundException.class})@Overridepublic Todo update(TodoDTO updated) throws TodoNotFoundException {Todo model = findById(updated.getId());model.update(updated.getDescription(), updated.getTitle());indexService.update(model);return model;}
}
摘要
现在,我们已经向单个Spring Data Solr存储库添加了一个自定义方法,并实现了使用Solr的部分更新功能的更新功能。 本教程教了我们两件事:
- 我们知道如何将自定义方法添加到单个Spring Data Solr存储库。
- 我们知道,只有存储了文档的所有字段( 存储属性的值为true),我们才可以使用部分更新。
我的Spring Data Solr教程的下一部分描述了如何利用从该博客文章中学到的技能来使用Spring Data Solr创建动态查询 。
PS此博客条目的示例应用程序可从Github获得 。
翻译自: https://www.javacodegeeks.com/2013/05/spring-data-solr-tutorial-adding-custom-methods-to-a-single-repository.html