본문 바로가기
Kotlin

26. 코틀린 엑셀 + 데이터베이스

by NaHyungMin 2021. 8. 23.

수석 부장님이 파트너 은행의 목록 변경으로 인해 재등록을 하라고 하셨다.

원래는 운영을 전담하는 연구원이 하고 있었지만 때마침 휴가라 내가 등록해야 했다.

 

그런데 보니깐... 30분정도 하나씩 비교해가면서 해야 하는 노가다였다.

등록하고 다음날 연구원에게 물어보니, 변경될 때마다 그러고 있다고 했다. 경악..

 

그래서 그냥 파트너에서 들어온 Excel 데이터를 하이버네이트로 데이터베이스에 새로 만들어 버림.

 

코드는 다음과 같다.

dependencies {
    testImplementation(kotlin("test-junit5"))
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")

    implementation("org.apache.poi:poi:5.0.0")
    implementation("org.apache.poi:poi-ooxml:5.0.0")

    implementation("org.mariadb.jdbc:mariadb-java-client:2.7.4")
    implementation("org.hibernate:hibernate-core:5.5.6")
}

build.gradle.kts

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.mariadb.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mariadb://</property>
        <property name="hibernate.connection.username"></property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.MariaDBDialect</property>
        <property name="hibernate.jdbc.batch_size">1000</property>
        <property name="order_updates">true</property>
       <!-- <property name="hibernate.default_schema"></property>-->
        <property name="show_sql">true</property>
        <!--<property name="hbm2ddl.auto">none</property>-->
        <property name="hbm2ddl.auto">create</property>
        <mapping class="PartnerbankDto"></mapping>
    </session-factory>
</hibernate-configuration>

hibernate.cfg.xml

 

fun main(args: Array<String>) {
    println("Hello World!")
    val filePath: String = "D:\\City.xlsx";
    val partnerBankDtoList: List<PartnerbankDto> = ExcelParser().getPartnerBankDtoList(filePath)
    val batchSize: Int = 100

    HibernateUtil.getSessionFactory()!!.openSession().use {
        it.beginTransaction()

        for (i in partnerBankDtoList.indices) {
            it.save(partnerBankDtoList[i])

            if ((i % batchSize) == 0) {
                it.flush()
                it.clear()
            }
        }

        it.transaction.commit()
    }

    HibernateUtil.shutdown()
    println("Bye Hello World!")
}

main.kt

 

@Entity
@Table(name = "t_partner_bank_new")
class PartnerbankDto {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var seq:Int = 0

    @Column(name = "partner_id", length = 64)
    lateinit var partner_id: String

..........................

 

PartnerbankDto

 

import org.hibernate.SessionFactory
import org.hibernate.boot.Metadata
import org.hibernate.boot.MetadataSources
import org.hibernate.boot.registry.StandardServiceRegistry
import org.hibernate.boot.registry.StandardServiceRegistryBuilder

//https://howtodoinjava.com/hibernate/hibarnate-build-sessionfactory/
object HibernateUtil {
    private var sessionFactory: SessionFactory? = buildSessionFactory()
    private fun buildSessionFactory(): SessionFactory? {
        return try {
            if (sessionFactory == null) {
                val standardRegistry: StandardServiceRegistry = StandardServiceRegistryBuilder()
                    .configure("hibernate.cfg.xml").build()
                val metaData: Metadata? = MetadataSources(standardRegistry)
                    .metadataBuilder
                    .build()
                sessionFactory = metaData!!.sessionFactoryBuilder.build()
            }
            sessionFactory
        } catch (ex: Throwable) {
            throw ExceptionInInitializerError(ex)
        }
    }

    fun getSessionFactory(): SessionFactory? {
        return sessionFactory
    }

    fun shutdown() {
        getSessionFactory()?.close()
    }
}

HibernateUtil

 

import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.xssf.usermodel.XSSFSheet
import java.io.FileInputStream
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.math.BigDecimal
import java.sql.Date
import java.sql.Timestamp

class ExcelParser {

    fun getPartnerBankDtoList(filePath: String): List<PartnerbankDto> {
        val partnerBankDtoList: MutableList<PartnerbankDto> = mutableListOf()
        val fileInputStream: FileInputStream = FileInputStream(filePath)

        XSSFWorkbook(fileInputStream).use {
            val sheet: XSSFSheet = it.getSheetAt(0)
            val rowCount: Int = sheet.physicalNumberOfRows
            println(rowCount)

            for(row in sheet.rowIterator()) {
                row.getCell(0).cellType = CellType.STRING
                val cell0 = row.getCell(0)

                try {
                    cell0.stringCellValue.toIntOrNull() ?: continue

                    val partnerbankDto:PartnerbankDto = PartnerbankDto()

                    //Default
                    partnerbankDto.max_limit = BigDecimal(0.00000000)
                    partnerbankDto.create_time = Timestamp(java.util.Date().time)
                    partnerbankDto.update_time = Timestamp(java.util.Date().time)

                    //variable
                    partnerbankDto.bank_name1 = cellBankName.stringCellValue

                    partnerBankDtoList.add(partnerbankDto)
                } catch (ex : Exception) {
                    println(ex)
                }
            }
        }

        fileInputStream.close()
        return partnerBankDtoList
    }
}

ExcelParser

 

중요하다고 생각될 정보는 그냥 코드에서 지워버림.

제대로 등록이 되긴하는데, 하이버네이트가 테이블을 알파벳 순으로 만들어버린다.

인터넷 찾아보니, 안에 ddl 코드를 변경하면 되긴하는데... 그 정도까지 할 파서는 아니다.