Couchbase spring data

Couchbase and Spring data

Couchbase data is basically json data. Different from MySQL and Mongodb, it’s a little bit different. Anyway, let’s prepare to use spring data for couchbase

As for simple client programming, please check “Couchbase java

build.gradle

implementation 'org.springframework.boot:spring-boot-starter-data-couchbase'

This is dependency.

Prepare Entity (Document) class

This is similar with MongoDB.

We need to prepare data class to retrieve from

I prepared 2 types for this sample (simple one and nested data one)

In this example, I use “travel-sample” prepared by Couchbase.

Data is separated by “type” key. “airline”, “airport” etc… We can support multiple entity using “type” key.

TravelSample.java

This is very simple

import com.couchbase.client.java.repository.annotation.Field;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.couchbase.core.mapping.Document;

@Data
@Document
public class Airport {

    @Id
    private String id;

    @Field
    private String airportname;

    @Field
    private String city;

    @Field
    private String country;

    @Field
    private String faa;

    // Geo?
    @Field
    private Geo geo;

    @Field
    private String icao;

    @Field
    private String type;

    @Field
    private String tz;
}

@Data is lombok, @Documentation is an annotation to support couchbase entity

@Id is primary key for couchbase, and @Field indicates each data field

Airport.java

This has child class named “Geo”. Geo is also class

@Data
@Document
public class Airport {

    @Id
    private String id;

    @Field
    private String airportname;

    @Field
    private String city;

    @Field
    private String country;

    @Field
    private String faa;

    // Geo?
    @Field
    private Geo geo;

    @Field
    private String icao;

    @Field
    private String type;

    @Field
    private String tz;
}

Geo.java

@Data
public class Geo {

    private String alt;

    private String lat;

    private String lon;
}

Prepare Repository

Same as other datasource, we need to prepare

TravelSampleRepository.java

public interface TravelSampleRepository extends CouchbasePagingAndSortingRepository<TravelSample, String> {

    // List<TravelSample> findByCountry(String country);
    @Query("#{#n1ql.selectEntity} WHERE type='airline'")
    List<TravelSample> findAirlineBy();

    @Query("#{#n1ql.selectEntity} WHERE type='airport' LIMIT 10")
    List<Airport> findAirPort();

    @Query("#{#n1ql.selectEntity} WHERE type='airline' and country= $1")
    List<TravelSample> findAirlineByCountry(String country);
}

Unfortunately, some simple query prepared by spring-data does not work. In this example, findByCountry is not working. Different from other data sources, Couchbase has key for couchbase bucket.

To retrieve data, we should take care of type key. In this time, have WHERE clause to support each entity

Work with Spring Batch

In this time, let’s use Spring Batch

build.gradle

plugins {
    id 'org.springframework.boot' version '2.2.2.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id "io.freefair.lombok" version "4.1.6"
    id 'java'
}

group 'com.rakuten.reward.sample.couchbase'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-batch'
    implementation 'org.springframework.boot:spring-boot-starter-data-couchbase'
    implementation 'org.hsqldb:hsqldb'

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation 'org.springframework.batch:spring-batch-test'
}

HSQLDB is only for Spring Batch log.

CouchbaseConfig.java

This is couchbase connection configuration

@Configuration
@EnableCouchbaseRepositories(basePackages = {"com.rakuten.reward.sample.couchbase.springbatchcouchbase.couchbase"})
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {

    @Override
    protected List<String> getBootstrapHosts() {
        return Collections.singletonList("127.0.0.1");
    }

    @Override
    public Cluster couchbaseCluster() throws Exception {
        return CouchbaseCluster.create("localhost").authenticate("username", "password");
    }

    @Override
    public ClusterInfo couchbaseClusterInfo() throws Exception {
        Cluster cc = couchbaseCluster();
        ClusterManager manager = cc.clusterManager();
        return manager.info();
    }

    @Override
    protected String getBucketName() {
        return "travel-sample";
    }

    @Override
    protected String getBucketPassword() {
        return "";
    }

    /* {"callsign":"MILE-AIR","country":"United States","iata":"Q5","icao":"MLA","id":10,"name":"40-Mile Air","type":"airline"} */
}

This is an example, actually we can use spring configuration by application.yml

BatchConfiguration.java

This is simple batch job definition

@Configuration
@EnableBatchProcessing
@EnableAutoConfiguration
public class BatchConfiguration {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private TravelSampleRepository travelSampleRepository;

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet((StepContribution contribution, ChunkContext chunkContext)-> {
                    // List<TravelSample> list = travelSampleRepository.findAirlineBy();
                    // Works!
                    Optional<TravelSample> list2 = travelSampleRepository.findById("airline_10");

                    List<Airport> list3 = travelSampleRepository.findAirPort();

                    // By Country
                    List<TravelSample> list4 = travelSampleRepository.findAirlineByCountry("France");

                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Job job(Step step1, Step step2) throws Exception {
        return jobBuilderFactory.get("job1")
                .incrementer(new RunIdIncrementer())
                .start(step1)
                .build();
    }
}

Main.java

This is main function. (Just run Spring application)

@SpringBootApplication
public class Main {

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

}
Data
スポンサーリンク
Professional Programmer2

コメント