Kotlin

25. 코틀린 데이터베이스 연동

NaHyungMin 2021. 1. 26. 11:26

자바 스프링, 스프링 부트 구조가 아닌 자바 콘솔 프로그래밍.

으. 하루 삽질하며 JDBC와 하이버네이트를 둘다 했다.

XML 파일 읽어와서 엘리먼트 이름이 ROW인 자식들을 찾아 데이터를 입력해주는 프로그램.

 

프로젝트 구조

 

 

build.gradle

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.4.21'
}

group '프로젝트 정보'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib"
    implementation "org.jetbrains.kotlin:kotlin-reflect:1.4.21"

    // https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client
    compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.1'

    // https://mvnrepository.com/artifact/org.hibernate/hibernate-core
    compile group: 'org.hibernate', name: 'hibernate-core', version: '5.4.27.Final'
}

 

hibernate.cfg.xml

<?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://url:3306/스키마</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">albatross</property>-->
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">none</property>
        <!--<property name="hbm2ddl.auto">create-drop</property>-->
        <mapping class="WatchDto"></mapping>
    </session-factory>
</hibernate-configuration>

 

Main.kt

import java.io.File

//http://klaus.hammermueller.at/paper/xml-sem/xml-sem.html
fun main(args: Array<String>) {
    /*WatchDto::class.java.declaredFields.forEach {
       // println(it.name)
    }*/

    //val dbManager: DBManager = DBManager()

    try {
        val xmlParser: XmlParser = XmlParser()
        val file: File = File("D:\\WLF_20210120.xml")
        val result = xmlParser.getXmlData(file)

        val session = HibernateUtil.getSessionFactory()!!.openSession()
       /* result.forEach {
            session.save(it)
        }*/

        val batchSize:Int = 1000

        //flush

        session.beginTransaction()

        for(i in 0 until result.count()) {
            session.save(result[i])

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

        session.transaction.commit()
        HibernateUtil.shutdown()

        /*val insertQuery = "INSERT INTO table(data_div, json) \n" +
                "VALUES (?, ?)";

        dbManager.insertList(insertQuery, result);*/
    } catch (ex: Exception) {
        println(ex.message)
    } finally {
        //dbManager.finalize()
    }

    println("Hello, world!")
}

 

WatchDto

import db_interface.IInsert
import db_interface.ISelect
import javax.persistence.*


@Entity
@Table(name = "테이블명")
class WatchDto {

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

    //not-null property references a null or transient value : WatchDto.data_div
    //@Column(name = "data_div", unique = false, nullable = false, length = 128)
    @Column(name = "data_div", length = 128)
    lateinit var data_div: String

    @Column(columnDefinition="TEXT")
    lateinit var json: String

    constructor() {
    }
}

 

XmlParser

import org.w3c.dom.Document
import org.w3c.dom.NodeList
import java.io.File
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory

class XmlParser {
    fun getXmlData(xmlFile: File) : List<WatchDto> {
        val watchDtoList: MutableList<WatchDto> = mutableListOf()

        val builderFactory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
        val builder: DocumentBuilder = builderFactory.newDocumentBuilder()
        val document: Document = builder.parse(xmlFile)

        document.documentElement.normalize()

        val nodeList = document.getElementsByTagName("ROW")

        for (i in 0 until nodeList.length) {
            val childNodes: NodeList = nodeList.item(i).childNodes
            val watchDto = WatchDto()

            for (j in 0 until childNodes.length) {
                val nodeName:String = childNodes.item(j).nodeName.toLowerCase()
                if(watchDto.javaClass.declaredFields.any { it.name == nodeName  } == true){
                    watchDto.javaClass.getDeclaredField(nodeName).set(watchDto, childNodes.item(j).textContent)
                }
            }

            watchDtoList.add(watchDto);
        }

        return watchDtoList;
    }
}

 

HibernateUtil

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()
    }
}

 

 

추가 파일로 되어 있는 DBManager는 JDBC 정보라 추가할 필요가 없다.

hibernate.cfg.xml에서 <property name="hbm2ddl.auto">none</property>는 한번 검색해봐야 한다.

안 그러면 테이블이 날라가버릴걸...?? 마음대로 수정이 되거나!! 참고 하시길.