如何用Java SQL语句为每个Apache Ignite缓存创建表?
解决Apache Ignite中为每个缓存创建独立SQL表的问题
你遇到的核心问题是:Ignite默认会把CREATE TABLE语句关联到当前上下文的缓存(或默认缓存),如果不明确指定表与缓存的绑定关系,所有缓存会共用同一个表。要实现每个缓存拥有独立的MYTABLE,并支持"CACHE_NAME".MYTABLE形式的查询,需要从缓存Schema配置和表绑定规则两个方面入手,具体步骤如下:
1. 确保每个缓存有独立的SQL Schema
在创建CacheConfiguration时,一定要将SQL Schema设置为与缓存名完全一致(这是后续区分表的关键):
String CACHENAME = "my_cache_01"; // 每个缓存用唯一的名字 CacheConfiguration<Object, Object> cacheConfiguration = new CacheConfiguration<>(CACHENAME); cacheConfiguration.setName(CACHENAME); // 核心:Schema名与缓存名一致 cacheConfiguration.setSqlSchema(CACHENAME); cacheConfiguration.setAtomicityMode(CacheAtomicityMode.ATOMIC); // 启动缓存 IgniteCache<Object, Object> cache = ignite.getOrCreateCache(cacheConfiguration).withKeepBinary();
2. 创建表时明确绑定到目标缓存
执行CREATE TABLE语句时,必须通过WITH "cache_name='XXX'"子句指定该表所属的缓存,同时将表放在对应缓存的Schema下:
String createTableSql = String.format( "CREATE TABLE IF NOT EXISTS \"%s\".MYTABLE(" + " TAG VARCHAR," + " TIMECREATED TIMESTAMP," + " VALUE DOUBLE," + " PRIMARY KEY(TAG,TIMECREATED)" + ") WITH \"cache_name='%s'\"", CACHENAME, CACHENAME ); // 通过当前缓存对象执行SQL,确保上下文正确 cache.query(new SqlFieldsQuery(createTableSql)).getAll();
这里的两个关键点:
- 用
"CACHENAME".MYTABLE指定表所在的Schema(双引号不能省略,因为缓存名可能包含特殊字符或大小写敏感) WITH "cache_name='CACHENAME'"强制Ignite将该表与指定缓存绑定,避免共用表
3. 按缓存名查询独立表
现在你可以通过指定Schema的方式查询对应缓存的MYTABLE了:
// 示例:查询my_cache_01缓存中的MYTABLE String querySql = "SELECT * FROM \"my_cache_01\".MYTABLE WHERE TAG = ?"; List<List<?>> results = cache.query(new SqlFieldsQuery(querySql).setArgs("sensor_001")).getAll(); // 或者用Ignite SQL API直接执行,更灵活 List<Map<String, Object>> resultMaps = ignite.sql() .execute("\"my_cache_01\"", querySql, "sensor_001") .map(row -> row.toMap()) .collect(Collectors.toList());
4. 验证表与缓存的关联关系
如果你想确认表是否正确绑定到缓存,可以从运行中的缓存配置中获取QueryEntity(注意不能用创建时的cacheConfiguration对象,必须从已启动的缓存中获取):
CacheConfiguration<?, ?> runningCacheCfg = cache.getConfiguration(CacheConfiguration.class); Collection<QueryEntity> queryEntities = runningCacheCfg.getQueryEntities(); // 遍历queryEntities,你会看到MYTABLE的实体,其中包含schema和缓存的关联信息 for (QueryEntity entity : queryEntities) { System.out.println("表名:" + entity.getTableName()); System.out.println("所属Schema:" + entity.getSchemaName()); }
关键总结
- 每个缓存的SQL Schema必须唯一,且与缓存名一致,这是区分不同缓存表的基础
- 创建表时必须通过
WITH "cache_name='XXX'"绑定到目标缓存,否则会默认使用当前上下文的缓存(导致表共用) - 查询时必须用双引号包裹缓存名(Schema名),确保Ignite能正确识别不同缓存的表
内容的提问来源于stack exchange,提问作者Shravan C
相关产品推荐
相关产品推荐

