요즘 재미삼아 스프링 공부를 해보고 있는데

우리나라에서는 Database를 사용할때 mybatis나 아니면 JPA를 쓰더군요

 

저는 어차피 재미 삼아 공부를 하는 거기때문에 Jetbrains에서 만든 Exposed가 눈에 띄었습니다.

Query 형 또는 Dao형 둘다 되더군요.. 

 

거기에다 저는 무려 Jetbrains의 노예이기 때문에..  한번 공부를 해야겠다는 마음을 먹고 이리저리 돌려보고 있었습니다.

 

이걸 여러개의 Database접근을 할 수 있는 내용을 찾아보다가 삽질하면서 만들어봤습니다.

프로젝트 스프링부트 프로젝트 빌드 타입은 Gradle 그리고 언어는 당연하게도 코틀린을 선택하였습니다.

 

(Jetbrains Exposed는 코틀린 전용 DB 프레임워크 라이브러리입니다..)

build.gradle.kts에서 dependencies부분에 Jetbrains exposed 라이브러리를 추가해야합니다..

dependencies {
    // with exposed
    implementation("org.jetbrains.exposed:exposed-spring-boot-starter:0.34.1")

}

application.yaml

spring:
  datasource:
    hikari:
      primary:
        driver-class-name: org.mariadb.jdbc.Driver
        jdbc-url: jdbc:mariadb://localhost:3306/db
        username: sa
        password: 1234!
        maximum-pool-size: 50
        max-lifetime: 30000
        idle-timeout: 28000
        connection-timeout: 0
        transaction-isolation: TRANSACTION_READ_UNCOMMITTED

      secondary:
        driver-class-name: org.mariadb.jdbc.Driver
        jdbc-url: jdbc:mariadb://localhost:3307/db
        username: sa
        password: 1234!
        maximum-pool-size: 50
        max-lifetime: 30000
        idle-timeout: 28000
        connection-timeout: 0
        transaction-isolation: TRANSACTION_READ_UNCOMMITTED

DataBaseConfig.kt

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.jetbrains.exposed.spring.SpringTransactionManager
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
import org.springframework.transaction.annotation.EnableTransactionManagement
import javax.sql.DataSource

@Configuration
@EnableTransactionManagement
class Datasource{
    @Bean
    @Primary
    @Qualifier("primaryHikariConfig")
    @ConfigurationProperties(prefix = "spring.datasource.hikari.primary")
    fun primaryHikariConfig(): HikariConfig? {
        return HikariConfig()
    }


    @Bean
    @Primary
    @Qualifier("primaryDataSource")
    @Throws(Exception::class)
    fun primaryDataSource(): DataSource? {
        return HikariDataSource(primaryHikariConfig())
    }

    @Bean
    @Qualifier("secondaryHikariConfig")
    @ConfigurationProperties(prefix = "spring.datasource.hikari.secondary")
    fun secondaryHikariConfig(): HikariConfig? {
        return HikariConfig()
    }

    @Bean
    @Qualifier("secondaryDataSource")
    @Throws(java.lang.Exception::class)
    fun secondaryDataSource(): DataSource? {
        return HikariDataSource(secondaryHikariConfig())
    }
}


@Configuration
@EnableTransactionManagement
class DatabaseConfig(
    @Qualifier("primaryDataSource") private val dataSource: DataSource, @Qualifier("secondaryDataSource") private val secondaryDataSource : DataSource
) {

    @Bean(name = ["PrimaryDB"])
    @Primary
    fun primaryTransactionManager() = SpringTransactionManager(dataSource)

    @Bean(name = ["SecondaryDataDB"])
    fun secondaryTransactionManager() = SpringTransactionManager(secondaryDataSource)
}

이제 한번 테스트로 두번째로 연결된 DB로 대충 만든 테이블을 Sleect 해보자...


import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

// name = "user"  테이블 이름이 user 라는 뜻 
// 테이블 이름지정 없이 할 경우 클래스 이름으로 테이블에 접근하게 된다. users 
// id 컬럼을 다른 이름으로 지정했을 경우 이런식으로 바꿀수도 있다.
object Users : IntIdTable(name = "user", columnName = "idx") {
    val name = varchar("user_id", 256)
    val pw = varchar("user_pw", 256)
}


class User(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<User>(Users)

    val name by Users.name
    val pw by Users.pw
}


@Service
@Transactional("SecondaryDataDB")
class UserRepository {
    fun showAll() {
        transaction {
            for (user in User.all()) {
                println("id: ${user.id.value}, name:${user.name} password: ${user.pw}")
            }
        }
    }
}

처음에는 스프링 자체도 낯설다 보니 헤맸지만 막상 하고 보니 어렵지는 않다.

+ Recent posts