본문 바로가기
Kotlin

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

by NaHyungMin 2021. 1. 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>는 한번 검색해봐야 한다.

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