javascript
通过委托增强Spring数据存储库
我最近寫了幾篇有關Kotlin代表團的文章。 通過這樣做,我實現(xiàn)了一種將其應用于Spring Data存儲庫的有用方法。 這將使Spring Data在提供定制路線的同時繼續(xù)散布一些魔力。 這篇文章中顯示的代碼在Kotlin中,但仍然與Java有關。
這篇文章使用R2DBC,但是內(nèi)容足夠通用,可以應用于任何Spring Data模塊。
如果您在這些領域沒有太多的背景知識,那么在Kotlin中 使用Spring Data R2DBC和類委托讀取異步RDBMS訪問將是有益的。
作為回顧。 Spring Data提供的魔力是什么?
Spring Data允許您編寫一個僅需要定義所需查詢的接口。 然后它將完成創(chuàng)建實現(xiàn)和為您注入依賴項的所有工作。 看起來像這樣:
@Repository interface PersonRepository : R2dbcRepository<Person, Int> { @Query ( "SELECT * FROM people WHERE age > $1" ) fun findAllByAgeGreaterThan(age: Int): Flux<Person> }由于正在使用Spring Data R2DBC,因此尚不完全支持完全推斷的查詢。 這就是為什么手動寫出查詢的原因。
不利的一面是它正在基于接口創(chuàng)建實現(xiàn)。 因此,如果要進行任何類型的自定義,則需要自己創(chuàng)建接口的實例,注入其依賴關系并實現(xiàn)每個查詢。 例如:
class PersonRepositoryImpl( private val entity: RelationalEntityInformation<Person, Int>, private val databaseClient: DatabaseClient, converter: R2dbcConverter, private val accessStrategy: ReactiveDataAccessStrategy ) : SimpleR2dbcRepository<Person, Int>(entity, databaseClient, converter, accessStrategy), PersonRepository { override fun findAllByAgeGreaterThan(age: Int): Flux<Person> { val mapper: StatementMapper.TypedStatementMapper<Person> = accessStrategy.statementMapper.forType(entity.javaType) val selectSpec: StatementMapper.SelectSpec = mapper .createSelect(entity.tableName) .withProjection(accessStrategy.getAllColumns(entity.javaType)) .withCriteria(Criteria.where( "age" ).greaterThan(age)) val operation: PreparedOperation<*> = mapper.getMappedObject(selectSpec) return databaseClient.execute().sql(operation).`as`(entity.javaType).fetch().all() } }是的,該查詢代碼可能很糟糕,我相信您可以做得更好。 你明白我的意思。
可以通過委派基于您的接口實現(xiàn)的Spring倉庫來消除創(chuàng)建此類的麻煩。 然后,您可以添加所需的所有自定義。
在Kotlin中,這看起來像:
@Repository class DelegatingPersonRepository( private val delegate: PersonRepository) : PersonRepository by delegate { override fun <S : Person> save(objectToSave: S): Mono<S> { // override `save` implementation } // any other overrides (kotlin provides delegated implementations) }在Java中,這比較麻煩,但仍然可以輕松實現(xiàn):
@Repository public class DelegatingPersonRepository implements PersonRepository { private final PersonRepository delegate; public DelegatingPersonRepository(PersonRepository delegate) { this .delegate = delegate; } @Override public Flux<Person> findAllByAgeGreaterThan( int age) { return delegate.findAllByAgeGreaterThan(age); } @Override public <S extends Person> Mono<S> save(S entity) { // override `save` implementation } // all other implementations of `PersonRepository` functions }在這兩個版本中, DelegatingPersonRepository調(diào)用PersonRepository定義的findAllByAgeGreaterThan的實現(xiàn)。 到目前為止,還沒有直接花費精力來編寫查詢數(shù)據(jù)庫的功能。
使用DelegatingPersonRepository ,所有未覆蓋的函數(shù)調(diào)用將委托給Spring創(chuàng)建的PersonRepository的實現(xiàn)。
對于像我這樣的人,他真的不喜歡將SQL查詢放在一起并編寫所有轉(zhuǎn)換代碼。 通過這種方式使用委派確實可以使您充分利用Spring Data的優(yōu)勢,同時仍然為您提供自定義結(jié)果的空間。 您節(jié)省的代碼量實際上可能不是那么大。 但是,將其組合在一起所需的工作量大大減少了。 讓Spring為您完成所有繁重的工作!
翻譯自: https://www.javacodegeeks.com/2019/09/augmenting-spring-data-repository-delegation.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的通过委托增强Spring数据存储库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DDoS流量(ddos流量牵引)
- 下一篇: 只读副本和Spring Data第3部分