当前位置: 首页 > news >正文

Apache Ignite 与 Spring Data 集成

这份文档是关于 Apache Ignite 与 Spring Data 集成 的官方指南。它展示了如何像使用 Spring Data JPA 操作数据库一样,用统一的、声明式的接口来操作 Ignite 缓存数据


我们来一步步通俗易懂地解析这段内容,帮助你彻底理解:

💡 核心思想:让开发者可以用“写接口 + 方法命名”的方式,自动实现对 Ignite 缓存的增删改查,而无需手动写 SQL 或缓存 API。


🌟 一、为什么要用 Spring Data + Ignite?

在没有 Spring Data 之前,你要操作 Ignite 缓存,得这样写代码:

IgniteCache<Long, Person> cache = ignite.cache("PersonCache");
cache.put(1L, new Person(...));
List<Long> ids = cache.query(new SqlQuery<>("Person", "orgId > ?")).getAll();

这很繁琐,而且业务逻辑和缓存 API 耦合严重。

而用了 Spring Data 后,你可以像操作数据库一样:

personRepository.save(1L, person);
List<Person> list = personRepository.findByFirstName("John");

好处:

  • 接口驱动,代码简洁
  • 方法名自动生成 SQL 查询
  • 统一数据访问层风格(和 JPA、MongoDB 等保持一致)
  • 易于测试和替换底层存储

📦 二、添加依赖(Maven)

<dependency><groupId>org.apache.ignite</groupId><artifactId>ignite-spring-data_2.2</artifactId><version>{ignite.version}</version>
</dependency>

📌 注意:

  • ignite-spring-data_2.2 是针对 Spring Data 2.2+ 的版本。
  • 如果你用的是老版本 Spring Data(如 2.0),要用 ignite-spring-data_2.0ignite-spring-data

✅ 引入后,Ignite 就能支持 CrudRepository 风格的编程模型了。


🧱 三、定义自己的 Repository 接口

1. 创建实体类 Person

public class Person {@QuerySqlFieldprivate Long id;@QuerySqlFieldprivate String firstName;@QuerySqlFieldprivate String lastName;// getter/setter...
}

⚠️ 注意:要用 @QuerySqlField 注解标记可以用于 SQL 查询的字段。


2. 创建 Repository 接口

@RepositoryConfig(cacheName = "PersonCache")
public interface PersonRepository extends IgniteRepository<Person, Long> {List<Person> findByFirstName(String name);Cache.Entry<Long, Person> findTopByLastNameLike(String name);@Query("SELECT id FROM Person WHERE orgId > ?")List<Long> selectId(long orgId, Pageable pageable);
}

我们逐行解释:

@RepositoryConfig(cacheName = "PersonCache")

  • 告诉 Spring Data:这个接口对应的是哪个 Ignite 缓存(Cache)
  • 所有操作都会作用于名为 "PersonCache" 的分布式缓存。

extends IgniteRepository<Person, Long>

  • Person:缓存中存储的值类型(value)。
  • Long:缓存的键类型(key)。
  • 这个接口继承了 CrudRepository 的基本操作(如 findById, deleteById 等),但也做了适配。

✅ 方法一:findByFirstName(String name)

  • 方法名遵循 Spring Data 命名规范
  • 框架会自动解析为 SQL 查询:
    SELECT * FROM Person WHERE firstName = ?
    
  • 返回 List<Person>,即使只有一条也返回列表。

✅ 方法二:findTopByLastNameLike(String name)

  • Top 表示只取第一条。
  • Like 表示模糊匹配(支持 % 通配符)。
  • 自动转为:
    SELECT * FROM Person WHERE lastName LIKE ? LIMIT 1
    
  • 返回 Cache.Entry<Long, Person>:包含 key 和 value。

✅ 方法三:@Query("SELECT id FROM Person WHERE orgId > ?")

  • 使用 @Query 注解写自定义 SQL 查询
  • 支持分页参数 Pageable
  • 只查 id 字段,性能更高。

⚠️ 四、哪些 CRUD 操作不支持?为什么?

Spring Data 的 CrudRepository 有这些方法:

save(S entity)                    // ❌ 不支持
save(Iterable<S> entities)       // ❌ 不支持
delete(T entity)                 // ❌ 不支持
delete(Iterable<? extends T> entities) // ❌ 不支持

❓ 为什么?

因为 Ignite 是 Key-Value 存储,不像数据库有自动生成主键机制。

比如:

personRepository.save(new Person("John")); // 没给 key,Ignite 不知道存到哪个 key 下!

✅ 替代方案(必须显式提供 key):

// ✅ 正确方式:必须带 key
save(ID key, S entity)
save(Map<ID, S> entities)
deleteAll(Iterable<ID> ids)

例如:

repo.save(1L, new Person(1L, "John"));
repo.save(personsMap); // Map<Long, Person>

🔔 所以:在 Ignite 中使用 Spring Data,必须自己管理 key


⚙️ 五、配置类:启用 Ignite Repositories

@Configuration
@EnableIgniteRepositories
public class SpringAppCfg {@Beanpublic Ignite igniteInstance() {IgniteConfiguration cfg = new IgniteConfiguration();cfg.setIgniteInstanceName("springDataNode");cfg.setPeerClassLoadingEnabled(true);CacheConfiguration ccfg = new CacheConfiguration("PersonCache");ccfg.setIndexedTypes(Long.class, Person.class); // 启用 SQL 查询支持cfg.setCacheConfiguration(ccfg);return Ignition.start(cfg);}
}

关键点:

@EnableIgniteRepositories

  • 启用 Ignite 的 Spring Data 支持。
  • 扫描所有 @RepositoryConfig 标记的接口,自动生成实现类。

@Bean public Ignite igniteInstance()

  • 必须提供一个 Ignite 实例 Bean。
  • 这个节点将用于连接集群,并被所有 IgniteRepository 使用。

ccfg.setIndexedTypes(Long.class, Person.class)

  • 启用 SQL 查询功能。
  • 告诉 Ignite:Person 类可以通过 SQL 查询(如 SELECT * FROM Person)。

🚀 六、使用 Repository(示例)

ctx = new AnnotationConfigApplicationContext();
ctx.register(SpringAppCfg.class);
ctx.refresh();// 获取 Repository 实例
PersonRepository repo = ctx.getBean(PersonRepository.class);// 插入数据(必须带 key)
TreeMap<Long, Person> persons = new TreeMap<>();
persons.put(1L, new Person(1L, "John", "Smith"));
repo.save(persons);// 查询数据
List<Person> johns = repo.findByFirstName("John");
for (Person p : johns) {System.out.println(">>> " + p);
}// 模糊查询
Cache.Entry<Long, Person> top = repo.findTopByLastNameLike("Smi%");
System.out.println(">>> Top: " + top.getValue());

🧠 七、核心机制总结(它是怎么工作的?)

步骤说明
1️⃣你定义一个接口,继承 IgniteRepository<T, ID>
2️⃣加上 @RepositoryConfig(cacheName="xxx") 绑定缓存
3️⃣写方法名如 findByXxxAndYyy(...)
4️⃣Spring Data 在启动时动态生成实现类
5️⃣根据方法名自动翻译成 Ignite SQL 查询
6️⃣调用时自动执行 SQL 并返回结果

🔍 类似于 MyBatis 的 Mapper 接口,但这里是基于方法命名规则自动生成 SQL


🎯 八、适用场景 & 最佳实践

场景是否推荐
微服务中访问 Ignite 缓存✅ 推荐,风格统一
需要频繁 SQL 查询缓存数据✅ 推荐
只做简单 key-value 存取❌ 不必要,直接用 IgniteCache 更简单
已有 Spring Data 架构(如 JPA)✅ 容易统一数据访问层

✅ 最佳实践建议:

  1. 实体类加 @QuerySqlField:只有标记的字段才能用于 SQL 查询。
  2. 合理使用 @Query:复杂查询用注解写 SQL。
  3. 注意 key 管理save(entity) 不支持,必须用 save(key, entity)
  4. 开启对等类加载setPeerClassLoadingEnabled(true),避免节点间类不一致。
  5. 缓存名唯一:确保 @RepositoryConfig(cacheName) 对应的缓存在集群中已创建或配置。

🧩 九、一句话总结

Apache Ignite 通过实现 Spring Data 的 CrudRepository 接口,让你可以用“接口 + 方法命名”的方式,像操作数据库一样操作分布式缓存,自动将方法名转换为 SQL 查询,极大提升了开发效率和代码可读性,尤其适合已有 Spring Data 技术栈的项目。


✅ 十、对比:Ignite + Spring Boot vs Ignite + Spring Data

特性Spring Boot AutoconfigureSpring Data
目的自动启动 Ignite 节点或 Thin Client提供声明式数据访问接口
配置方式application.yml + @Bean@EnableIgniteRepositories + @RepositoryConfig
编程模型手动调用 IgniteCache API声明式接口(类似 JPA)
是否生成 SQL否(需手动写)✅ 是(方法名自动转 SQL)
适合场景基础集成、缓存管理复杂查询、统一数据访问层

✅ 实际项目中,两者可以结合使用:

  • Spring Boot 自动配置 Ignite 节点
  • Spring Data 定义 Repository 接口进行数据操作

如果你需要,我可以为你生成一个完整的示例项目结构,包含:

  • pom.xml
  • application.yml
  • Person.java
  • PersonRepository.java
  • AppConfig.java
  • Service 层调用示例

是否需要?😊

http://www.dtcms.com/a/306090.html

相关文章:

  • Electron + Fabric 打包遇到error LNK2001
  • 【面试场景题】随机立减金额计算
  • JVM——内存布局、类加载机制及垃圾回收机制
  • Http401和403什么意思
  • 颐顿机电携手观远BI数据:以数据驱动决策,领跑先进制造智能化升级
  • 皮尔逊相关系数的理论基础、统计特性与应用局限
  • 操作系统:总结(part_1,part_2)
  • Python Pandas.get_dummies函数解析与实战教程
  • Python在自动化与运维领域的核心角色:工具化、平台化与智能化
  • 从零开始,在Windows环境部署vllm
  • Boost.Asio:探索异步I/O引擎核心
  • stm32的PID控制算法
  • 学习游戏制作记录(冻结敌人时间与黑洞技能)7.30
  • 【音视频】WebRTC 开发环境搭建-Web端
  • Apple基础(Xcode②-Flutter结构解析)
  • ica1靶机练习
  • K8s 备份与恢复利器:Velero 实战指南
  • MySQL常见面试题
  • springboot本地访问https链接,证书错误
  • Spark的宽窄依赖
  • Kubernetes 中 ConfigMap 与 Secret 的深度解析
  • gaussdb demo示例
  • Spring Cloud Gateway静态路由实战:Maven多模块高效配置指南
  • 时序数据库厂商 TDengine 发布 AI 原生的工业数据管理平台 IDMP,“无问智推”改变数据消费范式
  • ES 文件浏览器:多功能文件管理与传输利器
  • 数据建模怎么落地?从概念、逻辑到物理模型,一文讲请!
  • Kubernetes高级调度02
  • 《超级秘密文件夹》密码遗忘?试用版/正式版找回教程(附界面操作步骤)
  • AI任务相关解决方案11-基于 Qwen3+langchain+Agent 的学术论文编辑平台系统搭建与开发案例
  • Redis学习------缓存穿透