Korištenje Couchbasea u proljetnoj aplikaciji

1. Uvod

U ovom nastavku našeg uvoda u Couchbase kreiramo set Spring usluga koje se mogu zajedno koristiti za stvaranje osnovnog sloja postojanosti za Spring aplikaciju bez upotrebe Spring Data.

2. Usluga klastera

Kako bi se zadovoljilo ograničenje da samo jedan CouchbaseEnvironment može biti aktivan u JVM-u, započinjemo pisanjem usluge koja se povezuje s klasterom Couchbase i omogućuje pristup segmentima podataka bez izravnog izlaganja bilo kojem Klastera ili CouchbaseEnvironment instance.

2.1. Sučelje

Ovdje je naš ClusterService sučelje:

javno sučelje ClusterService {Segment openBucket (Naziv niza, Lozinka niza); }

2.2. Provedba

Naša klasa implementacije instancira a DefaultCouchbaseEnvironment i povezuje se s klasterom tijekom @PostConstruct faza tijekom proljetne inicijalizacije konteksta.

To osigurava da klaster nije null i da je povezan kad se klasa ubrizga u druge servisne klase, omogućujući im tako otvaranje jednog ili više segmenata podataka:

@Service javna klasa ClusterServiceImpl implementira ClusterService {privatni klaster klastera; @PostConstruct private void init () {CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create (); cluster = CouchbaseCluster.create (env, "localhost"); } ...}

Dalje, pružamo a ConcurrentHashMap da sadrži otvorene kante i implementira openBucket metoda:

privatna segmenta karte = novo ConcurrentHashMap (); @Override sinkroniziranog javnog segmenta openBucket (Naziv niza, Lozinka niza) {if (! Buckets.containsKey (name)) {Bucket bucket = cluster.openBucket (name, password); buckets.put (ime, vjedro); } vratiti buckets.get (ime); }

3. Servis za kante

Ovisno o tome kako dizajnirate svoju aplikaciju, možda ćete trebati omogućiti pristup istom podatkovnom segmentu u više proljetnih usluga.

Ako smo tijekom pokušaja pokretanja aplikacije samo pokušali otvoriti isti segment u dvije ili više usluga, druga usluga koja to pokušava vjerojatno će naići na ConcurrentTimeoutException.

Da bismo izbjegli ovaj scenarij, definiramo a BucketService sučelje i klasa implementacije po segmentu. Svaka klasa implementacije djeluje kao most između ClusterService i klase kojima je potreban izravan pristup određenoj Kanta.

3.1. Sučelje

Ovdje je naš BucketService sučelje:

javno sučelje BucketService {Bucket getBucket (); }

3.2. Provedba

Sljedeća klasa omogućuje pristup "baeldung-tutorial" kanta:

@Service @Qualifier ("TutorialBucketService") javna klasa TutorialBucketService implementira BucketService {@Autowired private ClusterService couchbase; kanta za privatnu kantu; @PostConstruct private void init () {bucket = couchbase.openBucket ("baeldung-tutorial", ""); } @Override public Bucket getBucket () {return bucket; }}

Ubrizgavanjem ClusterService u našem TutorialBucketService klasa implementacije i otvaranje segmenta u metodi označenoj s @PostConstruct, osigurali smo da će kanta biti spremna za upotrebu kad TutorialBucketService zatim se ubrizgava u druge usluge.

4. Sloj postojanosti

Sada kada imamo uslugu za dobivanje a Kanta Primjerice, stvorit ćemo sloj trajnosti nalik na spremište koji pruža CRUD operacije za klase entiteta drugim uslugama bez izlaganja Kanta primjer za njih.

4.1. Entitet osoba

Ovdje je Osoba klasa entiteta koju želimo nastaviti:

javni razred Osoba {private String id; tip privatnog niza; privatni naziv niza; private String homeTown; // standardni geteri i postavljači}

4.2. Pretvaranje klasa entiteta u i iz JSON-a

Za pretvaranje klasa entiteta u i iz JsonDocument objekte koje Couchbase koristi u svojim operacijama trajnosti, definiramo JsonDocumentConverter sučelje:

javno sučelje JsonDocumentConverter {JsonDocument toDocument (T t); T fromDocument (JsonDocument doc); }

4.3. Implementacija JSON Convertera

Dalje, moramo implementirati a JsonConverter za Osoba entiteta.

@Service javna klasa PersonDocumentConverter implementira JsonDocumentConverter {...}

Mogli bismo koristiti Jackson knjižnica u suradnji s JsonObject razredu toJson i odJson metode za serializaciju i deserializacijuentiteta, međutim u tome postoje dodatni režijski troškovi.

Umjesto toga, za toDocument , koristit ćemo tečne metode JsonObject razred za stvaranje i popunjavanje a JsonObject prije nego što ga zamotate a JsonDocument:

@Override public JsonDocument toDocument (Person p) {JsonObject content = JsonObject.empty () .put ("type", "Person") .put ("name", p.getName ()) .put ("homeTown", p .getHomeTown ()); return JsonDocument.create (p.getId (), content); }

I za fromDocument metodu, koristit ćemoJsonObject razredu getString metoda zajedno sa postavljačima u Osoba razred u našem fromDocument metoda:

@Override public Person fromDocument (JsonDocument doc) {JsonObject content = doc.content (); Osoba p = nova Osoba (); p.setId (doc.id ()); p.setType ("Osoba"); p.setName (content.getString ("ime")); p.setHomeTown (content.getString ("homeTown")); povratak p; }

4.4. CRUD sučelje

Sada stvaramo generički CrudService sučelje koje definira operacije trajanja za klase entiteta:

javno sučelje CrudService {void create (T t); T čitanje (ID niza); T readFromReplica (ID niza); ažuriranje praznine (T t); brisanje void (ID niza); boolean postoji (ID niza); }

4.5. Implementacija CRUD usluge

S postavljenim klasama entiteta i pretvarača, sada implementiramo CrudService za Osoba entitet, ubrizgavanje usluge segmenta i pretvarača dokumenata prikazanih gore i preuzimanje segmenta tijekom inicijalizacije:

@Service javna klasa PersonCrudService implementira CrudService {@Autowired private TutorialBucketService bucketService; @Autowired privatni pretvarač PersonDocumentConverter; kanta za privatnu kantu; @PostConstruct private void init () {bucket = bucketService.getBucket (); } @Override public void create (Person person) {if (person.getId () == null) {person.setId (UUID.randomUUID (). ToString ()); } JsonDocument dokument = converter.toDocument (osoba); vedro.insert (dokument); } @Override public Osoba pročitana (ID niza) {JsonDocument doc = bucket.get (id); return (doc! = null? converter.fromDocument (doc): null); } @Override public Person readFromReplica (ID niza) {List docs = bucket.getFromReplica (id, ReplicaMode.FIRST); return (docs.isEmpty ()? null: converter.fromDocument (docs.get (0))); } @Override public void update (Osoba osoba) {JsonDocument document = converter.toDocument (person); bucket.upsert (dokument); } @Override public void delete (String id) {bucket.remove (id); } @Override javna logička vrijednost postoji (ID niza) {return bucket.exists (id); }}

5. Sve to zajedno

Sad kad imamo sve dijelove našeg sloja postojanosti na mjestu, evo jednostavnog primjera usluge registracije koja koristi PersonCrudService da ustraju i dođu do podnositelja zahtjeva:

@Service javna klasa RegistrationService {@Autowired private PersonCrudService crud; javni void registerNewPerson (ime niza, niz homeTown) {osoba osoba = nova osoba (); person.setName (ime); person.setHomeTown (homeTown); crud.create (osoba); } javna osoba findRegistrant (ID niza) {try {return crud.read (id); } catch (CouchbaseException e) {return crud.readFromReplica (id); }}}

6. Zaključak

Pokazali smo da je s nekoliko osnovnih Spring usluga prilično trivijalno ugraditi Couchbase u Spring aplikaciju i implementirati osnovni sloj postojanosti bez upotrebe Spring Data.

Izvorni kod prikazan u ovom vodiču dostupan je u projektu GitHub.

Možete saznati više o Couchbase Java SDK na službenom mjestu dokumentacije za programere Couchbase.


$config[zx-auto] not found$config[zx-overlay] not found