Java中Stalactite ORM簡介

banq發表於2024-05-16

快速介紹 Stalactite ORM以及與 Spring 框架的整合:

Java ORM世界非常穩定,存在的庫很少,但它們在過去十年中都沒有帶來任何突破性的變化。同時,應用程式架構隨著一些趨勢而發展,例如六邊形架構、CQRS、領域驅動設計或領域純度。

Stalactite 試圖透過允許持久化任何型別的類而不需要註釋它們或使用外部 XML 檔案來更適合這些新範例:

  • 它的對映由方法引用組成

MappingEase.entityBuilder(Country.class, Long.class)
    .mapKey(Country::getId, IdentifierPolicy.afterInsert())
    .mapOneToOne(Country::getCapital, MappingEase.entityBuilder(City.class, Long.class)
        .mapKey(City::getId, IdentifierPolicy.afterInsert())
        .map(City::getName))


這樣做的好處是,您可以更好地檢視實體圖,因為對映是透過流暢的應用程式介面(API)進行的,它將您的實體關係鏈化,而不是將註釋遍佈整個實體。

  • 這對了解實體圖的複雜性非常有幫助,因為複雜性會影響實體圖的負載和記憶體。
  • 由於 Stalactite 只急切地獲取資料,因此我們可以說所見即所得。

第一步
2.0.0 版本已釋出幾周,並可作為Maven 依賴項使用,以下是 HSQLDB 的示例。目前,Stalactite 相容以下資料庫(主要是最新版本):HSQLDB、H2、PostgreSQL、MySQL 和 MariaDB。

<dependency>
   <groupId>org.codefilarete.stalactite</groupId>
   <artifactId>orm-hsqldb-adapter</artifactId>
   <version>2.0.0</version>
</dependency>

如果您對較少資料庫供應商專用的模組感興趣,可以使用 orm-all-adapter 模組。請注意,它會給您帶來額外的模組和額外的 JDBC 驅動程式,從而增加您的工件。

將 Statactite 作為依賴項獲取後,下一步是獲取 JDBC 資料來源並將其傳遞給org.codefilarete.stalactite.engine.PersistenceContext:


org.hsqldb.jdbc.JDBCDataSource dataSource= new org.hsqldb.jdbc.JDBCDataSource();
dataSource.setUrl(<font>"jdbc:hsqldb:mem:test");
dataSource.setUser(
"sa");
dataSource.setPassword(
"");
PersistenceContext persistenceContext = new PersistenceContext(dataSource, new HSQLDBDialect());


然後是有趣的部分:對映。假設您獲得一個國家/地區,您可以透過 Fluent API 快速設定其對映,從org.codefilarete.stalactite.mapping.MappingEase類開始:

EntityPersister<Country, Long> countryPersister = MappingEase.entityBuilder(Country.class, Long.class)
    .mapKey(Country::getId, IdentifierPolicy.afterInsert())
    .map(Country::getName)
    .build(persistenceContext);

  • afterInsert():識別符號策略,意味著country.id列是自增列。還存在另外兩種策略:beforeInsert()由資料庫序列(例如)給出的識別符號,以及alreadyAssigned():具有由業務規則給出的自然識別符號的實體,
  • 任何未宣告的屬性均被視為暫時的,不由Stalactite管理。

表結構模型可以使用org.codefilarete.stalactite.sql.ddl.DDLDeployer類來生成(它將生成到PersistenceContext資料來源中):

DDLDeployer ddlDeployer = new DDLDeployer(persistenceContext);
ddlDeployer.deployDDL();


最後,您可以透過EntityPersister之前獲得的資訊來持久化您的實體,請參閱下面的示例。

Country myCountry = new Country();
myCountry.setName(<font>"myCountry"); 
countryPersister.insert(myCountry); 
myCountry.setName(
"myCountry with a different name"); 
countryPersister.update(myCountry); 
Country loadedCountry = countryPersister.select(myCountry.getId()); 
countryPersister.delete(loadedCountry);


您可能會注意到,在 Stalactite persister 中找不到JPA方法。原因是Stalactite與JPA有很大不同,並且不以相容JPA為目標:

  • 沒有註釋,
  • 沒有附加/分離機制,
  • 沒有一級快取,
  • 沒有延遲載入等等。

因此,這些方法非常直接地達到了他們的目標:


與 Spring 整合
你可能會對Stalactite的原始用法感興趣,同時,你可能會對它與 Spring 的整合感興趣,以便從 @Repository 的神奇功能中獲益。

Stalactite提供了這一功能,但需要注意的是,它仍是一個正在開發中的功能。

啟用它的方法與 JPA 相同:

  • 在 Spring 應用程式中使用 @EnableStalactiteRepositories 註解來啟用Stalactite儲存庫。
  • 然後將 PersistenceContext 和 EntityPersister 宣告為 @Bean :

@Bean
public PersistenceContext persistenceContext(DataSource dataSource) {
    return new PersistenceContext(dataSource);
}

@Bean
public EntityPersister<Country, Long> countryPersister(PersistenceContext persistenceContext) { 
    return MappingEase.entityBuilder(Country.class, long.class
            .mapKey(Country::getId, IdentifierPolicy.afterInsert())
            .map(Country::getName)
            .build(persistenceContext);
}


然後,您就可以將您的版本庫宣告為這樣的版本庫,以便注入到您的服務中:

@Repository
public interface CountryStalactiteRepository extends StalactiteRepository<Country, Long> {
}

如前所述,由於 Stalactite 的正規化與 JPA 不同(沒有註解、沒有附加/脫離機制等),因此在 Stalactite 中找不到與 JPA 儲存庫相同的方法:

  • save:儲存給定實體,根據其持久化狀態插入或更新實體
  • saveAll:與前一個方法相同,但有一個龐大的應用程式介面
  • findById:嘗試在資料庫中按 ID 查詢實體
  • findAllById:與前一種方法相同,提供大量應用程式介面
  • delete:從資料庫中刪除給定實體
  • deleteAll:與前一個相同,使用大量 API

結論
在這些章節中,我們介紹了 Stalactite ORM,有關配置、對映和所有文件的更多資訊可以在網站上找到。 
該專案是開源的,擁有 MIT 許可證,並透過Github共享。


 

相關文章