我的缓存为空,因此sql查询返回null。 通读意味着如果错过了缓存,那么Ignite将自动转到底层数据库(或持久存储)以加载相应的数据。
如果有新数据插入基础数据库表,我必须关闭缓存服务器以自动从数据库表中加载新插入的数据,否则它将自动同步?
是否与Spring的@Cacheable相同或工作方式不同。
在我看来答案是否定的。缓存SQL查询不能作为缓存中的数据工作,但当我尝试使用cache.get时,我得到了以下结果:
案例1:
System.out.println("data == " + cache.get(new PersonKey("Manish", "Singh")).getPhones());
结果==> data == 1235
案例2:
PersonKey per = new PersonKey();
per.setFirstname("Manish");
System.out.println("data == " + cache.get(per).getPhones());
抛出错误: - 如下 error image,image2
答案 0 :(得分:4)
当有一组已知的键要读取时,可以应用读取语义。这不是SQL的情况,因此如果您的数据位于任意第三方存储(RDBMS,Cassandra,HBase,...)中,您必须在运行查询之前将数据预加载到内存中。
但是,Ignite提供了本机持久性存储[1],它消除了这种限制。它允许使用任何Ignite API,而不需要内存中的任何内容,这也包括SQL查询。在您使用数据时,数据将按需提取到内存中。
[1] https://apacheignite.readme.io/docs/distributed-persistent-store
答案 1 :(得分:1)
当您在数据库中插入某些内容并且尚未在缓存中时,如果 readThrough 已启用且,则 get 操作将从数据库中检索缺失值CacheStore 已配置。
但是目前它对于在缓存上执行的SQL查询不起作用。您应首先调用loadCache,然后值将出现在缓存中并可用于SQL。
当您执行第二次 get 时,会在DB中搜索name
和lastname
的确切组合。它被转换为包含lastname=null
条件的CQL查询,并且失败,因为lastname
不能是null
。
<强> UPD:强>
要获取firstname
列等于'Manish'的所有记录,您可以先使用适当的谓词执行loadCache
,然后在缓存上运行SQL查询。
cache.loadCache((k, v) -> v.lastname.equals("Manish"));
SqlFieldsQuery qry = new SqlFieldsQuery("select firstname, lastname from Person where firstname='Manish'");
try (FieldsQueryCursor<List<?>> cursor = cache.query(qry)) {
for (List<?> row : cursor)
System.out.println("firstname:" + row.get(0) + ", lastname:" + row.get(1));
}
请注意,loadCache
是一项复杂的操作,需要运行数据库中的所有记录,因此不应过于频繁地调用它。您可以提供null作为谓词,然后将从数据库中加载所有记录。
另外,为了使SQL在缓存上快速运行,您应该将firstname
字段标记为QueryEntity
配置中的索引。
答案 2 :(得分:0)
在您的情况2中,您是否尝试过指定lastname
?通过堆栈跟踪,显然Cassandra预计它不会为空。