如何在Spring data GemFire/Geode中配置要写入动态区域的数据



我已经在GemFire中创建了多个Region。我想根据请求将一般数据写入userregionemloyee区域(我还有几个区域(。在控制器中,它接收一个通用请求,因此它必须从请求中识别要选择的现有区域。

@Region(value="UserRegion")
public class GeneralData implements Serializable {

当区域名称被注释时,如何从控制器设置区域名称。

您似乎在问是否可以在运行时根据请求动态确定Region,例如来自Spring[Web]@Controller

也许,类似于PR#91中要求的内容?尽管如此,我还是拒绝了这个PR,支持一种更灵活的方法,将其命名为DATAGEODE-244-">添加RegionResolver接口,以便在需要时/需要时启用惰性区域解析。">

不过,你的问题有点模棱两可,我不想在这里假设任何事情。

有几点。。。

1( 首先,应用程序域对象(例如GeneralDataEmployee(确实被持久化到特定的、显式声明的Region w.r.t.到">映射"(即使用SDG@Region">mapping注释(,这是由Spring DataRepository抽象解析的。就这一点而言,这与任何其他映射技术(例如ORM;使用Hibernate的JPA(没有太大区别。

默认情况下,如果未指定@Region映射注释,则SD[G]将使用应用程序域对象类型的简单类名(例如"Employee"(来解析对象将持久化的Region。通常,最好是显式的,并使用Spring Data[GemFire]映射注释声明您的意图(例如@Region@Id来标记标识符等(。

2( 其次,当然,这一切都取决于您是否首先使用Spring Data[GemFire]存储库基础设施。如果没有,那么上述观点就没有意义了。如果你是,我想你想要这样的东西。。。

@Region("Employees")
class Employee { ... }
@Controller
class MyController {
@Autowired
private EmployeeRepository employeeRepository;
@PostMapping("/employees")
public String process(Employee employee) {
// modify employee, then save...
if (employee.isContractor()) {
// save to "Contractors" Region
}
else {
employeeRepository.save(employee);
}
}
}

当然,您不能使用EmployeeRepository来保存Employee对象(该对象映射到"Employees"Region到"Contractors"Region,因为Employee类型使用`@Region"映射注释"映射"到"Emp雇员"Region。

SDG确实在不久前添加了支持,现在允许用户使用@Region映射注释来注释Repository接口,例如。。。

@Region("Contractors")
interface ContractorRepository extends CrudRepository<Employee, Long> { ... }

这将有效地覆盖应用程序域对象类型(例如Employee(上的@Region映射注释,而在Repo上使用@Region映射注释。这允许用户对同一应用程序域对象类型使用不同的Repository(接口(声明,以便将域对象映射到不同的Regions。

尽管如此,如果您有很多不同的Regions和基于请求的动态逻辑,那么为每个潜在目的地都有一个Repository接口声明,这是非常麻烦的。

或者,您可以在Spring Web MVC配置中注册不同的SpringHttpMessageConverters,以将请求数据转换为(实体(类型(例如Contractor(,该类型根据数据所属位置确定其持久目的地。

@Region("Contractors")
class Contractor extends Employee { ... }

然后:

@PostMapping("/employees")
public void process(Contractor contractor) {
// modify contractor, then save...
this.employeeRepository.save(contractor);
}

3( 第三,当然,如果您没有使用Spring Data Repository抽象(和SDG扩展(,那么您可以通过使用SDG的GemfireTemplate对数据的持久化位置进行更多控制。

例如:

@Region("Employees")
class Employee { .. }
@Region("Contractors")
class Contractor extends Employee { ... }
@Configuration
@ClientCacheApplication
class GemFireConfiguration {
@Bean("Employees")
ClientRegionFactoryBean employeesRegion(ClientCache clientCache) { ... }
@Bean("Contractors")
ClientRegionFactoryBean contractorsRegion(ClientCache clientCache) { ... }
@Bean("employeesTemplate) {
GemfireTemplate employeesTemplate(ClientCache clientCache) {
return new GemfireTemplate(clientCache.getRegion("/Employees"));
}
@Bean("contractorsTemplate) {
GemfireTemplate contractorsTemplate(ClientCache clientCache) {
return new GemfireTemplate(clientCache.getRegion("/Contractors"));
}
}

@Controller
class MyController {
@Autowired
@Qualifier("employeeTemplate")
private GemfireTemplate employeesTemplate;
@Autowired
@Qualifier("contractorsTemplate")
private GemfireTemplate contractorsTemplate;
@PostMapping("/employees")
public void process(Employee employee) {
// modify the employee, then save...
if (employee.isContractor()) {
constractorsTemplate.put(employee.getId(), employee);
else {
employeesTemplate.put(employee.getId(), employee);
}
}
}

当然,您可能会想出一种更具创造性的方法,使用策略模式或类似效果,根据请求"解决"需要哪个模板。

如果我正确理解你的UC,那么DATAGEODE-244应该在不久的将来提供一些缓解,一旦它相对于其他正在进行的工作被优先考虑(实际上很快(。

我要说的是,我并不真正喜欢根据请求类型动态更改持久位置。每个实体都经过精心设计,可以映射到特定的目标持久存储。

此外,我也不喜欢"JUNK"区域,即存储多种"类型"数据的区域。这对于查询来说不是最佳的,这可能是您希望将单个应用程序域类型保留到不同Region的原因之一,因为这些Region可能会针对不同类型的查询(带索引(和/或事件进行调整。

无论如何,希望这个答案能提供一些方向或想法,直到DATAGEODE-244准备就绪。

干杯!

最新更新