简体   繁体   中英

Migrating from Mysql to Cassandra Spring boot

I am totally new to Cassandra, this is the very first time, never used it before, so far we have been using Spring Boot and MySql as our DB, but now we are planning to migrate our database to Cassandra with the minimum code or no change. here is a sample demo of code that we have been using.

config class

package com.example.demo.config;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Generated;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
import static org.hibernate.cfg.AvailableSettings.*;
@Configuration
@EnableTransactionManagement
@EnableJpaAuditing
@EnableJpaRepositories(entityManagerFactoryRef = "orclEntityManagerFactory", transactionManagerRef = "orclTransactionManager", basePackages = {"com.example.demo.repository"})
@Generated
public class DataSourceConfig {
    @Value("${spring.datasource.driver-class-name}")
    private String orclDbDriver;
    @Value("${spring.datasource.url}")
    private String orclDbConnUrl;
    @Value("${spring.datasource.username}")
    private String orclDbUsername;
    @Value("${spring.datasource.password}")
    private String orclDbPassword;
    @Value("${spring.datasource.poolName}")
    private String dataSourcePoolName;
    @Value("${spring.jpa.properties.hibernate.dialect}")
    private String orclHibernateDialect;
    @Value("${spring.jpa.hibernate.ddl-auto}")
    private String hibernateDDL;
    @Value("${spring.jpa.show-sql}")
    private boolean showSql;
    @Value("${spring.datasource.packagesToScan}")
    private String[] packagesToScan;
    public DataSourceConfig() {
    }
    @Bean
    @Primary
    public DataSource orclDataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(this.orclDbDriver);
        dataSource.setJdbcUrl(this.orclDbConnUrl);
        dataSource.setUsername(this.orclDbUsername);
        dataSource.setPassword(this.orclDbPassword);
        dataSource.setPoolName(this.dataSourcePoolName);
        return dataSource;
    }
    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean orclEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(this.orclDataSource());
        factory.setPackagesToScan(this.packagesToScan);
        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setDatabase(Database.MYSQL);
        jpaVendorAdapter.setGenerateDdl(Boolean.TRUE);
        jpaVendorAdapter.setShowSql(showSql);
        jpaVendorAdapter.setDatabasePlatform(orclHibernateDialect);
        factory.setJpaVendorAdapter(jpaVendorAdapter);
        HashMap<String, Object> properties = new HashMap();
        properties.put(HBM2DDL_AUTO, this.hibernateDDL);
        properties.put(DIALECT, this.orclHibernateDialect);
        properties.put(STATEMENT_BATCH_SIZE, "500");
        properties.put(ORDER_UPDATES, "true");
        properties.put(ORDER_INSERTS, "true");
        properties.put(GENERATE_STATISTICS, "true");
        factory.setJpaPropertyMap(properties);
        return factory;
    }
    @Bean
    @Primary
    public JpaTransactionManager orclTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(this.orclEntityManagerFactory().getObject());
        return transactionManager;
    }
}

controller class

import com.example.demo.entity.Child;
import com.example.demo.repository.ChildRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.util.List;

@RestController
public class HelloController {
    @Autowired
    private ChildRepository childRepository;

    @GetMapping("put")
    public Child getHello() {
        Child child = new Child();
        child.setName("shrikant");
        child.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
        return childRepository.save(child);
    }

    @GetMapping("get")
    public List<Child> hello() {
        return childRepository.findAll();
    }
}

repository

package com.example.demo.repository;
import com.example.demo.entity.Child;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ChildRepository extends JpaRepository<Child, Long> {
}

 

application.dev

spring.datasource.url=jdbc:mysql://localhost:3306/student_db?jdbcCompliantTruncation=false&sessionVariables=sql_mode='NO_ENGINE_SUBSTITUTION'&useSSL=false&useServerPrepStmts=false&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.poolName=springHikariCp
spring.jpa.generate-ddl=true
spring.jpa.database.schema=student_db
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.datasource.packagesToScan=com.example.demo.entity
spring.profiles.active=dev

build.gradle

plugins {
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
repositories {
    mavenCentral()
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    compile 'mysql:mysql-connector-java'  
    annotationProcessor 'org.projectlombok:lombok' 
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
test {
    useJUnitPlatform()
}

I have installed Cassandra with the help of google and able to login using cqlsh .

created keyspace

CREATE KEYSPACE IF NOT EXISTS mykeyspace WITH replication = {'class':'SimpleStrategy', 'replication_factor':1};

added Cassandra dependency in Gradle

compile 'org.springframework.boot:spring-boot-starter-data-cassandra'

but what should be the configuration properties in the application.properties, I couldn't find any of the examples on Google creating a custom data source, all are using Spring Boot auto-config, but I can't do that, because that will be a major code change.

You need to use the CassandraRepository instead of JpaRepository interface

public interface ChildRepository extends CassandraRepository<Child, Long> { }

You need to have these properties in your application.properties

spring.data.cassandra.contact-points=127.0.0.1 (or your corresponding connection uri)
spring.data.cassandra.username=<username, if any>
spring.data.cassandra.password=<password, if any>
spring.data.cassandra.keyspace=default
spring.data.cassandra.port=9042
spring.data.cassandra.schema-action=NONE

Then you will be relatively fine. But like the other guys said in the comments section, it is quite important that you should understand the nature of Cassandra. If you don't implement your data model based on your queries, it won't be successful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM