Brug af Couchbase i en forårsprogram

1. Introduktion

I denne opfølgning på vores introduktion til Couchbase opretter vi et sæt Spring-tjenester, der kan bruges sammen til at skabe et grundlæggende persistenslag til en Spring-applikation uden brug af Spring Data.

2. Klyngetjeneste

For at tilfredsstille den begrænsning, at kun en enkelt CouchbaseEnvironment kan være aktiv i JVM, begynder vi med at skrive en tjeneste, der opretter forbindelse til en Couchbase-klynge og giver adgang til dataspand uden direkte at udsætte nogen af Klynge eller CouchbaseEnvironment tilfælde.

2.1. Interface

Her er vores ClusterService grænseflade:

offentlig grænseflade ClusterService {Bucket openBucket (strengnavn, strengadgangskode); }

2.2. Implementering

Vores implementeringsklasse instantierer en StandardCouchbaseEnvironment og forbinder til en klynge under @PostConstruct fase under initialisering af forårssammenhæng.

Dette sikrer, at klyngen ikke er nul, og at den er tilsluttet, når klassen injiceres i andre serviceklasser, hvilket gør det muligt for dem at åbne en eller flere dataspande:

@Service offentlig klasse ClusterServiceImpl implementerer ClusterService {privat klyngeklynge; @PostConstruct privat ugyldigt init () {CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create (); cluster = CouchbaseCluster.create (env, "localhost"); } ...}

Dernæst giver vi en ConcurrentHashMap at indeholde de åbne spande og implementere openBucket metode:

private kortspande = nye ConcurrentHashMap (); @ Override synkroniseret offentlig Bucket openBucket (strengnavn, strengadgangskode) {if (! Buckets.containsKey (name)) {Bucket bucket = cluster.openBucket (navn, adgangskode); buckets.put (navn, spand); } returner skovle.get (navn); }

3. Skovl service

Afhængigt af hvordan du arkitekterer din applikation, skal du muligvis give adgang til den samme dataspand i flere Spring-tjenester.

Hvis vi blot forsøgte at åbne den samme spand i to eller flere tjenester under applikationsstart, vil den anden tjeneste, der forsøger dette, sandsynligvis støde på en ConcurrentTimeoutException.

For at undgå dette scenario definerer vi en BucketService interface og en implementeringsklasse pr. spand. Hver implementeringsklasse fungerer som en bro mellem ClusterService og de klasser, der har brug for direkte adgang til et bestemt Spand.

3.1. Interface

Her er vores BucketService grænseflade:

offentlig grænseflade BucketService {Bucket getBucket (); }

3.2. Implementering

Følgende klasse giver adgang til “baeldung-tutorial”Spand:

@Service @Qualifier ("TutorialBucketService") offentlig klasse TutorialBucketService implementerer BucketService {@Autowired privat ClusterService couchbase; privat spand spand; @PostConstruct privat ugyldigt init () {bucket = couchbase.openBucket ("baeldung-tutorial", ""); } @ Override public Bucket getBucket () {return bucket; }}

Ved at injicere ClusterService i vores TutorialBucketService implementeringsklasse og åbning af skovlen i en metode, der er kommenteret med @PostConstruct, vi har sikret, at skovlen er klar til brug, når den TutorialBucketService injiceres derefter i andre tjenester.

4. Persistenslag

Nu hvor vi har en service på plads til at få en Spand For eksempel opretter vi et lager-lignende persistenslag, der leverer CRUD-operationer til enhedsklasser til andre tjenester uden at udsætte Spand eksempel til dem.

4.1. Personenheden

Her er Person enhedsklasse, som vi ønsker at fortsætte:

offentlig klasseperson {privat streng-id; privat streng type; privat strengnavn; privat String hjemby; // standard getters og setter}

4.2. Konvertering af enhedsklasser til og fra JSON

At konvertere enhedsklasser til og fra JsonDocument objekter, som Couchbase bruger i sine persistensoperationer, definerer vi JsonDocumentConverter grænseflade:

offentlig grænseflade JsonDocumentConverter {JsonDocument toDocument (T t); T fromDocument (JsonDocument doc); }

4.3. Implementering af JSON Converter

Dernæst skal vi implementere en JsonConverter til Person enheder.

@Service offentlig klasse PersonDocumentConverter implementerer JsonDocumentConverter {...}

Vi kunne bruge Jackson bibliotek i forbindelse med JsonObject klassens tilJson og fraJson metoder til at serialisere og deserialisereenheder, men der er yderligere omkostninger ved at gøre det.

I stedet for til Dokument metode, bruger vi de flydende metoder til JsonObject klasse til at oprette og udfylde en JsonObject inden indpakning a JsonDocument:

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

Og til fra Dokument metode, bruger viJsonObject klassens getString metode sammen med setterne i Person klasse i vores fra Dokument metode:

@ Override offentlig person fra dokument (JsonDocument doc) {JsonObject indhold = doc.content (); Person p = ny person (); p.setId (doc.id ()); p.setType ("Person"); p.setName (content.getString ("navn")); p.setHomeTown (content.getString ("hjemby")); returnere p; }

4.4. CRUD-grænseflade

Vi opretter nu en generik CrudService interface, der definerer vedvarende operationer for enhedsklasser:

offentlig grænseflade CrudService {void create (T t); T read (String id); T readFromReplica (streng-id); ugyldig opdatering (Tt); ugyldig sletning (streng-id); boolsk findes (streng-id); }

4.5. Implementering af CRUD-tjenesten

Med enhed- og konvertererklasser på plads implementerer vi nu CrudService til Person enhed, indsprøjtning af bucket service og dokumentkonverter vist ovenfor og hentning af bucket under initialisering:

@Service offentlig klasse PersonCrudService implementerer CrudService {@Autowired private TutorialBucketService bucketService; @Autowired privat PersonDocumentConverter-konverter; privat spand spand; @PostConstruct privat ugyldigt init () {bucket = bucketService.getBucket (); } @ Overstyr offentlig tomrum oprette (Person person) {if (person.getId () == null) {person.setId (UUID.randomUUID (). ToString ()); } JsonDocument-dokument = converter.toDocument (person); bucket.insert (dokument); } @ Override offentlig person læst (streng-id) {JsonDocument doc = bucket.get (id); returnere (doc! = null? converter.fromDocument (doc): null); } @ Override offentlig person readFromReplica (streng-id) {Liste docs = bucket.getFromReplica (id, ReplicaMode.FIRST); returnere (docs.isEmpty ()? null: converter.fromDocument (docs.get (0))); } @Override offentlig ugyldig opdatering (Person person) {JsonDocument document = converter.toDocument (person); bucket.upsert (dokument); } @ Overstyr offentlig ugyldig sletning (streng-id) {bucket.remove (id); } @ Override offentlig boolsk findes (streng-id) {return bucket.exists (id); }}

5. At sætte det hele sammen

Nu hvor vi har alle delene af vores persistenslag på plads, her er et simpelt eksempel på en registreringstjeneste, der bruger PersonCrudService for at vedvare og hente registranter:

@Service offentlig klasse RegistrationService {@Autowired privat PersonCrudService crud; public void registerNewPerson (String name, String homeTown) {Person person = new Person (); person.setName (navn); person.setHomeTown (hjemby); crud.create (person); } offentlig person findRegistrant (streng-id) {prøv {return crud.read (id); } fange (CouchbaseException e) {return crud.readFromReplica (id); }}}

6. Konklusion

Vi har vist, at det med et par grundlæggende Spring-tjenester er ret trivielt at inkorporere Couchbase i en Spring-applikation og implementere et grundlæggende persistenslag uden at bruge Spring Data.

Kildekoden vist i denne vejledning er tilgængelig i GitHub-projektet.

Du kan lære mere om Couchbase Java SDK på det officielle Couchbase-udviklingsdokumentationswebsted.


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