javascript
通过委托增强Spring数据存储库
我最近寫(xiě)了幾篇有關(guān)Kotlin代表團(tuán)的文章。 通過(guò)這樣做,我實(shí)現(xiàn)了一種將其應(yīng)用于Spring Data存儲(chǔ)庫(kù)的有用方法。 這將使Spring Data在提供定制路線的同時(shí)繼續(xù)散布一些魔力。 這篇文章中顯示的代碼在Kotlin中,但仍然與Java有關(guān)。
這篇文章使用R2DBC,但是內(nèi)容足夠通用,可以應(yīng)用于任何Spring Data模塊。
如果您在這些領(lǐng)域沒(méi)有太多的背景知識(shí),那么在Kotlin中 使用Spring Data R2DBC和類委托讀取異步RDBMS訪問(wèn)將是有益的。
作為回顧。 Spring Data提供的魔力是什么?
Spring Data允許您編寫(xiě)一個(gè)僅需要定義所需查詢的接口。 然后它將完成創(chuàng)建實(shí)現(xiàn)和為您注入依賴項(xiàng)的所有工作。 看起來(lái)像這樣:
@Repository interface PersonRepository : R2dbcRepository<Person, Int> { @Query ( "SELECT * FROM people WHERE age > $1" ) fun findAllByAgeGreaterThan(age: Int): Flux<Person> }由于正在使用Spring Data R2DBC,因此尚不完全支持完全推斷的查詢。 這就是為什么手動(dòng)寫(xiě)出查詢的原因。
不利的一面是它正在基于接口創(chuàng)建實(shí)現(xiàn)。 因此,如果要進(jìn)行任何類型的自定義,則需要自己創(chuàng)建接口的實(shí)例,注入其依賴關(guān)系并實(shí)現(xiàn)每個(gè)查詢。 例如:
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() } }是的,該查詢代碼可能很糟糕,我相信您可以做得更好。 你明白我的意思。
可以通過(guò)委派基于您的接口實(shí)現(xiàn)的Spring倉(cāng)庫(kù)來(lái)消除創(chuàng)建此類的麻煩。 然后,您可以添加所需的所有自定義。
在Kotlin中,這看起來(lái)像:
@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中,這比較麻煩,但仍然可以輕松實(shí)現(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 }在這兩個(gè)版本中, DelegatingPersonRepository調(diào)用PersonRepository定義的findAllByAgeGreaterThan的實(shí)現(xiàn)。 到目前為止,還沒(méi)有直接花費(fèi)精力來(lái)編寫(xiě)查詢數(shù)據(jù)庫(kù)的功能。
使用DelegatingPersonRepository ,所有未覆蓋的函數(shù)調(diào)用將委托給Spring創(chuàng)建的PersonRepository的實(shí)現(xiàn)。
對(duì)于像我這樣的人,他真的不喜歡將SQL查詢放在一起并編寫(xiě)所有轉(zhuǎn)換代碼。 通過(guò)這種方式使用委派確實(shí)可以使您充分利用Spring Data的優(yōu)勢(shì),同時(shí)仍然為您提供自定義結(jié)果的空間。 您節(jié)省的代碼量實(shí)際上可能不是那么大。 但是,將其組合在一起所需的工作量大大減少了。 讓Spring為您完成所有繁重的工作!
翻譯自: https://www.javacodegeeks.com/2019/09/augmenting-spring-data-repository-delegation.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的通过委托增强Spring数据存储库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: DDoS流量(ddos流量牵引)
- 下一篇: 手机wps文档清除格式(在手机版WPS中