如何以多列为键实现Ignite缓存/表的AffinityKey关联?
嘿,我来帮你搞定Ignite多键缓存的关联查询问题!首先得先明确你的实体类结构,我先基于常见的复合主键(多列键)场景补全你的类定义,再给你写关联查询的具体实现~
一、先补全你的实体类与缓存创建代码
1. Person 复合主键类
public class PersonKey implements Serializable { private Long id; private Long orgId; // 关联Organization的主键字段 // 别忘了写构造器、getter/setter,还有重写equals()和hashCode()! }
2. Person 值对象
public class Person implements Serializable { private String name; private Integer age; // 构造器、getter/setter }
3. Organization 复合主键类
public class OrgKey implements Serializable { private Long id; private String region; // 同样要写构造器、getter/setter,重写equals()和hashCode() }
4. Organization 值对象
public class Organization implements Serializable { private String orgName; private String address; // 构造器、getter/setter }
5. Ignite缓存创建代码
Ignite ignite = Ignition.start(); // 创建Person多键缓存 CacheConfiguration<PersonKey, Person> personCacheCfg = new CacheConfiguration<>("personCache"); // 必须设置索引类型,Ignite才会为字段建索引 personCacheCfg.setIndexedTypes(PersonKey.class, Person.class); ignite.getOrCreateCache(personCacheCfg); // 创建Organization多键缓存 CacheConfiguration<OrgKey, Organization> orgCacheCfg = new CacheConfiguration<>("orgCache"); orgCacheCfg.setIndexedTypes(OrgKey.class, Organization.class); ignite.getOrCreateCache(orgCacheCfg);
二、多键缓存的关联查询实现
Ignite支持用SQL直接关联多键缓存,核心是用KEY.字段名来访问复合主键里的属性,下面给你两种常用的查询方式:
方式1:基础SQL查询(关联Person和Organization)
比如我们要关联Person和Organization,关联条件是Person的orgId等于Organization的id,可以这么写:
String sql = "SELECT p.name, o.orgName " + "FROM personCache p " + "JOIN orgCache o ON p.KEY.orgId = o.KEY.id"; try (QueryCursor<List<?>> cursor = ignite.query(new SqlQuery<>(Person.class, sql))) { for (List<?> row : cursor) { System.out.println("Person Name: " + row.get(0) + ", Org Name: " + row.get(1)); } }
方式2:带参数的SQL Fields Query(更灵活)
如果需要加过滤条件或者返回更多字段,用SqlFieldsQuery更合适:
SqlFieldsQuery sqlQuery = new SqlFieldsQuery( "SELECT p.name, p.age, o.orgName, o.address " + "FROM personCache p " + "INNER JOIN orgCache o ON p.KEY.orgId = o.KEY.id " + "WHERE o.KEY.region = ?" ); sqlQuery.setArgs("North America"); // 传入过滤参数 try (QueryCursor<List<?>> cursor = ignite.query(sqlQuery)) { for (List<?> row : cursor) { System.out.printf("Name: %s, Age: %d, Org: %s, Address: %s%n", row.get(0), row.get(1), row.get(2), row.get(3)); } }
几个关键注意点
- 复合主键类必须实现Serializable接口,而且一定要正确重写
equals()和hashCode(),不然缓存会出问题。 - 查询时必须用
KEY.字段名的语法访问主键属性,这是Ignite SQL识别复合主键字段的规则。 - 如果需要左连接/右连接,直接把
INNER JOIN换成LEFT JOIN或RIGHT JOIN就行,Ignite支持标准SQL的关联语法。 - 缓存创建时一定要调用
setIndexedTypes(),不然Ignite不会为字段建索引,查询性能会很差。
内容的提问来源于stack exchange,提问作者Manikanta Reddy Pasala
相关产品推荐
相关产品推荐

