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

우리나라에서는 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}")
            }
        }
    }
}

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


GUI Git 클라이언트 중 SmartGit를 그동안 써왔는데.. 


GitKraken을 쓰고나서 짜증이 나서 뒤도 안돌아보고 SmartGit로 돌아왔네요 



GitKraken이 SmartGit보다 안좋은 이유는 다음과 같습니다. 


1. 라이선스 문제. 

우선 GitKraken는 무료 라이선스말고 상용버전 라이선스는 구독 라이선스밖에 없습니다. 

이게 무슨 문제냐면 SmartGit도 구독 라이선스가 있지만 일반 라이선스도 별도 존재합니다. 

즉 라이선스 기간이 끝나고 나면 더이상 유료기능을 사용 할 수 없습니다. 

보통 일반적으로 라이선스 기간이 끝나면 업데이트는 안되지만 기존 버전에 대해서는 사용할 수 있는 권리를 가지고 있는데.. 구독 라이선스는 구독기간이 끝나면 사용 권한을 소멸 시켜버리죠.

물론 Smart Git도 그렇고 GitKraken도 비상업용 라이선스는 무료 사용이 가능 합니다. :)

(근데 GitKraken 인앱 충돌 편집기를... 유료버전기능으로 넘기다니.... )



2.파일 인코딩 문제 

Java나 최신 개발환경을 사용하고 있는 사람들은 별문제가 아닐 수 있으나... 

마찬가지로 크리티컬합니다. 

제가 테스트 해본건 윈도우 인데 아마 다른 OS도 마찬가지 일듯 싶습니다. 

UTF-8 파일이 아닌 EUC-KR 및 CP949 파일등에서 한글을 작성을 하면  GitKraken에서는 

한글이 깨져보입니다. 

Java처럼 기본 파일인코딩이 UTF-8을 사용할 경우는 별문제는 안될 수 있겠지만 

C++등에서는 중요한 문제가 될 수도 있겠죠...




3. 프로젝트 이름 별칭 가능 여부 

자신의 컴퓨터에 Git 프로젝트가 많다면 자기가 알아보기 싶데 그룹을 나누고 별칭을 붙이고 싶습니다.

하지만 그룹기능은 SmartGit나 GitKraken이나 전부 있지만...  프로젝트명에 별칭으로 변경하는건 GitKraken에서는 할수가 없네요. 무조건 디렉터리 이름이 프로젝트 명이 됩니다.

SmartGit는 별칭이 가능합니다. 





그래도 GitKraken을 써보고 싶었던 이유는 다크 테마 UI가 맘에 들었기때문입니다. 

물론 SmartGit도 최근 업데이트를 통해 다크 테마를 지원하긴 하지만 아직은 뭔가 반쪽자리 

테마라고 느껴지거든요.. 

스크롤바 색같은경우는 아직도 다크 테마에 현재 어울리지를 않네요.

Code refactorings are used to restructure your existing code without changing its external behaviour. The most popular is probably the Rename refactoring, which changes the name of a variable, method, class, etc. Refactoring is an essential technique to maintain the quality of your code, make it more readable and easier to maintain and reuse.

CLion offers you a set of code refactorings, which track down and correct the affected code references automatically. This means you can always be sure that your project will work correctly, even after large-scale changes. The list of refactorings available in CLion includes:

  • Rename (Shift+F6) renames symbols, automatically correcting all references in the code for you.
  • Change Signature (Ctrl+F6 on Windows/Linux, Cmd+F6 on OS X) helps you add/remove/reorder function parameters, change the result type or update the name of the function, all usages will be fixed as well.
  • Move (F6) moves files or directories, as well as methods, variables or constants.
  • Copy (F5) allows you to create a copy of file or directory.
  • Safe Delete (Alt+Delete on Windows/Linux, Cmd+Delete Forward on OS X) safely removes files and symbols from your code.
  • Inline (Ctrl+Alt+N on Windows/Linux, Alt+Cmd+N on OS X) replaces redundant variable usage/method calls with its initializer/declaration.
  • Extract refactoring – CLion analyses the block of code where the refactoring was invoked, detects input and output variables, together with the usages of the selected expression to replace them with the newly created:
    • Variable (Ctrl+Alt+V on Windows/Linux, Alt+Cmd+V on OS X)
    • Constant (Ctrl+Alt+C on Windows/Linux, Alt+Cmd+C on OS X)
    • Parameter (Ctrl+Alt+P on Windows/Linux, Alt+Cmd+P on OS X)
    • Typedef (Ctrl+Alt+K on Windows/Linux, Alt+Cmd+K on OS X)
    • Define (Ctrl+Alt+D on Windows/Linux, Alt+Cmd+D on OS X)
    • Method (Ctrl+Alt+M on Windows/Linux, Alt+Cmd+M on OS X)
  • Pull Members Up safely moves class members to a superclass.
  • Push Members Down safely moves class members to a subclass.

You can use Refactor This (Ctrl+Alt+Shift+T on Windows/Linux, Ctrl+T on OS X) to get the list of the refactorings available in the current scope.

Watch CLion’s refactorings in action:

기존에는 useoldmanifestmerger true 를 추가해서 처리 했지만..


안드로이드 스튜디오 정식 버전이 나오면서 useoldmanifestmerger를 찾을 수가 없다는 

에러가 발생한다. 


따라서 다른 방식으로 처리를 해야 한다. 


AndroidManifest.xml파일을 열어서 다음과 같이 프로퍼티를 추가한다. 


manifest 프로퍼티 추가 

xmlns:tools="http://schemas.android.com/tools"


application에 프로퍼티 추가 

tools:replace="theme, icon, label"


위에 있는 두분을 수정하면 이런 형식으로 나오게 된다. 




<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="homework.sample.app" >

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
tools:replace="theme, icon, label">

</application>

</manifest>


하지만 파이널판타지 ARR로 다시 돌아오다!


보는내내 남의 일이 아니고 내일 같은 느낌 들었다.

나의 어린 시간들은 어디로 갔을까~


 

그래 다 가져가라~ -ㅁ-a

 

헐....

 

 

헐.....

 

헐!!?

+ Recent posts