当使用自定义类作为Ignite键时,是否可以查询嵌套字段?
使用ApacheIgnite2.7.6,我试图创建一个缓存,其密钥是一个自定义类,其中包含多个字段,并嵌入到值中。缓存工作,但SQL接口显示嵌套键中字段的空值。此外,当我将这些字段作为表的主键时,结果似乎违反了标准SQL,因为主键中允许多个空值。有什么办法可以让这一切顺利进行吗 可复制的示例如下:当使用自定义类作为Ignite键时,是否可以查询嵌套字段?,ignite,Ignite,使用ApacheIgnite2.7.6,我试图创建一个缓存,其密钥是一个自定义类,其中包含多个字段,并嵌入到值中。缓存工作,但SQL接口显示嵌套键中字段的空值。此外,当我将这些字段作为表的主键时,结果似乎违反了标准SQL,因为主键中允许多个空值。有什么办法可以让这一切顺利进行吗 可复制的示例如下: @Test public void testComplexKey() throws InterruptedException { val queryEntity = new QueryEnti
@Test
public void testComplexKey() throws InterruptedException {
val queryEntity = new QueryEntity(TestKey.class, TestValue.class);
// I get the same results regardless of whether these 2 lines are present or not
queryEntity.getFields().put("key", TestKey.class.getName());
queryEntity.setKeyFieldName("key");
// I get the same results regardless of whether this lines is present or not
queryEntity.setKeyFields(Sets.newHashSet("key.firstName", "key.lastName"));
queryEntity.getFields().put("key.firstName", String.class.getName());
queryEntity.getFields().put("key.lastName", String.class.getName());
queryEntity.getFields().put("data", String.class.getName());
queryEntity.setTableName("test_values");
val cache = ignite.getOrCreateCache(
new CacheConfiguration<TestKey, TestValue>()
.setName("test_values")
.setQueryEntities(Lists.newArrayList(queryEntity))
);
cache.put(new TestKey("Bob", "Jones"), new TestValue(new TestKey("Bob", "Jones"), "The quick red fox jumped over the lazy brown dog"));
cache.put(new TestKey("Jim", "Smith"), new TestValue(new TestKey("Jim", "Smith"), "The quick red dog jumped over the lazy brown fox"));
Assertions.assertEquals("The quick red fox jumped over the lazy brown dog", cache.get(new TestKey("Bob", "Jones")).data);
// This assertion would fail - no rows found
// Assertions.assertEquals("The quick red fox jumped over the lazy brown dog", cache.query(new SqlQuery<TestKey, TestValue>(TestValue.class, "firstName = 'Bob'")).getAll().stream().findFirst().orElseThrow().getValue().data);
// This just to keep the test running and allow me to query the SQL interface
while (true) Thread.sleep(10000);
}
@NoArgsConstructor // This is Lombok shorthand
@AllArgsConstructor
public static class TestKey {
@Getter
@Setter
String firstName;
@Getter
@Setter
String lastName;
}
@NoArgsConstructor
@AllArgsConstructor
public static class TestValue {
@Getter
@Setter
TestKey key;
@Getter
@Setter
String data;
}
@测试
public void testComplexKey()引发InterruptedException{
val queryEntity=newqueryentity(TestKey.class,TestValue.class);
//无论这两行是否存在,我都会得到相同的结果
queryEntity.getFields().put(“key”,TestKey.class.getName());
queryEntity.setKeyFieldName(“键”);
//无论这行是否存在,我都会得到相同的结果
queryEntity.setKeyFields(set.newHashSet(“key.firstName”、“key.lastName”));
queryEntity.getFields().put(“key.firstName”,String.class.getName());
queryEntity.getFields().put(“key.lastName”,String.class.getName());
queryEntity.getFields().put(“数据”,String.class.getName());
queryEntity.setTableName(“测试值”);
val cache=ignite.getOrCreateCache(
新缓存配置()
.setName(“测试值”)
.setQueryEntity(list.newArrayList(queryEntity))
);
put(新的TestKey(“Bob”,“Jones”)、新的TestValue(新的TestKey(“Bob”,“Jones”)、“敏捷的红狐跳过了懒惰的棕色狗”);
put(新的TestKey(“吉姆”,“史密斯”)、新的TestValue(新的TestKey(“吉姆”,“史密斯”)、“敏捷的红狗跳过了懒惰的棕色狐狸”);
Assertions.assertEquals(“敏捷的红狐跳过了懒惰的棕色狗”,cache.get(新测试键(“鲍勃”,“琼斯”)).data);
//此断言将失败-未找到任何行
//Assertions.assertEquals(“敏捷的红狐跳过了懒惰的棕色狗”,cache.query(新的SqlQuery(TestValue.class,“firstName='Bob'))).getAll().stream().findFirst().orelsetrow().getValue().data);
//这只是为了保持测试运行,并允许我查询SQL接口
while(真)线程。sleep(10000);
}
@NoArgsConstructor//这是龙目语速记
@AllArgsConstructor
公共静态类TestKey{
@吸气剂
@塞特
字符串名;
@吸气剂
@塞特
字符串lastName;
}
@诺尔格构装师
@AllArgsConstructor
公共静态类TestValue{
@吸气剂
@塞特
测试键;
@吸气剂
@塞特
字符串数据;
}
生成的SQL视图是。。。相当混乱:
在SQL引擎中,您的对象都是“展平”的,因此您可以引用
键.firstName
,就像firstName
一样
queryEntity.setKeyFields(Sets.newHashSet("firstName", "lastName"));
queryEntity.getFields().put("firstName", String.class.getName());
queryEntity.getFields().put("lastName", String.class.getName());
queryEntity.getFields().put("data", String.class.getName());
大多数人发现在要向SQL公开的属性上使用@QuerySqlField
注释更容易
不需要在值中包含键对象。删除它还将消除您所引用的“firstName”列的模糊性。在SQL引擎中,您的对象都是“展平”的,因此您引用的是
键。firstName
就像firstName
一样
queryEntity.setKeyFields(Sets.newHashSet("firstName", "lastName"));
queryEntity.getFields().put("firstName", String.class.getName());
queryEntity.getFields().put("lastName", String.class.getName());
queryEntity.getFields().put("data", String.class.getName());
大多数人发现在要向SQL公开的属性上使用@QuerySqlField
注释更容易
不需要在值中包含键对象。删除它还将消除您所引用的“firstName”列的模糊性