我有两个缓存,一个用于 Person,另一个用于 Company 对象,通过将 Person.Id 指定为键,将 Person.CompanyId 指定为关联键。
personCache.Put(new AffinityKey(p1.Id, p1.CompanyId), p1);
companyCache.Put(c1.Id, c1);
是否可以使用 Person.Id 从缓存中获取人员? (没有 Person.CompanyId)?
最佳答案
是的,但不适用于键值 API。
根据定义,Key-Value API 需要 key 才能访问数据。如果您的 key 是 AffinityKey(personId, companyId)
,那么您必须构造完整的 key 对象才能使用 IgniteCache::get
操作。
但是,还有 SQL API,它是访问相同数据的另一个接口(interface)。您可以将缓存声明为支持 SQL 的缓存,并将 personId
声明为该缓存中的 SQL 字段。
有多种方法可以创建启用 SQL 的缓存:
使用
CREATE TABLE
语句创建它(而不是在节点配置中指定它或使用createCache
方法创建)。将
indexedTypes
指定为CacheConfiguration
的一部分,并将键和值对象的字段注释为@QuerySqlField
。< br/>indexedTypes
的问题是您必须将注释放入类中。显然,这不适用于AffinityKey
类,因为您无法更改它。将
QueryEntity
指定为CacheConfiguration
的一部分。
QueryEntity
的问题在于它可能会变得相当复杂,并且通常比@QuerySqlField
注释更难维护。
就您而言,我建议不要使用 AffinityKey
类并创建您自己的版本 - 我们将其称为 PersonKey
。您可以注释其字段并使用 indexedTypes
。
下面是一个简短的示例:
public class SqlFieldInKeyExample {
static class PersonKey {
@QuerySqlField
long personId;
@QuerySqlField
@AffinityKeyMapped
long companyId;
public PersonKey(long personId, long companyId) {
this.personId = personId;
this.companyId = companyId;
}
}
static class Person {
@QuerySqlField
String name;
public Person(String name) {
this.name = name;
}
}
public static void main(String[] args) throws IgniteException {
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
CacheConfiguration<PersonKey, Person> cfg = new CacheConfiguration<PersonKey, Person>()
.setName("PersonCache")
.setIndexedTypes(PersonKey.class, Person.class);
IgniteCache<PersonKey, Person> cache = ignite.createCache(cfg);
cache.put(new PersonKey(9000, 42), new Person("John Doe"));
List<List<?>> result = cache.query(new SqlFieldsQuery("SELECT * FROM PERSON WHERE PERSONID = 9000")).getAll();
assert result.size() == 1;
System.out.println(">>>>> Person: " + result.get(0));
}
}
}
输出(除其他外)是:
>>>>> Person: [9000, 42, John Doe]
关于c# - Apache 点燃: How to get cached item without affinity key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69281665/