hgw8837 2024-12-30
20241230 하관우 back-end 최초커밋
@317bb2bb44d9f34e4134388d39b860b7f6b13c49
 
.gitignore (added)
+++ .gitignore
@@ -0,0 +1,39 @@
+HELP.md
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+/logs/
 
build.gradle (added)
+++ build.gradle
@@ -0,0 +1,112 @@
+plugins {
+	id 'java'
+	id 'org.springframework.boot' version '3.2.1'
+	id 'io.spring.dependency-management' version '1.1.4'
+}
+
+group = 'com.takensoft'
+version = '0.0.1-SNAPSHOT'
+apply plugin:'war'
+
+java {
+	sourceCompatibility = '17'
+}
+
+repositories {
+	mavenCentral()
+}
+
+dependencies {
+
+	// postgresql jdbc
+	implementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0'
+	// 오라클 jdbc
+	implementation group: 'com.oracle.database.jdbc', name: 'ojdbc11', version: '21.8.0.0'
+	// 마리아 jdbc
+	implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '3.3.2'
+	// mysql jdbc
+	implementation group: 'com.mysql', name: 'mysql-connector-j', version: '8.0.33'
+	// mssql jdbc
+	implementation group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version: '12.4.2.jre11'
+
+	// cron-utils 라이브러리 추가
+	implementation 'com.cronutils:cron-utils:9.1.3'
+	// mybatis
+	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
+
+	// sftp
+	implementation 'com.jcraft:jsch:0.1.55'
+
+	//lombok 라이브러리
+	compileOnly 'org.projectlombok:lombok'
+	annotationProcessor 'org.projectlombok:lombok'
+	testCompileOnly 'org.projectlombok:lombok'
+	testAnnotationProcessor 'org.projectlombok:lombok'
+	
+	// https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
+	implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
+	// https://mvnrepository.com/artifact/org.json/json
+	implementation group: 'org.json', name: 'json', version: '20231013'
+	// https://mvnrepository.com/artifact/org.springframework.security/spring-security-crypto
+	implementation group: 'org.springframework.security', name: 'spring-security-crypto', version: '6.2.1'
+	// https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
+	//compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
+	implementation 'org.springframework.boot:spring-boot-starter'
+	implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
+	// Log4j2 스타터
+	implementation 'org.springframework.boot:spring-boot-starter-log4j2'
+	// https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310
+	implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
+
+	// 웹 푸시 라이브러리
+	implementation group: 'nl.martijndwars', name: 'web-push', version: '5.1.1'
+	implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.70'
+
+	//poi
+	implementation 'org.apache.poi:poi:5.2.5'
+	implementation 'org.apache.poi:poi-ooxml:5.2.5'
+
+	// Super CSV 라이브러리 추가
+	implementation 'net.sf.supercsv:super-csv:2.4.0'
+	//Open CSV 라이브러리 추가
+	implementation group: 'com.opencsv', name: 'opencsv', version: '5.5.2'
+
+	// 기본
+	implementation 'org.springframework.boot:spring-boot-starter-web'
+	testImplementation 'org.springframework.boot:spring-boot-starter-test'
+
+	// API 게이트 웨이
+	implementation files('libs/apim-gateway-auth-1.1.jar')
+
+	// 새올 추가
+	implementation files('libs/commons-beanutils-1.8.3.jar')
+	implementation files('libs/commons-collections-3.2.1.jar')
+	implementation files('libs/commons-lang-2.5.jar')
+	implementation files('libs/commons-logging-1.1.1.jar')
+	implementation files('libs/crypto.jar')
+	implementation files('libs/ezmorph-1.0.2.jar')
+	implementation files('libs/httpclient-4.3.5.jar')
+	implementation files('libs/httpcore-4.3.2.jar')
+	implementation files('libs/json-lib-2.4-jdk15.jar')
+
+
+	providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
+
+	// 지원되지 않은 오라클 DB 문자 집합 문제 해결용
+	implementation group: 'com.oracle.ojdbc', name: 'orai18n', version: '19.3.0.0'
+}
+
+configurations {
+	all {
+		exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
+	}
+}
+
+tasks.named('test') {
+	useJUnitPlatform()
+}
+
+bootJar{
+	archiveBaseName="takenbimanager"
+	archiveVersion=version
+}(파일 끝에 줄바꿈 문자 없음)
 
gradle/wrapper/gradle-wrapper.jar (Binary) (added)
+++ gradle/wrapper/gradle-wrapper.jar
Binary file is not shown
 
gradle/wrapper/gradle-wrapper.properties (added)
+++ gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Dec 27 17:54:29 KST 2023
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
 
gradlew (added)
+++ gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"
 
gradlew.bat (added)
+++ gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
 
libs/apim-gateway-auth-1.1.jar (Binary) (added)
+++ libs/apim-gateway-auth-1.1.jar
Binary file is not shown
 
libs/commons-beanutils-1.8.3.jar (Binary) (added)
+++ libs/commons-beanutils-1.8.3.jar
Binary file is not shown
 
libs/commons-collections-3.2.1.jar (Binary) (added)
+++ libs/commons-collections-3.2.1.jar
Binary file is not shown
 
libs/commons-lang-2.5.jar (Binary) (added)
+++ libs/commons-lang-2.5.jar
Binary file is not shown
 
libs/commons-logging-1.1.1.jar (Binary) (added)
+++ libs/commons-logging-1.1.1.jar
Binary file is not shown
 
libs/crypto.jar (Binary) (added)
+++ libs/crypto.jar
Binary file is not shown
 
libs/ezmorph-1.0.2.jar (Binary) (added)
+++ libs/ezmorph-1.0.2.jar
Binary file is not shown
 
libs/httpclient-4.3.5.jar (Binary) (added)
+++ libs/httpclient-4.3.5.jar
Binary file is not shown
 
libs/httpcore-4.3.2.jar (Binary) (added)
+++ libs/httpcore-4.3.2.jar
Binary file is not shown
 
libs/json-lib-2.4-jdk15.jar (Binary) (added)
+++ libs/json-lib-2.4-jdk15.jar
Binary file is not shown
 
settings.gradle (added)
+++ settings.gradle
@@ -0,0 +1,1 @@
+rootProject.name = 'taken_bi_manager'
 
src/main/java/com/takensoft/taken_bi_manager/DBConnectTest.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/DBConnectTest.java
@@ -0,0 +1,54 @@
+package com.takensoft.taken_bi_manager;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionUtil;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.vo.CheckMessage;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+
+public class DBConnectTest {
+	public static void main(String[] args) throws Exception {
+
+		try {
+			Calendar cal = Calendar.getInstance();
+
+
+			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmm");
+
+			cal.add(12, -10);
+
+			int i = 0;
+
+
+			while (i <= 20) {
+				cal.add(12, 1);
+				String keyTime = df.format(cal.getTime());
+
+
+				++i;
+
+				if(i == 10){
+					int s = 0/0;
+				}
+			}
+
+
+
+		}catch (Exception e){
+
+
+		}
+
+
+		
+		
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/MemberSelectTest.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/MemberSelectTest.java
@@ -0,0 +1,60 @@
+package com.takensoft.taken_bi_manager;
+
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import com.takensoft.taken_bi_manager.common.connection.api.util.ApiUtil;
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam;
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.data.util.DataTableConvert;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+
+
+public class MemberSelectTest {
+		
+	public static void main(String[] args) throws Exception {
+		
+			DataTable dt = new DataTable();
+			
+			ConnectionApi ca = new ConnectionApi();
+			ca.setUrl("http://61.82.138.90:10971/aiSafetyCrossing/requestLogInfo.json");
+			ca.setType(1);
+			ca.setRequestType(1);
+			ca.setDepth("resultData>");
+			ApiParam apiParam1 = new ApiParam();
+			apiParam1.setKey("st_dt");
+			apiParam1.setValue("yyyy-MM-dd 10:22:00");
+			apiParam1.setDateForm(true);
+//			apiParam1.setDateType("month");
+			apiParam1.setAddMonth(0);
+			ca.getParams().add(apiParam1);
+			ApiParam apiParam2 = new ApiParam();
+			apiParam2.setKey("ed_dt");
+			apiParam2.setValue("yyyy-MM-dd 10:24:00");
+			apiParam2.setDateForm(true);
+//			apiParam2.setDateType("month");
+			apiParam2.setAddMonth(0);
+			ca.getParams().add(apiParam2);
+			ApiParam apiParam3 = new ApiParam();
+			apiParam3.setKey("apiKey");
+			apiParam3.setValue("f66b623060d0f20fee9663b8c0e445dc882cbf4ec4543630abd16c7960be7012");
+			ca.getParams().add(apiParam3);
+			
+			List<Map<String,Object>> data = ApiUtil.getApiDataList(ApiUtil.apiRequest(ca));
+			
+			dt = DataTableConvert.listMaptoDataset(data);
+			
+			int co = 0;
+			for(List<Object> temp: dt.getRowData()) {				
+
+				if(co == 9 ) co = 0;
+			}
+			
+
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/TakenBiManagerApplication.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/TakenBiManagerApplication.java
@@ -0,0 +1,47 @@
+package com.takensoft.taken_bi_manager;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
+
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
+@SpringBootApplication
+@EnableScheduling
+class TakenBiManagerApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(TakenBiManagerApplication.class, args);
+	}
+
+	@Bean(name="jsonView")
+	public MappingJackson2JsonView getJsonView () {
+		ObjectMapper objectMapper = getObjectMapper();
+		MappingJackson2JsonView jsonView = new MappingJackson2JsonView(objectMapper);
+		jsonView.setExtractValueFromSingleKeyModel(true);
+		return jsonView;
+	}
+
+	@Bean(name = "objectMapper")
+	public ObjectMapper getObjectMapper() {
+		ObjectMapper mapper = new ObjectMapper();
+
+		mapper.registerModule(new JavaTimeModule());
+		//기본 날짜 포맷 비활성화
+		mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+		//새로운 날짜 포맷 세팅
+		/*SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		mapper.setDateFormat(dateFormat);
+		mapper.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));*/
+
+		return mapper;
+	}
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/code/dao/CmmnCodeDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/dao/CmmnCodeDAO.java
@@ -0,0 +1,27 @@
+package com.takensoft.taken_bi_manager.common.code.dao;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.takensoft.taken_bi_manager.common.code.vo.CmmnCode;
+import com.takensoft.taken_bi_manager.user.member.vo.Member;
+
+/**
+ * @author 김성원
+ * @since 2021.01.18
+ * 
+ * 공통코드 처리 관련 DAO 클래스
+ */
+@Mapper
+public interface CmmnCodeDAO {
+	
+	/**
+	 * @author 김성원
+	 * @since 2021.01.10
+	 * 
+	 * 그룹아이디밑 코드 리스트 가져오기
+	 */
+	 public List<CmmnCode> getCodeListByGroupId(String groupId) throws Exception;
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/code/service/CmmnCodeService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/service/CmmnCodeService.java
@@ -0,0 +1,16 @@
+package com.takensoft.taken_bi_manager.common.code.service;
+
+import java.util.List;
+
+import com.takensoft.taken_bi_manager.common.code.vo.CmmnCode;
+
+public interface CmmnCodeService {
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.19
+	 * 
+	 * 공통코드 리스트 가져오기
+	 */
+	public List<CmmnCode> getCodeListByGroupId(String groupId) throws Exception;	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/code/service/impl/CmmnCodeServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/service/impl/CmmnCodeServiceImpl.java
@@ -0,0 +1,24 @@
+package com.takensoft.taken_bi_manager.common.code.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.takensoft.taken_bi_manager.common.code.dao.CmmnCodeDAO;
+import com.takensoft.taken_bi_manager.common.code.service.CmmnCodeService;
+import com.takensoft.taken_bi_manager.common.code.vo.CmmnCode;
+
+@Service
+public class CmmnCodeServiceImpl implements CmmnCodeService {
+	
+	@Autowired
+	private CmmnCodeDAO cmmnCodeDAO;
+
+	@Override
+	public List<CmmnCode> getCodeListByGroupId(String groupId) throws Exception {
+		// TODO Auto-generated method stub
+		return cmmnCodeDAO.getCodeListByGroupId(groupId);
+	}
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnCode.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnCode.java
@@ -0,0 +1,52 @@
+package com.takensoft.taken_bi_manager.common.code.vo;
+
+import java.sql.Timestamp;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2023-12-28
+ * 
+ * 공통코드 객체
+ */
+@Getter
+@Setter
+public class CmmnCode {
+	
+	
+	// 콩통코드  
+	private String cmmnCode;
+	
+	// 그룹코드
+	private String groupCode;
+	
+	// 코드명 
+	private String codeNm;
+	
+	// 코드 설명
+	private String codeDc;
+	
+	// 상위코드 (없으면 생략)
+	private String upperCode;
+	
+	// 코드 정렬순서 
+	private String codeOrdr;
+	
+	// 코드 사용여부
+	private boolean useAt;
+	
+	// 생성일
+	private Timestamp creatDt;
+	
+	// 생성자ID
+	private String creatId;
+	
+	// 수정일 
+	private Timestamp updtDt;
+		
+	// 수정자 ID
+	private String updtId;
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnGroup.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnGroup.java
@@ -0,0 +1,42 @@
+package com.takensoft.taken_bi_manager.common.code.vo;
+
+import java.sql.Timestamp;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2023-12-28
+ * 
+ * 공통코드 그룹 객체
+ */
+@Getter
+@Setter
+public class CmmnGroup {
+
+	// 공통코드 그룹 코드
+	private String groupCode;
+	
+	// 공통코드 그룹 코드 명 
+	private String groupCodeNm;
+	
+	// 공통코드 그룹 설명 
+	private String groupCodeDc;
+	
+	// 공통코드 그룹 사용여부
+	private boolean useAt;
+	
+	// 생성일
+	private Timestamp creatDt;
+	
+	// 생성자ID
+	private String creatId;
+	
+	// 수정일 
+	private Timestamp updtDt;
+		
+	// 수정자 ID
+	private String updtId;
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/config/FilterConfig.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/FilterConfig.java
@@ -0,0 +1,21 @@
+package com.takensoft.taken_bi_manager.common.config;
+
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.takensoft.taken_bi_manager.common.config.filter.SessionCheck;
+
+@Configuration
+public class FilterConfig {
+
+	@Bean
+    public FilterRegistrationBean<SessionCheck> sessionCheck() {
+        FilterRegistrationBean<SessionCheck> registrationBean = new FilterRegistrationBean<>();
+        registrationBean.setFilter(new SessionCheck());
+        registrationBean.addUrlPatterns("/*");
+        registrationBean.setOrder(1);
+        registrationBean.setName("sessionCheck");
+        return registrationBean;
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/config/MybatisConfig.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/MybatisConfig.java
@@ -0,0 +1,5 @@
+package com.takensoft.taken_bi_manager.common.config;
+
+public class MybatisConfig {
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/config/filter/SessionCheck.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/filter/SessionCheck.java
@@ -0,0 +1,52 @@
+package com.takensoft.taken_bi_manager.common.config.filter;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import org.springframework.web.filter.GenericFilterBean;
+import org.springframework.web.util.ContentCachingResponseWrapper;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.util.AuthUtil;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+public class SessionCheck extends GenericFilterBean {
+
+	@Override
+	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+		 throws IOException, ServletException {		
+	
+		 HttpServletRequest  httpServletRequest = (HttpServletRequest)request;
+		 String uri =httpServletRequest.getRequestURI().toString();		 
+		 chain.doFilter(request, response);
+		 // 로그인 세션 처리 (없으면 세션 없음 메세지 전달)
+	/*	 if(!uri.trim().contains("/login")) {
+			 HashMap<String, Object> LoginUserInfo = (HashMap<String, Object>)httpServletRequest.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION);
+			 if(LoginUserInfo == null) {
+				 ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);
+				 chain.doFilter(request, responseWrapper);
+				 CustomeResultMap map = new CustomeResultMap();
+				 map.getCheckMessage().setError("로그인 정보가 없습니다.");
+				 map.getCheckMessage().setStatus(100);
+				 map.getCheckMessage().setSuccess(false);
+				 
+				 String newResponse = new ObjectMapper().writeValueAsString(map);
+			     response.setContentType("application/json");
+			     response.setContentLength(newResponse.length());
+			     response.getOutputStream().write(newResponse.getBytes());				
+			 }else {
+
+				 chain.doFilter(request, response);
+			 }
+		 }		 
+        */
+	}
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/dao/ConnectionApiDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/dao/ConnectionApiDAO.java
@@ -0,0 +1,21 @@
+package com.takensoft.taken_bi_manager.common.connection.api.dao;
+
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam;
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface ConnectionApiDAO {
+
+    public void apiConnectionInfoInsert(ConnectionApi connectionApi) throws Exception;
+
+    public void apiParameterInfoInsert(ApiParam apiParam)throws Exception;
+
+    public int deletefilterItem(ConnectionApi connectionApi)throws Exception;
+
+    public ConnectionApi selectConnectionApi(String connectionId)throws Exception;
+
+    public int  deleteApiConnectionInfo(String groupId)throws Exception;
+
+    public int  deleteApiParameterInfo(String groupId)throws Exception;
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/service/ConnectionApiService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/service/ConnectionApiService.java
@@ -0,0 +1,48 @@
+package com.takensoft.taken_bi_manager.common.connection.api.service;
+
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+
+import java.util.*;
+
+public interface ConnectionApiService {
+    /**
+     * @author 박정하
+     * @since 2024.11.27
+     *
+     * OpenApi 호출
+     */
+    public HashMap<String, Object> apiRequestTest(ConnectionApi params) throws Exception;
+
+    /**
+     * @author 이원호
+     * @since 2021.11.03
+     *
+     * OpenApi 호출
+     */
+    public DataTable apiRequest(ConnectionApi connApi ) throws Exception;
+
+    /**
+     * @author 이원호
+     * @since 2021.11.10
+     *
+     * API 연계정보 등록
+     */
+    public void apiConnectionInfoInsert(ConnectionApi connectionApi) throws Exception;
+
+    /**
+     * @author 이원호
+     * @since 2021.11.10
+     *
+     * 연계API 파라미터 정보 등록
+     */
+    public void apiParameterInfoInsert(ConnectionApi connectionApi) throws Exception;
+
+    /**
+     * @author 이원호
+     * @since 2021.11.10
+     *
+     * 연계API 정보 가져오기
+     */
+    public ConnectionApi selectConnectionApi(String connectionId) throws Exception;
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/service/impl/ConnectionApiServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/service/impl/ConnectionApiServiceImpl.java
@@ -0,0 +1,235 @@
+package com.takensoft.taken_bi_manager.common.connection.api.service.impl;
+
+import com.takensoft.taken_bi_manager.common.connection.api.dao.ConnectionApiDAO;
+import com.takensoft.taken_bi_manager.common.connection.api.service.ConnectionApiService;
+import com.takensoft.taken_bi_manager.common.connection.api.util.DataUtil;
+import com.takensoft.taken_bi_manager.common.connection.api.util.SeolAPIUtil;
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam;
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.HTTPUtil;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import lombok.RequiredArgsConstructor;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Service
+@RequiredArgsConstructor
+public class ConnectionApiServiceImpl implements ConnectionApiService {
+    private final ConnectionApiDAO connectionApiDAO;
+
+    private Map<String, Object> findKeyResult = new HashMap<>();
+
+    @Override
+    public HashMap<String, Object> apiRequestTest(ConnectionApi connApi) throws Exception {
+        List<String> keys = new ArrayList<>();
+
+        if (connApi.getType() != 3) {
+            CommonUtil commonUtil = new CommonUtil();
+            HTTPUtil httpcon = new HTTPUtil();
+            String result = httpcon.HttpGetConnectionApi(connApi.getUrl(), connApi.getParams());
+            connApi.setResult(result);
+
+            if(connApi.getType() == 2) {
+                String jsonStr = commonUtil.xmlStrToJsonStr(connApi.getResult());
+                connApi.setResult(jsonStr);
+            }
+
+            JSONParser parser = new JSONParser();
+            JSONObject jsonObject = null;
+            JSONArray jsonArray = null;
+            if(connApi.getResult().substring(0,1).equals("[")) {
+                jsonArray = (JSONArray) parser.parse(connApi.getResult());
+            } else {
+                jsonObject = (JSONObject) parser.parse(connApi.getResult());
+            }
+
+            if(jsonObject != null) {
+                Map<String, Object> map = commonUtil.jsonObjectToMap(jsonObject);
+
+                if (map.containsKey("response")) {
+                    Map<String, Object> response = (Map<String, Object>) map.get("response");
+                    if (response.containsKey("body")) {
+                        Map<String, Object> body = (Map<String, Object>) response.get("body");
+                        if (body.containsKey("item")) {
+                            keys.add("response>body>item");
+                        } else if (body.containsKey("items")) {
+                            if (body.get("items").toString().substring(0,1).equals("[")) {
+                                keys.add("response>body>items");
+                            } else {
+                                keys.add("response>body>items>item");
+                            }
+                        }
+                    }
+                } else {
+                    String keyString = result.substring(0, result.indexOf('['));
+                    String[] keysArray = keyString.split(",");
+                    String key = keysArray[keysArray.length - 1].substring(1, keysArray[keysArray.length - 1].length() - 2);
+
+                    findKeyResult = new HashMap<>();
+                    findKeyResult.put("key", null);
+                    findKeyResult.put("totalRow", 0);
+                    findKey(map, key);
+
+                    keys.add((String) findKeyResult.get("key"));
+                }
+            }
+        }
+
+        HashMap<String, Object> resultMap = new HashMap<>();
+        resultMap.put("key", keys);
+        return resultMap;
+    }
+
+    private void findKey(Map<String, Object> map, String key) {
+        for (Map.Entry<String, Object> entrySet : map.entrySet()) {
+            if (entrySet.getKey().equals(key)) {
+                String resultKey = (String) findKeyResult.get("key");
+                if (resultKey == null) {
+                    findKeyResult.put("key", entrySet.getKey() + ">");
+                } else {
+                    findKeyResult.put("key", resultKey + entrySet.getKey() + ">");
+                }
+                List<HashMap<String, Object>> datas = (List<HashMap<String, Object>>) entrySet.getValue();
+                findKeyResult.put("totalRow", datas.size());
+            } else {
+                if (entrySet.getValue() instanceof Map) {
+                    Map<String, Object> newMap = (Map<String, Object>) entrySet.getValue();
+                    findKey(newMap, key);
+                }
+            }
+        }
+    }
+
+    @Override
+    public DataTable apiRequest(ConnectionApi connApi) throws Exception {
+        List<ApiParam> paramList = connApi.getParams();
+        List<ApiParam> realParams = new ArrayList<>();
+        HashMap<String, Integer> pageParams = new HashMap<>();
+        for (ApiParam param : paramList) {
+            if (param.getIndex() < 0) {
+                pageParams.put(param.getKey(), (Integer) param.getValue());
+            } else {
+                realParams.add(param);
+            }
+        }
+
+        DataTable dataTable = new DataTable();
+        if (connApi.getType() != 3) {
+            CommonUtil commonUtil = new CommonUtil();
+            HTTPUtil httpcon = new HTTPUtil();
+            connApi.setResult(httpcon.HttpGetConnectionApi(connApi.getUrl(), realParams));
+
+            if(connApi.getType() == 2) {
+                String jsonStr = commonUtil.xmlStrToJsonStr(connApi.getResult());
+                connApi.setResult(jsonStr);
+            }
+
+            JSONParser parser = new JSONParser();
+            JSONObject jsonObject = null;
+            JSONArray jsonArray = null;
+            if(connApi.getResult().substring(0,1).equals("[")) {
+                jsonArray = (JSONArray) parser.parse(connApi.getResult());
+            } else {
+                jsonObject = (JSONObject) parser.parse(connApi.getResult());
+            }
+
+            List<Map<String,Object>> dataList = new ArrayList<>();
+
+            // depth 리스트
+            if(jsonArray == null) {
+                // jsonObject to Map
+                Map<String, Object> resultMap = commonUtil.jsonObjectToMap(jsonObject);
+                String [] depthList = connApi.getDepth().split(">");
+
+                int deptCount = 0;
+                for(String depth : depthList) {
+                    deptCount++;
+                    depth = depth.trim();
+                    Object temp = (Object)resultMap.get(depth);
+                    // 리스트 판별
+                    if(temp instanceof List) {
+                        if (deptCount < depthList.length) {
+                            List<Map<String, Object>> tempList = (List<Map<String, Object>>) temp;
+                            resultMap =  tempList.get(0);
+                        } else {
+                            dataList = (List<Map<String, Object>>) temp;
+                        }
+                    }else {
+                        resultMap = (Map<String, Object>) temp;
+                    }
+                }
+            }else {
+                dataList = (List<Map<String, Object>>)jsonArray;
+            }
+
+            int max = 0;
+            int indx = 0;
+
+            // 최대 길이의 키값을 가진 객체 구하기
+            for(int i = 0 ; i < dataList.size() ; i++){
+                if(dataList.get(i).keySet().size() > max) {
+                    max = dataList.get(i).keySet().size();
+                    indx = i;
+                }
+            }
+            // 빈정보 공백으로 채우기
+            for(Map<String, Object> item : dataList ) {
+                if(max != item.size()) {
+                    for (Map.Entry<String, Object> entry : dataList.get(indx).entrySet())
+                    {
+                        if(item.get(entry.getKey()) == null) {
+                            item.put(entry.getKey(),"");
+                        }
+                    }
+                }
+            }
+
+            dataTable = DataUtil.setMaptoDataTable(dataList);
+            DataUtil.setColumnMetaData(dataTable, false);
+            DataTypeUtil.convertDataTableColumMeta(dataTable);
+        } else {
+            SeolAPIUtil seolAPIUtil = new SeolAPIUtil();
+            dataTable = seolAPIUtil.getSeolMain("http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213", "5110000SOI001");
+        }
+
+        List<List<Object>> rowData = dataTable.getRowData();
+        Integer onePageRow = pageParams.get("onePageRow");
+        Integer currentPage = pageParams.get("currentPage");
+        if (onePageRow != null && onePageRow != 0) {
+            int start = currentPage == 1 ? 0 : onePageRow * (currentPage - 1);
+            int end = start + onePageRow;
+
+            List<List<Object>> newRowData = new ArrayList<>();
+            for (int i = start; i < end; i++) {
+                newRowData.add(rowData.get(i));
+            }
+            dataTable.setRowData(newRowData);
+        }
+
+        return dataTable;
+    }
+
+    @Override
+    public void apiConnectionInfoInsert(ConnectionApi connectionApi) throws Exception {
+        connectionApiDAO.apiConnectionInfoInsert(connectionApi);
+    }
+
+    @Override
+    public void apiParameterInfoInsert(ConnectionApi connectionApi) throws Exception {
+        for(int i=0; i<connectionApi.getParams().size(); i++) {
+            connectionApi.getParams().get(i).setParamId(connectionApi.getConnectionId());
+            connectionApiDAO.apiParameterInfoInsert(connectionApi.getParams().get(i));
+        }
+    }
+
+    @Override
+    public ConnectionApi selectConnectionApi(String connectionId) throws Exception {
+        return connectionApiDAO.selectConnectionApi(connectionId);
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/ApiUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/ApiUtil.java
@@ -0,0 +1,132 @@
+package com.takensoft.taken_bi_manager.common.connection.api.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.HTTPUtil;
+
+/**
+ * @author 김성원
+ * @since 2024.01.12
+ * 
+ * API 연계 관련 기능 리스트 입니다. 
+ */
+public class ApiUtil {
+	/**
+	 * @author 김성원
+	 * @since 2024.01.12
+	 * 
+	 * OpenApi 데이터 수집 기능 
+	 */
+	public static ConnectionApi apiRequest(ConnectionApi connApi) throws Exception {
+		ObjectMapper mapper = new ObjectMapper();
+
+		// 새올데이터 API 데이터 수집
+		if (connApi.getType() == 3) {
+			SeolAPIUtil seolAPIUtil = new SeolAPIUtil();
+			DataTable dataTable = seolAPIUtil.getSeolMain("http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213", "5110000SOI001");
+			connApi.setResult(dataTable.toString());
+		} else {
+			HTTPUtil httpcon = new HTTPUtil();
+			connApi.setResult(httpcon.HttpGetConnectionApi(connApi.getUrl(), connApi.getParams()));
+		}
+	
+        return connApi;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.12
+	 * 
+	 * OpenApi 데이터 수집 기능 
+	 */
+	public static List<Map<String,Object>>  getApiDataList (ConnectionApi connApi) throws Exception{
+		ObjectMapper mapper = new ObjectMapper();
+
+		// depth 리스트
+		String [] depthList = connApi.getDepth().split(">");
+		CommonUtil commonUtil = new CommonUtil();
+
+		// Return Type :  1=JSON, 2=XML
+		if(connApi.getType() ==2) {
+			// XML String to JSON String
+			String jsonStr = commonUtil.xmlStrToJsonStr(connApi.getResult());
+			connApi.setResult(jsonStr);
+		}
+		
+		JSONParser parser = new JSONParser();		
+		
+		JSONObject jsonObject = null;
+		JSONArray jsonArray = null;
+		
+		if(connApi.getResult().substring(0,1).equals("[")) {
+			jsonArray = (JSONArray) parser.parse(connApi.getResult());
+		}else {
+			jsonObject = (JSONObject) parser.parse(connApi.getResult());
+		}
+		
+		List<Map<String, Object>> apiDataList = new ArrayList<Map<String, Object>>();
+		
+		if(jsonArray == null) {
+			// jsonObject to Map
+			Map<String, Object> resultMap = new HashMap<String, Object>();
+			resultMap = commonUtil.jsonObjectToMap(jsonObject);
+		
+			int deptCount = 0;			
+			for(String depth : depthList) {
+				deptCount++;
+				depth = depth.trim();			
+				Object temp = (Object)resultMap.get(depth);
+				
+				// 리스트 판별
+				if(temp instanceof List) {
+					if(deptCount < depthList.length) {
+						List<Map<String, Object>> tempList = (List<Map<String, Object>>) temp;
+						resultMap =  tempList.get(0);
+					}else {
+						apiDataList = (List<Map<String, Object>>) temp;
+					}		
+				}else {
+					resultMap = (Map<String, Object>) temp;	
+				}
+			}
+		}else {
+			apiDataList = (List<Map<String, Object>>)jsonArray;
+		}
+		
+		int max = 0;
+		int indx = 0;
+		
+		// 최대 길이의 키값을 가진 객체 구하기 		
+		for(int i = 0 ; i < apiDataList.size() ; i++){
+			if(apiDataList.get(i).keySet().size() > max) {
+				max = apiDataList.get(i).keySet().size();
+				indx = i;
+			}			
+		}
+		
+		// 빈정보 공백으로 채우기 
+		for(Map<String, Object> item : apiDataList ) {
+			if(max != item.size()) {
+				for (Map.Entry<String, Object> entry : apiDataList.get(indx).entrySet()) 
+				{
+					if(item.get(entry.getKey()) == null) {
+						item.put(entry.getKey(),"");
+					}
+				}
+			}
+		}		
+		
+		return apiDataList;
+	}
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/DataUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/DataUtil.java
@@ -0,0 +1,1145 @@
+package com.takensoft.taken_bi_manager.common.connection.api.util;
+
+import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.ColumnValue;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.DatasetPost;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author 최정우
+ * @since 2019.11.19
+ *
+ * Dataset과 관련된 Util입니다.
+ */
+public class DataUtil {
+
+
+    public final static String COLUMN_NAME = "col";
+
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * DataTable의 ColumnDatas와 rowData를 활용하여 '컬럼의 메타 정보 세팅'
+     */
+    public static void setColumnMetaData (DataTable dataTable, boolean addData) throws Exception {
+
+
+        //데이터가 없을 때 return
+        if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) {
+            dataTable.getCheckMessage().setSuccess(false);
+            dataTable.getCheckMessage().setMessage("컬럼 정보가 없습니다.");
+            return;
+        } else {
+
+            //한 행의 총 varchar size
+            int varcharTotalSize = 0;
+
+
+            // 맥스 사이즈 정하겠음
+            //컬럼 정보 세팅 (시작)
+            for(int cellIndex = 0; cellIndex < dataTable.getColumnDatas().size(); cellIndex++) {
+
+                int maxLength = 10;
+                //원본 컬럼명
+                String originColumnName = dataTable.getColumnDatas().get(cellIndex).getColumnNm();
+
+                //DB에 생성될 컬럼명 set
+                if (StringUtil.isEmpty(dataTable.getColumnDatas().get(cellIndex).getColumnNm()) == true) {
+                    dataTable.getColumnDatas().get(cellIndex).setColumnNm(COLUMN_NAME + cellIndex);
+                }
+
+                //컬럼 Index set
+                dataTable.getColumnDatas().get(cellIndex).setOrdr(cellIndex);
+
+
+                dataTable.getColumnDatas().get(cellIndex).setDisplyColumnNm(originColumnName);
+
+
+
+
+                //열(컬럼)의 데이터 타입 (컬럼의 열 데이터가 없을 때, STRING 타입)
+                DataType dataType = dataTable.getColumnDatas().get(cellIndex).getDataTy();
+
+                //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정)
+                Set<DataType> datatypes = new HashSet<DataType>();
+
+
+                //각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+
+                List<ColumnValue> columnValues = new ArrayList<ColumnValue>();
+                for(int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+
+                    //cellIndex열 중 rowIndex행 값-value
+                    String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString();
+
+                    if(!StringUtil.isEmpty(value) && value.length() > maxLength) {
+                        maxLength = value.length();
+                    }
+
+                    /*
+                     * 문자열이 비어있거나
+                     * 문자열이 Null or null or NULL인 경우 실제 null값 세팅
+                     * */
+                    if (StringUtil.isEmpty(value) || StringUtil.isNullText(value) == true) {
+                        dataTable.getRowData().get(rowIndex).set(cellIndex, null);
+                        value = null;
+                    }
+
+                    //해당 '값'의 '데이터 타입 조회'
+                    DataType type = DataType.getDataType(value);
+
+                    //Cell 데이터 값 및 타입 세팅
+
+                    if(addData == true) {
+                        ColumnValue columnValue = new ColumnValue();
+                        columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅
+                        columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅 //dataTable에 Cell 데이터 값  및 타입 세팅
+                        columnValues.add(columnValue);
+                    }
+
+
+                    //컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력
+                    datatypes.add(type);
+
+                    if(rowIndex > 100000) {
+
+                        if(dataTable.getRowData().size()  > 10000 && rowIndex < dataTable.getRowData().size() - 10000 ) {
+                            rowIndex = dataTable.getRowData().size() - 10000;
+                        }
+                        //	break;
+                    }
+                }
+                //각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+                dataTable.getColumnDatas().get(cellIndex).setColumnValues(columnValues);
+
+                //해당 열(컬럼)의 데이터 타입이 지정되지 않았을 때 -> #읽은 컬럼 데이터를 바탕으로 데이터 타입지정#
+                if (dataType == null) {
+                    dataType = getColumnDataType(datatypes);
+                    dataTable.getColumnDatas().get(cellIndex).setDataType(dataType);
+                }
+
+
+
+                /*DB데이터 타입 생성*/
+                if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기
+                    ColumnValue columnValue = null;
+
+                    //해당 열의 문자열 크기
+                    int size = maxLength;
+
+                    //컬럼의 열 데이터가 존재할 때, 가장 긴 문자열의 글자수 구하기
+                    /*
+                     * if (columnValues.size() > 0) { //null값 제외한 목록 만들기 List<ColumnValue>
+                     * noneNullColumnValues = columnValues.stream().filter(s -> s.getValue() !=
+                     * null).collect(Collectors.toList());
+                     *
+                     * if (noneNullColumnValues != null && noneNullColumnValues.size() > 0) { //최대
+                     * 길이 값 구하기 columnValue = noneNullColumnValues.stream().max((s1, s2) ->
+                     * StringUtil.stringLength(s1.getValue()) -
+                     * StringUtil.stringLength(s2.getValue())).get(); //가장 긴 문자열의 글자수 size =
+                     * StringUtil.stringLength(columnValue.getValue()); } }
+                     */
+
+                    //테이블 생성시에 필요한 DB데이터 타입으로 Convert
+                    String dbDataType = DataType.convertDbDataType(dataType, size);
+
+                    //DB데이터 타입 입력
+                    dataTable.getColumnDatas().get(cellIndex).setDbDataType(dbDataType);
+                    //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력
+                    if (dbDataType.equals("varchar")) {
+
+                        dataTable.getColumnDatas().get(cellIndex).setDataSize(size);//데이터 타입 크기 입력
+
+                        //varchar 총 사이즈에 추가
+                        varcharTotalSize += size;
+                    }
+                } else if (dataTable.getColumnDatas().get(cellIndex).getDataTy() == DataType.DATE) {
+
+                    //text -> date형식으로 변경
+                    for(int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+                        //cellIndex열 중 rowIndex행 값-value
+                        String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString();
+                        String dateTextValue = CommonUtil.parseDateText(value);
+                        dataTable.getRowData().get(rowIndex).set(cellIndex, dateTextValue);
+                    }
+
+                    dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null));
+                    dataTable.getColumnDatas().get(cellIndex).setDataSize(20);
+
+                } else {//'문자열'도 아니고 '날짜'도아닐 때 => DB데이터 타입 입력
+                    dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null));
+                    dataTable.getColumnDatas().get(cellIndex).setDataSize(20);
+                }
+
+            }//cell for문 끝
+
+            dataTable.getCheckMessage().setSuccess(true);
+            dataTable.getCheckMessage().setMessage("컬럼 메타 정보 세팅 완료");
+        }
+    }
+
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * DataTable의 ColumnDatas와 rowData를 활용하여 '컬럼의 메타 정보 세팅' 실제 컬럼데이터 적재 없음
+     */
+    public static void setColumnMetaDataRihjt (DataTable dataTable) throws Exception {
+
+    }
+
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * rowData를 columnData로 Convert
+     */
+    public static List<ColumnData> columnDataCreateByFile (List<List<Object>> rowData) throws Exception {
+        //각 컬럼 목록
+        List<ColumnData> columnDatas = new ArrayList<ColumnData>();
+        //데이터가 없을 때 return
+        if (rowData == null || rowData.size() == 0) return columnDatas;
+
+        //최대 Cell 크기
+        int cellMaxSize = rowDataCellMaxSize(rowData);
+
+        //rowData cell의 빈공간 채우기
+        //rowData = rowDataCellInfill(rowData, cellMaxSize);
+        rowDataCellInfill(rowData, cellMaxSize);
+
+
+        //한 핸의 총 varchar size
+        int varcharTotalSize = 0;
+
+        //컬럼 정보 세팅 (시작)
+        for(int cellIndex = 0; cellIndex < cellMaxSize; cellIndex++) {
+            //해더 정보 세팅
+            ColumnData columnData = new ColumnData();
+            String originColumnName = rowData.get(0).get(cellIndex).toString();
+            columnData.setOrginlColumnNm(originColumnName);
+            columnData.setColumnNm(COLUMN_NAME + cellIndex);
+            columnData.setOrdr(cellIndex);
+            if (StringUtil.isEmpty(originColumnName) == true) {
+                columnData.setDisplyColumnNm(COLUMN_NAME + cellIndex);
+            } else {
+                columnData.setDisplyColumnNm(originColumnName);
+            }
+            //해더 정보 세팅
+
+            //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정)
+            Set<DataType> datatypes = new HashSet<DataType>();
+
+            //각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+            List<ColumnValue> columnValues = new ArrayList<ColumnValue>();
+            for(int rowIndex = 1; rowIndex < rowData.size(); rowIndex++) {
+                String value = rowData.get(rowIndex).get(cellIndex).toString();
+                DataType type = DataType.getDataType(value);
+
+                //Cell 데이터 값 및 타입 세팅
+                ColumnValue columnValue = new ColumnValue();
+                columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅
+                columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅
+                //dataTable에 Cell 데이터 값 및 타입 세팅
+                columnValues.add(columnValue);
+
+                //컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력
+                datatypes.add(type);
+            }
+            //각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+            columnData.setColumnValues(columnValues);
+
+            //컬럼의 데이터 타입 지정 (컬럼의 열 데이터가 없을 때, STRING 타입)
+            DataType dataType = getColumnDataType(datatypes);
+            columnData.setDataType(dataType);
+
+            //DB데이터 타입 생성
+            if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기
+                ColumnValue columnValue = null;
+                int size = 50;
+                //컬럼의 열 데이터가 존재할 때
+                if (columnValues.size() > 0) {
+                    //최대 길이 값 구하기
+                    columnValue = columnValues.stream().filter(s -> Objects.nonNull(s.getValue())).max((s1, s2) -> StringUtil.stringLength(s1.getValue()) - StringUtil.stringLength(s2.getValue())).get();
+                    //가장 긴 문자열의 글자수
+                    size = StringUtil.stringLength(columnValue.getValue());
+                }
+
+                //테이블 생성시에 필요한 DB데이터 타입으로 Convert
+                String dbDataType = DataType.convertDbDataType(dataType, size);
+
+                //DB데이터 타입 입력
+                columnData.setDbDataType(dbDataType);
+                //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력
+                if (dbDataType.equals("varchar")) {
+//					if (size < SystemCode.DEFAULT_VARCHAR_SIZE) {
+//						size = SystemCode.DEFAULT_VARCHAR_SIZE;
+//					}
+                    columnData.setDataSize(size);//데이터 타입 크기 입력
+
+                    //varchar 총 사이즈에 추가
+                    varcharTotalSize += size;
+                }
+            } else {//문자열이 아닐 때 => DB데이터 타입 입력
+                columnData.setDbDataType(DataType.convertDbDataType(dataType, null));
+            }
+
+            //컬럼 목록에 컬럼 정보 추가
+            columnDatas.add(columnData);
+        }
+
+
+//		if (varcharTotalSize)
+//		for(int i = 0; i < columnDatas.size(); i++) {
+//			columnDatas.get(i).
+//		}
+
+        return columnDatas;
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * rowData를 columnData로 Convert
+     */
+    public static List<ColumnData> columnDataCreateByAPI (List<List<Object>> rowData, List<Map<String, String>> columns) throws Exception {
+        //각 컬럼 목록
+        List<ColumnData> columnDatas = new ArrayList<ColumnData>();
+        //데이터가 없을 때 return
+        if (rowData == null || rowData.size() == 0 || columns == null || columns.size() == 0) return columnDatas;
+
+        //최대 Cell 크기
+        int cellMaxSize = rowDataCellMaxSize(rowData);
+
+        //rowData cell의 빈공간 채우기
+        //rowData = rowDataCellInfill(rowData, cellMaxSize);
+        rowDataCellInfill(rowData, cellMaxSize);
+
+        //한 핸의 총 varchar size
+        int varcharTotalSize = 0;
+
+        //컬럼 정보 세팅 (시작)
+        for(int cellIndex = 0; cellIndex < cellMaxSize; cellIndex++) {
+            //해더 정보 세팅
+            ColumnData columnData = new ColumnData();
+            String originColumnName = rowData.get(0).get(cellIndex).toString();
+            columnData.setOrginlColumnNm(originColumnName);
+            columnData.setColumnNm(COLUMN_NAME + cellIndex);
+            columnData.setOrdr(cellIndex);
+            if (StringUtil.isEmpty(originColumnName) == true) {
+                columnData.setDisplyColumnNm(COLUMN_NAME + cellIndex);
+            } else {
+                columnData.setDisplyColumnNm(originColumnName);
+            }
+            //해더 정보 세팅
+
+            //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정)
+            Set<DataType> datatypes = new HashSet<DataType>();
+
+            //각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+            List<ColumnValue> columnValues = new ArrayList<ColumnValue>();
+            for(int rowIndex = 1; rowIndex < rowData.size(); rowIndex++) {
+                String value = rowData.get(rowIndex).get(cellIndex).toString();
+                DataType type = DataType.getDataType(value);
+
+                //Cell 데이터 값 및 타입 세팅
+                ColumnValue columnValue = new ColumnValue();
+                columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅
+                columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅
+                //dataTable에 Cell 데이터 값 및 타입 세팅
+                columnValues.add(columnValue);
+
+                //컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력
+                datatypes.add(type);
+            }
+            //각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+            columnData.setColumnValues(columnValues);
+
+            //컬럼의 데이터 타입 지정 (컬럼의 열 데이터가 없을 때, STRING 타입)
+            DataType dataType = getColumnDataType(datatypes);
+            columnData.setDataType(dataType);
+
+            //DB데이터 타입 생성
+            if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기
+                ColumnValue columnValue = null;
+                int size = 50;
+                //컬럼의 열 데이터가 존재할 때
+                if (columnValues.size() > 0) {
+                    //최대 길이 값 구하기
+                    columnValue = columnValues.stream().filter(s -> Objects.nonNull(s.getValue())).max((s1, s2) -> StringUtil.stringLength(s1.getValue()) - StringUtil.stringLength(s2.getValue())).get();
+                    //가장 긴 문자열의 글자수
+                    size = StringUtil.stringLength(columnValue.getValue());
+                }
+
+                //테이블 생성시에 필요한 DB데이터 타입으로 Convert
+                String dbDataType = DataType.convertDbDataType(dataType, size);
+
+                //DB데이터 타입 입력
+                columnData.setDbDataType(dbDataType);
+                //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력
+                if (dbDataType.equals("varchar")) {
+//					if (size < SystemCode.DEFAULT_VARCHAR_SIZE) {
+//						size = SystemCode.DEFAULT_VARCHAR_SIZE;
+//					}
+                    columnData.setDataSize(size);//데이터 타입 크기 입력
+
+                    //varchar 총 사이즈에 추가
+                    varcharTotalSize += size;
+                }
+            } else {//문자열이 아닐 때 => DB데이터 타입 입력
+                columnData.setDbDataType(DataType.convertDbDataType(dataType, null));
+            }
+
+            //컬럼 목록에 컬럼 정보 추가
+            columnDatas.add(columnData);
+        }
+
+
+//		if (varcharTotalSize)
+//		for(int i = 0; i < columnDatas.size(); i++) {
+//			columnDatas.get(i).
+//		}
+
+        return columnDatas;
+    }
+
+    public static List<ColumnData> columnDataCreateByCrawling(List<List<Object>> rowData) throws Exception {
+        //각 컬럼 목록
+        List<ColumnData> columnDatas = new ArrayList<ColumnData>();
+        //데이터가 없을 때 return
+        if (rowData == null || rowData.size() == 0) return columnDatas;
+
+        //최대 Cell 크기
+        int cellMaxSize = rowDataCellMaxSize(rowData);
+
+        //rowData cell의 빈공간 채우기
+        //rowData = rowDataCellInfill(rowData, cellMaxSize);
+        rowDataCellInfill(rowData, cellMaxSize);
+
+        //컬럼 정보 세팅 (시작)
+        for(int cellIndex = 0; cellIndex < cellMaxSize; cellIndex++) {
+            //해더 정보 세팅
+            ColumnData columnData = new ColumnData();
+            String originColumnName = rowData.get(0).get(cellIndex).toString();
+            columnData.setOrginlColumnNm(originColumnName);
+            columnData.setColumnNm(originColumnName);
+            columnData.setOrdr(cellIndex);
+            if (StringUtil.isEmpty(originColumnName) == true) {
+                columnData.setDisplyColumnNm(COLUMN_NAME + cellIndex);
+            } else {
+                columnData.setDisplyColumnNm(originColumnName);
+            }
+            //해더 정보 세팅
+
+            columnData.setDataType(DataType.STRING);
+            if(cellIndex == 0) // url
+            {
+                columnData.setDbDataType("varchar");
+                columnData.setDataSize(191);
+                columnData.setUniq(true);
+            }else if(cellIndex ==2)
+            {
+                columnData.setDbDataType("MEDIUMTEXT");
+            }else {
+                columnData.setDbDataType("varchar");
+                columnData.setDataSize(256);
+            }
+
+            //컬럼 목록에 컬럼 정보 추가
+            columnDatas.add(columnData);
+        }
+
+        return columnDatas;
+
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * DataTable에 존재하는 ColumnData에 대한 DataType Setting
+     */
+    public static void setColumnDataType (DataTable dataTable) throws Exception {
+
+
+        //데이터가 없을 때 return
+        if (dataTable.getRowData() == null || dataTable.getRowData().size() == 0) return;
+
+        //컬럼 목록 for문
+        for(int cellIndex = 0; cellIndex < dataTable.getColumnDatas().size(); cellIndex++) {
+            //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정)
+            Set<DataType> dataTypes = new HashSet<DataType>();
+            //데이터 목록 for문
+            for(int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+                //Cell 데이터 값 조회
+                String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString();
+                //Cell 데이터 값의 '데이터 타입' 조회
+
+                /*
+                 * row > cell 데이터 값의 '데이터 타입' 지정
+                 *
+                 * cell목록들 중 문자타입(STRING)이 존재하면, 해당 cell 전체를  문자타입(STRING)으로 바꿈
+                 * (즉, 데이터 타입을 체크하지 않음 -> cell전체다 데이터 타입을 체크해도 상관은 없음. 하지만 모든 cell을 다 체크해야되서 느려짐.)
+                 */
+//				DataType type = null;
+//				if (dataTypes.contains(DataType.STRING) == true) {
+//					type = DataType.STRING;
+//				} else {
+//					type = DataType.getDataType(value);
+//				}
+//
+//				//Cell 데이터 값 및 타입 세팅
+//				ColumnValue columnValue = new ColumnValue();
+//				columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅
+//				columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅
+//				//dataTable에 Cell 데이터 값 및 타입 세팅
+//				dataTable.getColumnDatas().get(cellIndex).getColumnValues().add(columnValue);
+//
+//				//컬럼별 데이터의 '데이터 타입' 목록에 '데이터 타입' 입력
+//				dataTypes.add(type);
+            }//row 목록 for문 끝
+
+            /*컬럼의 '데이터 타입' 세팅*/
+            DataType columnDataType = getColumnDataType(dataTypes);
+            dataTable.getColumnDatas().get(cellIndex).setDataType(columnDataType);
+            /*컬럼의 '데이터 타입' 세팅*/
+
+
+            /*컬럼의 'DB용 데이터 타입' 세팅*/
+            if (columnDataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기
+                //문자열 데이터 길이
+                int size = 50;
+
+                //컬럼의 열 데이터가 존재할 때
+                List<ColumnValue> values = dataTable.getColumnDatas().get(cellIndex).getValues().stream().map(object -> (ColumnValue) object).collect(Collectors.toList());
+
+                for(int i = values.size() - 1 ; i >= 0 ; i--) {
+                    if(values.get(i).getValue() == null) {
+                        values.remove(i);
+                    }
+                }
+                if (values.size() > 0) {
+                    //최대 길이 값 구하기
+                    ColumnValue columnValue = values.stream().filter(s -> Objects.nonNull(s.getValue())).max((s1, s2) -> StringUtil.stringLength(s1.getValue()) - StringUtil.stringLength(s2.getValue())).get();
+                    //가장 긴 문자열의 글자수
+                    size = StringUtil.stringLength(columnValue.getValue());
+                }
+
+
+                //테이블 생성시에 필요한 DB데이터 타입으로 Convert
+                String dbDataType = DataType.convertDbDataType(columnDataType, size);
+
+
+                //DB데이터 타입 입력
+                dataTable.getColumnDatas().get(cellIndex).setDbDataType(dbDataType);
+                //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력
+                if (dbDataType.equals("varchar")) {
+//					if (size < SystemCode.DEFAULT_VARCHAR_SIZE) {
+//						size = SystemCode.DEFAULT_VARCHAR_SIZE;
+//					}
+                    dataTable.getColumnDatas().get(cellIndex).setDataSize(size);//데이터 타입 크기 입력
+                }
+            } else {//문자열이 아닐 때 => DB데이터 타입 입력
+                dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(columnDataType, null));
+            }/*컬럼의 'DB용 데이터 타입' 세팅*/
+
+        }//컬럼 목록 for문 끝
+
+        dataTable.getCheckMessage().setSuccess(true);
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * DataTable에 있는 rowData를 columnData로 Convert후, DataTable로 리턴
+     */
+    public static DataTable columnDataCreateByFile (DataTable dataTable) throws Exception {
+        dataTable.setColumnDatas(columnDataCreateByFile(dataTable.getRowData())); //?????
+        return dataTable;
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * rowData List<List<String>> -> DataTable로 Convert
+     */
+    public static DataTable dataTableCreate (List<List<Object>> rowData, String title) throws Exception {
+        DataTable dataTable = dataTableCreate(rowData);
+        dataTable.setDatasetSj(title);
+        return dataTable;
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * rowData List<List<String>> -> DataTable로 Convert (단, 데이터명이 없음)
+     */
+    public static DataTable dataTableCreate (List<List<Object>> rowData) throws Exception {
+        DataTable dataTable = new DataTable();
+        dataTable.setColumnDatas(columnDataCreateByFile(rowData));
+        return dataTable;
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * rowData cell의 최대 크기 (빈공간 채우기 위함)
+     */
+    public static int rowDataCellMaxSize (List<List<Object>> rowData) throws Exception {
+        int cellMaxSize = 0;
+        for(int rowIndex = 0; rowIndex < rowData.size(); rowIndex++) {
+            int cellSize = rowData.get(rowIndex).size();
+            if (cellMaxSize < cellSize) {
+                cellMaxSize = cellSize;
+            }
+        }
+
+        return cellMaxSize;
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.19
+     *
+     * rowData cell의 빈공간 채우기 (cellMaxSize 크기 만큼)
+     */
+    public static void rowDataCellInfill (List<List<Object>> rowData, int cellMaxSize) throws Exception {
+        for(int rowIndex = 0; rowIndex < rowData.size(); rowIndex++) {
+            int addSize = cellMaxSize - rowData.get(rowIndex).size();
+            for(int cellIndex = 0; cellIndex < addSize; cellIndex++) {
+                rowData.get(rowIndex).add(null);
+            }
+        }
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.27
+     *
+     * column의 데이터 타입 지정
+     */
+    public static DataType getColumnDataType (Set<DataType> datatypes) throws Exception {
+        if (datatypes.contains(DataType.STRING)) {
+            return DataType.STRING;
+        } else if (datatypes.contains(DataType.DATE)) {
+            if (datatypes.contains(DataType.DOUBLE) || datatypes.contains(DataType.LONG)) {
+                return DataType.STRING;
+            } else {
+                return DataType.DATE;
+            }
+        } else if (datatypes.contains(DataType.DOUBLE)) {
+            return DataType.DOUBLE;
+        } else if (datatypes.contains(DataType.LONG)) {
+            return DataType.LONG;
+        } else {
+            return DataType.STRING;
+        }
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.27
+     *
+     * 데이터 셋의 컬럼의 데이터 타입을 통해, 데이터 셋의 데이터 타입 지정
+     */
+//    public static DatasetDataType getDatasetDataType (List<ColumnData> columnDatas) throws Exception {
+//        for (int j = 0; j < columnDatas.size(); j++) {
+//            if (columnDatas.get(j).getDataType() != DataType.STRING) {
+//                return DatasetDataType.NUMBER;
+//            }
+//        }
+//
+//        return DatasetDataType.TEXT;
+//
+//    }?????
+
+
+
+    /**
+     * @author 김성원
+     * @since 2019.12.04
+     *
+     * double 형태의  List<ColumnValue> 데이터 최대 최소 평균
+     */
+    public static ColumnData setDoubleCalculation (ColumnData columnData , DataTable dataTable) throws Exception {
+        columnData.getValues().sort(null);
+
+        int index = 0;
+        Object min = 0;
+        Object max = 0;
+
+        for(int i = 0 ; i < dataTable.getColumnDatas().size() ; i++) {
+            if(dataTable.getColumnDatas().get(i).getColumnNm().equals(columnData.getColumnNm())) {
+                index = i;
+                break;
+            }
+        }
+
+        final int indx = index;
+
+
+        int totalSize = dataTable.getRowData().size();
+
+        //List<ColumnValue> nonNullColumnValues = columnData.getColumnValues().stream().filter(a -> a.getValue() != null).collect(Collectors.toList());
+
+        List<List<Object>> dataList = dataTable.getRowData().stream().filter(x1 -> x1.get(indx) != null).collect(Collectors.toList());
+
+        if (dataList.size() > 0) {
+
+            int nonNullSize = dataList.size();
+
+            columnData.setMin(CommonUtil.parseDouble(dataList.get(0).get(indx)));
+            columnData.setMax(CommonUtil.parseDouble(dataList.get(nonNullSize-1).get(indx)));
+
+            if(nonNullSize % 2 == 0) {
+                columnData.setMedian((CommonUtil.parseDouble(dataList.get(nonNullSize / 2).get(indx)) +  CommonUtil.parseDouble(dataList.get(nonNullSize / 2 -1 ).get(indx))) / 2);
+            }else {
+                columnData.setMedian(CommonUtil.parseDouble(dataList.get(nonNullSize / 2).get(indx)));
+            }
+
+            Object sum = dataList.stream().mapToDouble(mapper -> CommonUtil.parseDouble(mapper.get(indx))).sum();
+
+            columnData.setSum(sum);
+
+            columnData.setMean(Math.round((((double) sum / nonNullSize)*100)/100.0));
+
+            columnData.setNullCount(totalSize - nonNullSize);
+        } else {
+            columnData.setMin("0");
+            columnData.setMax("0");
+            columnData.setSum(0);
+            columnData.setMean(0.0);
+            columnData.setMedian("0");
+            columnData.setNullCount(0);
+        }
+
+        return columnData;
+    }
+
+    /**
+     * @author 김성원
+     * @since 2019.12.04
+     *
+     * 데이터 테이블의 DATAROW를 확인하여 최대최소 저장
+     */
+    public static DataTable setRowDataCalculation (DataTable table) throws Exception {
+
+        // 컬럼데이터 전체 최소 최대 계산
+        int index = 0;
+        for(ColumnData columnData :table.getColumnDatas()) {
+
+            if(columnData.getDataTy().equals(DataType.DOUBLE)) {
+                table.getColumnDatas().set(index,setDoubleCalculation(table.getCoulmnDataByCoulmnIndex(index),table));
+                table.getColumnDatas().get(index).getValues().clear();
+            }else if(columnData.getDataTy().equals(DataType.LONG)) {
+                table.getColumnDatas().set(index,setLongCalculation(table.getCoulmnDataByCoulmnIndex(index),table));
+                table.getColumnDatas().get(index).getValues().clear();
+            }
+            index++;
+        }
+
+
+
+        return table;
+    }
+
+
+    /**
+     * @author 김성원
+     * @since 2019.12.04
+     *
+     * Long 형태의  List<ColumnValue> 데이터 최대 최소 평균
+     */
+    public static ColumnData setLongCalculation (ColumnData columnData, DataTable dataTable) throws Exception {
+        columnData.getValues().sort(null);
+
+        int index = 0;
+        Object min = 0;
+        Object max = 0;
+
+        for(int i = 0 ; i < dataTable.getColumnDatas().size() ; i++) {
+            if(dataTable.getColumnDatas().get(i).getColumnNm().equals(columnData.getColumnNm())) {
+                index = i;
+                break;
+            }
+        }
+
+        final int indx = index;
+
+
+        int totalSize = dataTable.getRowData().size();
+
+        List<List<Object>> dataList = dataTable.getRowData().stream().filter(x1 -> x1.get(indx) != null).collect(Collectors.toList());
+
+
+        if (dataList.size() > 0) {
+
+            int nonNullSize = dataList.size();
+
+            if(nonNullSize != 0) {
+                columnData.setMin(CommonUtil.parseLong(dataList.get(0).get(indx)));
+                columnData.setMax(CommonUtil.parseLong(dataList.get(nonNullSize-1).get(indx)));
+                if(nonNullSize % 2 == 0) {
+                    columnData.setMedian((CommonUtil.parseLong(dataList.get(nonNullSize / 2).get(indx)) +  CommonUtil.parseLong(dataList.get(nonNullSize / 2 -1 ).get(indx))) / 2);
+                }else {
+                    columnData.setMedian(CommonUtil.parseLong(dataList.get(nonNullSize / 2).get(indx)));
+                }
+
+                Object sum = dataList.stream().mapToLong(mapper -> CommonUtil.parseLong(mapper.get(indx))).sum();
+
+                columnData.setSum(sum);
+
+                columnData.setMean(Math.round((( Double.parseDouble(sum.toString()) / nonNullSize)*100)/100.0));
+
+                columnData.setNullCount(totalSize - nonNullSize);
+            }else {
+                columnData.setMin("0");
+                columnData.setMax("0");
+                columnData.setSum(0);
+                columnData.setMean(0.0);
+                columnData.setMedian("0");
+                columnData.setNullCount(0);
+            }
+        } else {
+            columnData.setMin("0");
+            columnData.setMax("0");
+            columnData.setSum(0);
+            columnData.setMean(0.0);
+            columnData.setMedian("0");
+            columnData.setNullCount(0);
+        }
+
+        return columnData;
+    }
+
+    /**
+     * @author 김성원
+     * @since 2019.12.04
+     *
+     * double 형태의  List<ColumnValue> 문자열 최빈, 최다, 리스트구하기
+     */
+    public static ColumnData setStringCalculation (ColumnData columnData, DataTable dataTable) throws Exception {
+
+
+        columnData.setLeast("-");
+        columnData.setMode("-");
+        columnData.setNullCount(0);
+        int index = 0;
+
+        for(int i = 0 ; i < dataTable.getColumnDatas().size() ; i++) {
+            if(dataTable.getColumnDatas().get(i).getColumnNm().equals(columnData.getColumnNm())) {
+                index = i;
+                break;
+            }
+        }
+
+        final int indx = index;
+
+
+        int totalSize = dataTable.getRowData().size();
+
+        List<List<Object>> dataList = dataTable.getRowData().stream().filter(x1 -> x1.get(indx) != null).collect(Collectors.toList());
+
+
+
+        //	List<ColumnValue> nonNullColumnValues = columnData.getColumnValues().stream().filter(a -> a.getValue() != null).collect(Collectors.toList());
+
+        if (dataList.size() > 0) {
+
+            int nonNullSize = dataList.size();
+
+            final Map<String, Integer> counter = new HashMap<String, Integer>();
+
+            // 언어별 카운트
+            for( List<Object> value :  dataList ){
+
+                counter.put(StringUtil.toString(value.get(indx)), 1 + (counter.containsKey(StringUtil.toString(value.get(indx))) ? counter.get(StringUtil.toString(value.get(indx))) : 0));
+            }
+
+            // 정렬을 위한 LinkedList
+            List<Map.Entry<String, Integer>> list = new LinkedList<>(counter.entrySet());
+
+            Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
+                @Override
+                public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
+                    int comparision = (o1.getValue() - o2.getValue()) * -1;
+                    return comparision == 0 ? o1.getKey().compareTo(o2.getKey()) : comparision;
+                }
+            });
+
+
+            for(Map.Entry<String, Integer> temp : list) {
+                columnData.getValues().add(new ColumnValue(temp.getKey().trim(), DataType.STRING, temp.getValue()));
+            }
+
+            if(list.size() > 0) {
+                columnData.setLeast(list.get(0).getKey());
+                columnData.setMode(list.get(list.size()-1).getKey());
+            }
+
+            columnData.setNullCount(totalSize - nonNullSize);
+        }
+
+        return columnData;
+    }
+
+
+    /**
+     * @author 김성원
+     * @since 2021.11.04
+     *
+     * List<Map<String,Object>>형태의 데이터를  DataTable로 반환
+     */
+    public static DataTable setMaptoDataTable (List<Map<String,Object>> mapData) throws Exception {
+
+        DataTable dataTable = new DataTable();
+
+        Map<String,List<String>> columnDataMap = new HashMap<String,List<String>>();
+
+        // columnData 맵 데이터 생성
+        for(Map<String,Object> temp : mapData) {
+            for( Map.Entry<String, Object> elem : temp.entrySet() ){
+                if(columnDataMap.get(elem.getKey()) == null){
+                    columnDataMap.put(elem.getKey(), new ArrayList<String>());
+                    columnDataMap.get(elem.getKey()).add(elem.getKey());
+                }
+                try {
+                    columnDataMap.get(elem.getKey()).add(elem.getValue().toString());
+                }catch(Exception e) {
+                    columnDataMap.get(elem.getKey()).add("".toString());
+                }
+            }
+        }
+
+
+
+        for(Map.Entry<String, List<String>> elem : columnDataMap.entrySet()){
+            List<Object> elemData = new ArrayList<>();
+            elemData.add(elem.getValue());
+            dataTable.getRowData().add(elemData);
+        }
+
+        dataTable.setRowData(dataTable.matrixChange());
+
+        // rowData의 최대 Cell 크기
+        int cellMaxSize = DataUtil.rowDataCellMaxSize(dataTable.getRowData());
+
+        // rowData cell의 빈공간 채우기
+        DataUtil.rowDataCellInfill(dataTable.getRowData(), cellMaxSize);
+
+        // 헤더 정보 가지고오기
+        List<Object> headers = dataTable.getRowData().get(0);
+
+        // 세팅될 컬럼 정보
+        List<ColumnData> columnDatas = new ArrayList<ColumnData>();
+        for (int cellIndex = 0; cellIndex < headers.size(); cellIndex++) {
+            ColumnData columnData = new ColumnData();
+
+            // 헤더명 (컬럼명)
+            String originColumnName = headers.get(cellIndex).toString();
+
+            // 해당 열에 행데이터가 1개라도 존재하는지 체크 (헤더 데이터 포함해서 체크)
+            boolean isCellDataExist = false;
+
+            // 해당 열의 행 데이터 검사 시작
+            for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+                String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString();
+
+                // 값이 있으면, -> 검사 종료
+                if (StringUtil.isEmpty(value) == false) {
+                    isCellDataExist = true;
+                    break;
+                }
+            }
+
+            // 해당 열에 데이터가 한개라도 존재할 때 -> 컬럼 생성
+            if (isCellDataExist == true) {
+                /* 컬럼 생성 */
+                columnData.setOrginlColumnNm(originColumnName);
+                columnData.setDisplyColumnNm(originColumnName);
+                columnDatas.add(columnData);
+            } else {// 해당 열에 데이터가 없을 때 -> 해당 열 데이터 전체 삭제
+                /* 해당 열 데이터 전체 삭제 */
+                for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+                    dataTable.getRowData().get(rowIndex).remove(cellIndex);
+                }
+                /* 해당 열 데이터 전체 삭제 후, 현재 열 Index 1 줄이기 */
+                cellIndex--;
+            }
+        }
+
+        // DataTable의 컬럼정보 세팅
+        dataTable.setColumnDatas(columnDatas);
+
+        // 컬럼 데이터 세팅 후, 행별 데이터에 헤더값(0번 index) 제거
+
+
+        dataTable.getRowData().remove(0);
+        return dataTable;
+    }
+
+    /**
+     * @author 김성원
+     * @since 2021.11.04
+     *
+     * 컬럼데이터 업데이트 가능여부
+     */
+	/*
+	public static Map<String,Object> checkCoulmnDataInsert(ColumnData origin, List<Object> data) {
+		Map<String,Object> result = new HashMap<String,Object>();
+		result.put("result", true);
+		result.put("resultMassage", "정상작동");
+		DataType type = origin.getDataType();
+		int count = 0;
+		for(Object item : data) {
+			count++;
+			boolean check = true;
+			if(type.equals(DataType.STRING)) {
+				check = item instanceof String;
+				if(item.toString().length() > origin.getSize()) {
+					check = false;
+					result.put("result", false);
+					result.put("resultMassage", "["+origin.getDisplayColumnName() + "]의 데이터 크기("+origin.getSize()+")보다 큽니다. \r\n"
+							+ "데이터 : [" + item.toString() +"]의 크기("+item.toString().length()+")");
+				}
+			}else if(type.equals(DataType.INT)) {
+				try {
+					Integer.parseInt(item.toString());
+				}catch(Exception e) {
+					check = false;
+				}
+			}else if(type.equals(DataType.LONG)) {
+				try {
+					Long.parseLong(item.toString());
+				}catch(Exception e) {
+					check = false;
+				}
+			}else if(type.equals(DataType.DOUBLE)) {
+				try {
+					Double.parseDouble(item.toString());
+				}catch(Exception e) {
+					check = false;
+				}
+			}else if(type.equals(DataType.DATE) || type.equals(DataType.DATETIME)) {
+				check = item instanceof  Date;
+			}
+
+			if(check == false) {
+				result.put("result", false);
+				if(result.get("resultMassage").equals("정상작동")) {
+					result.put("resultMassage", "["+origin.getDisplayColumnName() + "]의 데이터 형태가 ["+type+"]와 일치하지 안습니다. \r\n"
+							+ "데이터 : (" + item.toString() +")");
+				}
+			}
+			if(count > 1000) {
+				break;
+			}
+		}
+
+		return result;
+	}
+	*/
+
+    /**
+     * @author 김성원
+     * @since 2021.11.04
+     *
+     * 컬럼데이터 업데이트 가능여부
+     */
+    public static Map<String,Object> checkCoulmnDataInserts(ColumnData origin, int index, List<List<String>> data) {
+        Map<String,Object> result = new HashMap<String,Object>();
+        result.put("result", true);
+        result.put("resultMassage", "정상작동");
+        DataType type = origin.getDataTy();
+        int count = 0;
+
+        for(List<String>  listItem : data) {
+            count++;
+            boolean check = true;
+            if(listItem.size() > index  && !StringUtil.isEmpty(listItem.get(index)) ) {
+                if(type.equals(DataType.STRING)) {
+                    if(listItem.get(index).length() > origin.getDataSize()) {
+                        check = false;
+                        result.put("result", false);
+                        result.put("resultMassage", "["+origin.getDisplyColumnNm() + "]의 데이터 크기("+origin.getDataSize()+")보다 큽니다. \r\n"
+                                + "데이터 : [" +listItem.get(index) +"]의 크기("+ listItem.get(index).length()+")");
+                    }
+                }else if(type.equals(DataType.INT)) {
+                    try {
+                        Integer.parseInt(listItem.get(index));
+                    }catch(Exception e) {
+                        check = false;
+                    }
+                }else if(type.equals(DataType.LONG)) {
+                    try {
+                        Long.parseLong(listItem.get(index));
+                    }catch(Exception e) {
+                        check = false;
+                    }
+                }else if(type.equals(DataType.DOUBLE)) {
+                    try {
+                        Double.parseDouble(listItem.get(index));
+                    }catch(Exception e) {
+                        check = false;
+                    }
+                }else if(type.equals(DataType.DATE) || type.equals(DataType.DATETIME)) {
+                    // 체크필요 //
+
+                    //check = item instanceof  Date;
+                }
+            }
+            if(count > 1000) {
+                break;
+            }
+
+        }
+
+        return result;
+    }
+
+
+    public static Map<String, Object> getJsonData(DatasetPost dp) {
+
+        Map<String,Object> resultData = new HashMap<String,Object>();
+
+        resultData.put("id", dp.getDataset_post_id());
+        resultData.put("title", dp.getPost_sj());
+        resultData.put("category", dp.getCategoryTitle());
+        if(StringUtil.isEmpty(dp.getOrigin())) {
+            resultData.put("orgName", "관리자");
+        }else {
+            resultData.put("orgName", dp.getOrigin());
+        }
+
+        resultData.put("createDate", dp.getCreat_dt());
+        resultData.put("updateDate", dp.getUpdt_dt());
+        resultData.put("requestCount", dp.getRdcnt());
+//        resultData.put("status", dp.getStatus());??
+        if(StringUtil.isEmpty(dp.getFile_manager_id())) {
+            resultData.put("fileExt", "0");
+        }else {
+            resultData.put("fileExt", "1");
+        }
+
+        /*혜민 추가 220428*/
+        resultData.put("datasetId",dp.getDataset_id());
+        /*혜민 추가 끝 220428*/
+        return resultData;
+    }
+
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/SeolAPIUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/SeolAPIUtil.java
@@ -0,0 +1,392 @@
+package com.takensoft.taken_bi_manager.common.connection.api.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author 최민식
+ * @since 2020.08.12
+ *
+ * 세올 데이터
+ */
+public class SeolAPIUtil {
+	// 인코딩타입
+	private final static String CHARSET = "UTF-8";
+	// 연계ID
+	private final static String IFID = "SOINN00001";
+	// 요청기관코드7자리
+	private final static String SRCORGCD = "5110000"; //상주시
+	// 응답기관코드7자리
+	private final static String TGTORGCD = "5110000"; //상주시
+
+	public static Map<String, Object> getParam () {
+		// 현재 날짜 호출
+		SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd");
+		Date nowDate = new Date();
+		String nowDate_format = format1.format(nowDate);
+
+		// 하루전 날짜 호출
+		Calendar cal = Calendar.getInstance();
+		DateFormat df = new SimpleDateFormat("yyyyMMdd");
+		Date date = null;
+		cal.add(Calendar.DATE, -1);
+		String aDayAgo = df.format(cal.getTime());
+
+		Map<String, Object> param = new HashMap<>();
+
+		/** 민원목록정보 정보 **/
+		Map<String, Object> detailInfo11 = new HashMap<>();
+		// 컬럼 정보
+		List<ColumnData> columnDatas11 = new ArrayList<ColumnData>();
+		columnDatas11.add(new ColumnData("dpp_user_posit_code", "처리담당자직급코드", DataType.STRING));
+		columnDatas11.add(new ColumnData("take_dep_nm", "접수부서명", DataType.STRING));
+		columnDatas11.add(new ColumnData("deal_plan_daycnt", "처리일수", DataType.STRING));
+		columnDatas11.add(new ColumnData("mw_kd_nm", "민원유형", DataType.STRING));
+		columnDatas11.add(new ColumnData("deal_plan_ymd", "처리예정일", DataType.STRING));
+		columnDatas11.add(new ColumnData("restamt_rtn", "잔액반송금액", DataType.STRING));
+		columnDatas11.add(new ColumnData("mw_pps_getr_yn", "수령여부", DataType.STRING));
+		columnDatas11.add(new ColumnData("tot_cnt", "총건수", DataType.STRING));
+		columnDatas11.add(new ColumnData("real_deal_tm", "처리시간", DataType.STRING));
+		columnDatas11.add(new ColumnData("fee_recpt_se_nm", "수납구분", DataType.STRING));
+		columnDatas11.add(new ColumnData("deal_plan_tm", "처리예정시간", DataType.STRING));
+		columnDatas11.add(new ColumnData("reg_dt", "등록일시", DataType.STRING));
+		columnDatas11.add(new ColumnData("main_deal_dep_code", "처리부서코드", DataType.STRING));
+		columnDatas11.add(new ColumnData("take_confrm_code", "접수확인여부(접수구분)", DataType.STRING));
+		columnDatas11.add(new ColumnData("take_se_nm", "민원접수구분", DataType.STRING));
+		columnDatas11.add(new ColumnData("take_dt", "접수일시", DataType.STRING));
+		columnDatas11.add(new ColumnData("mw_take_no", "접수번호", DataType.STRING, true));
+		columnDatas11.add(new ColumnData("take_dep_code", "접수부서코드", DataType.STRING));
+		columnDatas11.add(new ColumnData("sndmny_am", "송금액", DataType.STRING));
+		columnDatas11.add(new ColumnData("appl_mwin_se_nm", "신청인구분", DataType.STRING));
+		columnDatas11.add(new ColumnData("mw_afr_shtnm", "민원명", DataType.STRING));
+		columnDatas11.add(new ColumnData("deal_se_nm", "처리구분", DataType.STRING));
+		columnDatas11.add(new ColumnData("row_no", "로우넘", DataType.STRING));
+		columnDatas11.add(new ColumnData("main_deal_dep_nm", "처리부서명", DataType.STRING));
+		columnDatas11.add(new ColumnData("mw_notes", "민원요지", DataType.STRING));
+		columnDatas11.add(new ColumnData("real_deal_ymd", "처리일자", DataType.STRING));
+		columnDatas11.add(new ColumnData("take_user_posit_nm", "접수자직급명", DataType.STRING));
+		columnDatas11.add(new ColumnData("dpp_user_posit_nm", "처리담당자직급명", DataType.STRING));
+		columnDatas11.add(new ColumnData("take_user_posit_code", "접수자직급코드", DataType.STRING));
+		columnDatas11.add(new ColumnData("mw_se_nm", "민원구분", DataType.STRING));
+		detailInfo11.put("columnDatas", columnDatas11);
+		detailInfo11.put("requestInfo", "<dataList><data>"+nowDate_format+"</data></dataList>"
+				+ "<dataList><data>"+aDayAgo+"</data></dataList>"
+				+ "<dataList><data>1</data></dataList>"
+				+ "<dataList><data>100</data></dataList>");
+		param.put("5110000SOI001", detailInfo11); //상주시
+		/** 민원목록정보 정보 **/
+		return param;
+	}
+
+	/**
+	 * 쿼리종류 분류
+	 */
+	public DataTable getSeolMain(String url, String apikey) {
+		// 빈 객체 생성
+		DataTable dataTable;
+		if(apikey.equals("5110000SOI001") ) { // 상주시 민원
+			Map<String, Object> param = (Map<String, Object>) getParam().get(apikey);
+			dataTable = getSeolData(url, apikey, param);
+			// 현재 날짜 호출
+			SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd");
+			Date nowDate = new Date();
+			String nowDate_format = format1.format(nowDate);
+			// 하루전 날짜 호출
+			Calendar cal = Calendar.getInstance();
+			DateFormat df = new SimpleDateFormat("yyyyMMdd");
+			Date date = null;
+			cal.add(Calendar.DATE, -1);
+			String aDayAgo = df.format(cal.getTime());
+			String requestInfo = "<dataList><data>"+aDayAgo+"</data></dataList>"
+					+ "<dataList><data>"+nowDate_format+"</data></dataList>"
+					+ "<dataList><data>1</data></dataList>"
+					+ "<dataList><data>100</data></dataList>";
+			param.put("requestInfo", requestInfo);
+			// 페이지가 1이상일 경우 추가로 합쳐야할 정보들
+			DataTable dataTable_ = getSeolData(url, apikey, param);
+			// 데이터 추가
+			for(int j = 0; j < dataTable_.getRowData().size(); j++) {
+				System.out.println("j 소환 : " + j);
+				dataTable.getRowData().add(dataTable_.getRowData().get(j));
+			}
+		} else {
+			// ,구분자 짜르기
+			String[] apikeyList = apikey.split(",");
+			// 해당 정보의 갯수 호출
+			int cnt = getSeolDataCnt(url, apikeyList[1]);
+			// 페이징 갯수
+			int pagingCnt = (int) Math.ceil((double) cnt / 200);
+			// 페이징 갯수가 1이상일 경우
+			Map<String, Object> param = (Map<String, Object>) getParam().get(apikeyList[0]);
+			// 페이징 갯수가 1이상일 경우
+			if(pagingCnt > 1) {
+				dataTable = getSeolData(url, apikeyList[0], param);
+				for(int i = 1; i <= pagingCnt; i++) {
+					System.out.println("i 값을 알아보자 : " + i);
+					// 파라미터값 호출(쿼리문에 사용되는)
+					String requestInfo = (String) param.get("requestInfo");
+					// 페이징 증가
+					requestInfo = replaceLast(requestInfo, Integer.toString(i), Integer.toString(i+1));
+					// 변경된 파라미터값 삽입
+					param.put("requestInfo", requestInfo);
+
+					// 페이지가 1이상일 경우 추가로 합쳐야할 정보들
+					DataTable dataTable_ = getSeolData(url, apikeyList[0], param);
+					// 데이터 추가
+					for(int j = 0; j < dataTable_.getRowData().size(); j++) {
+						dataTable.getRowData().add(dataTable_.getRowData().get(j));
+					}
+				}
+				// 페이징 갯수가 1일 경우 한번만 호출
+			} else {
+				dataTable = getSeolData(url, apikeyList[0], param);
+			}
+		}
+		return dataTable;
+	}
+
+	/**
+	 * 마지막 문자열 치환
+	 */
+	public String replaceLast(String string, String toReplace, String replacement) {
+		int pos = string.lastIndexOf(toReplace);
+		if (pos > -1) {
+			return string.substring(0, pos)+ replacement + string.substring(pos +   toReplace.length(), string.length());
+		} else {
+			return string;
+		}
+	}
+
+	/**
+	 * 데이터 갯수 확인
+	 */
+	public int getSeolDataCnt(String url, String queryId) {
+		// 데이터 총 갯수
+		int cnt = 0;
+		// 해당 queryId에 맞는 정보 호출
+		Map<String, Object> param = (Map<String, Object>) getParam().get(queryId);
+		// 조회할 쿼리의 조건 값
+		String requestInfo = (String) param.get("requestInfo");
+		// 메세지 식별키
+		String msgkey = getMsgKey();
+		// 연계메세지 GPKI 암호화범위 <message></message>
+		// 암복호화는 표준보완API 이용(참조 : https://api.gpki.go.kr/)
+		String message = 	"<message>";
+		message = message + "  <body>";
+		message = message + "	<query_id>" + queryId + "</query_id>";
+		message = message + 	requestInfo;
+		message = message + "  </body>";
+		message = message + " </message>";
+		// API 요청 URL
+		url = "http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213";//상주시
+		try {
+			// 요청보낼 데이터 완성(XML)
+			String reqSoap = makeReqSoap(IFID, SRCORGCD, TGTORGCD, msgkey, message);
+			// API 요청
+			String resSoap = sendHttpRequest(url, reqSoap, CHARSET, IFID);
+			// 문서를 읽기 위한 공장 생성(DocumentBuilder(DOM 파서)를 생성시키는 Factory 클래스)
+			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+			// 빌더 생성(DOM파서 객체의 클래스)
+			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+			// XML문서 파싱
+			Document doc_ = dBuilder.parse(new ByteArrayInputStream(resSoap.getBytes()));
+			// DOM Tree XMl문서의 구조대로 완성
+			doc_.getDocumentElement().normalize();
+			// 특정 태그를 가진 모든 요소 선택(list 태그를 가진 요소 선택)
+			NodeList resultNode = doc_.getElementsByTagName("list");
+			for(int i = 0; i < resultNode.getLength(); i++) {
+				// 자식 노드 목록 호출
+				NodeList nList = resultNode.item(i).getChildNodes();
+				for(int j = 0; j < nList.getLength(); j++) {
+					// 노드 값
+					String nodeValue = nList.item(j).getTextContent();
+					// 정보 갯수
+					cnt = Integer.parseInt(nodeValue);
+				}
+			}
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+		}
+		return cnt;
+	}
+
+	/**
+	 * 데이터 수집
+	 *
+	 * queryId : 조회할 쿼리 ID
+	 * requestInfo : 조회할 쿼리의 조건 값 -> "<dataList><data>조건값</data></dataList>" 이런형태로 들어와야한다.(조건에 따라 다중으로 들어옴)
+	 * displayColumnName : 컬럼명(한글) 리스트
+	 * dataType_ : 해당 컬럼의 데이터 타입 리스트
+	 */
+	public DataTable getSeolData(String addr, String queryId, Map<String, Object> param) {
+		// 조회할 쿼리의 조건 값
+		String requestInfo = (String) param.get("requestInfo");
+		System.out.println("쿼리 확인 : " + requestInfo);
+		// 컬럼정보
+		List<ColumnData> columnDatas = (List<ColumnData>) param.get("columnDatas");
+		// 메세지 식별키
+		String msgkey = getMsgKey();
+		// 연계메세지 GPKI 암호화범위 <message></message>
+		// 암복호화는 표준보완API 이용(참조 : https://api.gpki.go.kr/)
+		String message = 	"<message>";
+		message = message + "  <body>";
+		message = message + "	<query_id>" + queryId + "</query_id>";
+		message = message + 	requestInfo;
+		message = message + "  </body>";
+		message = message + " </message>";
+		// API 요청 URL
+		addr = "http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213";//상주시
+		try {
+			// 요청보낼 데이터 완성(XML)
+			String reqSoap = makeReqSoap(IFID, SRCORGCD, TGTORGCD, msgkey, message);
+			System.out.println("reqSoap=>\n" + reqSoap);
+			// API 요청
+			String resSoap = sendHttpRequest(addr, reqSoap, CHARSET, IFID);
+			System.out.println("resSoap=>\n" + resSoap);
+			/** 리스트화 **/
+			// 문서를 읽기 위한 공장 생성(DocumentBuilder(DOM 파서)를 생성시키는 Factory 클래스)
+			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+			// 빌더 생성(DOM파서 객체의 클래스)
+			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+			// XML문서 파싱
+			Document doc_ = dBuilder.parse(new ByteArrayInputStream(resSoap.getBytes()));
+			// DOM Tree XMl문서의 구조대로 완성
+			doc_.getDocumentElement().normalize();
+			// 특정 태그를 가진 모든 요소 선택(list 태그를 가진 요소 선택)
+			NodeList resultNode = doc_.getElementsByTagName("list");
+			// 데이터 값
+			List<List<Object>> rm = new ArrayList<>();
+			for(int i = 0; i < resultNode.getLength(); i++) {
+				// 자식 노드 목록 호출
+				NodeList nList = resultNode.item(i).getChildNodes();
+				// 데이터 값
+				List<Object> nv = new ArrayList<>();
+				for(int j = 0; j < nList.getLength(); j++) {
+					// 노드 이름
+					String nodeName = nList.item(j).getNodeName();
+					// 노드 값
+					String nodeValue = nList.item(j).getTextContent();
+					if(nodeName.equals("#text")) continue;
+					nv.add(nodeValue);
+				}
+				rm.add(nv);
+			}
+			// 컬럼 값을 담을 빈 껍데기 생성
+			DataTable dataTable = new DataTable();
+			dataTable.setColumnDatas(columnDatas);
+			dataTable.setRowData(rm);
+			return dataTable;
+			/* 컬럼명(영문, 한문, 타입) 배열리스트로 담기 */
+		} catch(Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	// 메세지 식별키 생성 함수
+	private String getMsgKey() {
+		// 현재날짜와 시간
+		Date d = new Date();
+		// 날짜를 원하느 포맷으로 파싱
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssMS");
+		return sdf.format(d) + String.valueOf(Math.random()).substring(2, 10);
+	}
+
+	public synchronized String sendHttpRequest(String addr, String reqSoap, String charset, String soapAction) throws Exception {
+		OutputStream os = null;
+		BufferedWriter out = null;
+		InputStreamReader is = null;
+		BufferedReader bf = null;
+		StringBuffer response = null;
+		HttpURLConnection connection = null;
+
+		try {
+			URL _url = new URL(addr);
+			connection = (HttpURLConnection) _url.openConnection();
+			connection.setRequestMethod("POST");
+			connection.setDoOutput(true);
+			connection.setDoInput(true);
+			connection.setUseCaches(false);
+			connection.setDefaultUseCaches(false);
+			connection.setRequestProperty("Content-Type", "text/xml; charset=" + charset);
+			connection.setRequestProperty("Accept", "application/soap+xml, application/dime, multipart/related, text/*");
+			connection.setRequestProperty("SOAPAction", soapAction);
+			connection.setConnectTimeout(1000 * 60 * 10);
+			os = connection.getOutputStream();
+			out = new BufferedWriter(new OutputStreamWriter(os, charset));
+			out.write(reqSoap);
+			out.close();
+			is = new InputStreamReader(connection.getInputStream(), charset);
+			bf = new BufferedReader(is);
+			response = new StringBuffer();
+			String responsetemp;
+			while ((responsetemp = bf.readLine()) != null) {
+				response.append(responsetemp);
+			}
+			bf.close();
+		} catch (Exception e) {
+			throw e;
+		} finally {
+			if (is != null) {
+				is.close();
+			}
+			if (os != null) {
+				os.close();
+			}
+			if (bf != null) {
+				bf.close();
+			}
+			if (out != null) {
+				out.close();
+			}
+			if (connection != null) {
+				connection = null;
+			}
+		}
+		return response.toString();
+	}
+
+	public String makeReqSoap(String ifid, String srcorgcd, String tgtorgcd, String msgkey, String message) throws Exception {
+		StringBuffer sb = new StringBuffer();
+		sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">");
+		sb.append("   <soapenv:Header/>                        ");
+		sb.append("   <soapenv:Body>                           ");
+		sb.append("      <DOCUMENT>                            ");
+		sb.append("         <IFID>" + ifid + "</IFID>              ");
+		sb.append("         <SRCORGCD>" + srcorgcd + "</SRCORGCD>  ");
+		sb.append("         <TGTORGCD>" + tgtorgcd + "</TGTORGCD>  ");
+		sb.append("         <RESULTCODE>000</RESULTCODE>       ");
+		sb.append("         <MSGKEY>" + msgkey + "</MSGKEY>        ");
+		sb.append("         <DATA>                             ");
+		sb.append(message);
+		sb.append("         </DATA>                            ");
+		sb.append("      </DOCUMENT>                           ");
+		sb.append("   </soapenv:Body>                          ");
+		sb.append("</soapenv:Envelope>                         ");
+		return sb.toString();
+	}
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ApiParam.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ApiParam.java
@@ -0,0 +1,71 @@
+package com.takensoft.taken_bi_manager.common.connection.api.vo;
+
+
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2021.11.02
+ * 
+ * Api 커넥션의 파라미터 정보를 담습니다. 
+ */
+@Getter
+@Setter
+public class ApiParam implements Serializable {
+	
+	/**
+	 * 시리얼 버전
+	 */	
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 파라미터 DB저장 Key값
+	 */
+	private String paramId;	
+	
+	/**
+	 *  파라미터 순서
+	 */
+	private int index;
+	
+	/**
+	 * 파라미터 Key값
+	 */
+	private String key;
+	
+	/**
+	 * 파라미터 value값
+	 */
+	private Object value;
+	
+	/**
+	 * encode 제외 변수
+	 */
+	private boolean disableDecode;
+	
+	/**
+	 * 날짜계산 변수
+	 */
+	private boolean dateForm = false;	
+	
+	
+//	/**
+//	 * 날자 제어 타입(year, month, day)
+//	 */
+//	private String dateType;
+	
+	/**
+	 * 날자 제어변수 
+	 */
+	private int addMonth = 0;
+
+	
+	public static long getSerialversionuid() {
+		return serialVersionUID;
+	}
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ConnectionApi.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ConnectionApi.java
@@ -0,0 +1,98 @@
+package com.takensoft.taken_bi_manager.common.connection.api.vo;
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+import com.takensoft.taken_bi_manager.jobs.vo.JobItm;
+import com.takensoft.taken_bi_manager.jobs.vo.item.JobReadConItm;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2021.11.02
+ * 
+ * Api 커넥션 정보를 담는 Class 
+ */
+@Getter
+@Setter
+public class ConnectionApi extends JobReadConItm implements Serializable {
+
+	
+	/**
+	 * 연계 PAI 제목
+	 */	
+	private String title;
+	
+	/**
+	 * 연계 url
+	 */	
+	private String url;
+
+	/**
+	 * 연계 타입 1 = json, 2=xml
+	 */	
+	private int type;
+	
+	/**
+	 * 연계 타입 1 = post, 2 = get
+	 */	
+	private int requestType;
+	
+	/**
+	 * 연계 결과
+	 */	
+	private String result;
+	
+	/**
+	 * 뎁스설정  구분자 > 
+	 */	
+	private String depth;
+	
+	/**
+	 * 파라미터 리스트
+	 */	
+	private List<ApiParam> params = new  ArrayList<ApiParam>();
+	
+	/**
+	 * 데이터(행,열)의 컬럼인 Row의 Index
+	 */
+	private int rowDataColumnIndex;
+	
+	/**
+	 * 데이터(행,열)의 Row 시작 Index
+	 */
+	private int startRowIndex;
+	
+	/**
+	 * 데이터(행,열)의 Cell 시작 Index
+	 */
+	private int startCellIndex;
+
+
+	//추가 dataset_post_id
+	private String dataset_post_id;
+	
+	public ConnectionApi() {
+		this.params = new ArrayList<ApiParam>();
+		this.type = 1;
+	}	
+
+	
+	public Map<String, Object> paramstoMap(){
+		Map<String, Object> result = new HashMap<String,Object>();
+		
+		// this.params -> map 
+		for(int i=0; i< this.params.size(); i++	) {
+			result.put(this.params.get(i).getKey(), this.params.get(i).getValue());
+		}
+		
+		return result;
+	}
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/api/web/ConnectionApiRestController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/web/ConnectionApiRestController.java
@@ -0,0 +1,60 @@
+
+package com.takensoft.taken_bi_manager.common.connection.api.web;
+
+import com.takensoft.taken_bi_manager.common.connection.api.service.ConnectionApiService;
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+@RequiredArgsConstructor
+public class ConnectionApiRestController {
+    private final ConnectionApiService connectionApiService;
+
+    /**
+     * @author 이원호
+     * @since 2021.11.03
+     *
+     * OpenApi 호출
+     */
+    @RequestMapping(value ="/apiRequestTest.json", method = RequestMethod.POST)
+    public ModelAndView logSelectListAll(@RequestBody ConnectionApi params) throws Exception {
+        ModelAndView mav = new ModelAndView("jsonView");
+        mav.addObject("apiResponseResult", connectionApiService.apiRequestTest(params));
+        return mav;
+    }
+
+    /**
+     * @author 이원호
+     * @since 2021.11.05
+     *
+     * Api dataTable 호출
+     */
+    @RequestMapping(value ="/getApiDataTable.json", method = RequestMethod.POST)
+    public ModelAndView getApiDataTable(@RequestBody ConnectionApi connectionApi) throws Exception{
+        ModelAndView mav = new ModelAndView("jsonView");
+        DataTable dataTable = connectionApiService.apiRequest(connectionApi);
+        mav.addObject("dataTableResult", dataTable);
+
+        return mav;
+    }
+
+    /**
+     * @author 이원호
+     * @since 2021.11.10
+     *
+     * API 연계정보 등록
+     */
+    @RequestMapping(value ="/apiConnectionInfoInsert.json", method = RequestMethod.POST)
+    public ModelAndView apiConnectionInfoInsert( @RequestBody ConnectionApi connectionApi ) throws Exception{
+        ModelAndView mav = new ModelAndView("jsonView");
+        connectionApiService.apiConnectionInfoInsert(connectionApi);
+        connectionApiService.apiParameterInfoInsert(connectionApi);
+        mav.addObject("dataTableResult", "success");
+
+        return mav;
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/DatabaseDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/DatabaseDAO.java
@@ -0,0 +1,239 @@
+package com.takensoft.taken_bi_manager.common.connection.db.dao;
+
+
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+
+
+/**
+ * @author 김성원
+ * @since 2024.01.09
+ * 
+ * 데이터베이스 접속 모듈에 관련된 SQL문에 접근하는 DAO 추상 Class입니다.
+ */
+public abstract class DatabaseDAO {
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * SqlSessionTemplate 생성 메서드 입니다.
+	 */
+	public abstract void createConnector (ConnectionDB db) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 접속한 데이터베이스의 테이블 목록 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	public abstract List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등)
+	 */
+	public abstract List<ColumnData> getDBConnectionTableColumnList (Dataset dataset) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	public abstract List<LinkedHashMap<String, Object>> getDBConnectionTableDataList (DataTable datatable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	public abstract int getDBConnectionTableDataTotalRows (DataTable datatable) throws Exception;
+	
+		
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	public abstract List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList (DataTable datatable) throws Exception;
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 조회 없는 실행형 쿼리 
+	 */
+	public abstract int executeCustomQuery (DataTable datatable) throws Exception;
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.097
+	 * 
+	 * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	public abstract int getDBConnectionCustomQueryDataTotalRows (DataTable datatable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴)
+	 */
+	public abstract List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList (DataTable datatable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * DB연계 데이터 목록 총 갯수 조회
+	 */
+	public abstract int getDBCollectionQueryDataTotalRows (DataTable datatable) throws Exception;
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) 
+	 */
+	public abstract int getCustomQueryPrimaryOverlapCount (DataTable datatable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * DataSource Close
+	 */
+	public abstract void dbConnectionClose() throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 쿼리 실행후, 실행한 쿼리문 조회
+	 */
+	public abstract String getQuery (String id, Object parameter) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커넥션된 데이터베이스의 실제 테이블 생성(pk 존재유)
+	 */
+	public abstract int datasetTableCreate(DataTable datatable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커넥션된 데이터베이스의 실제 테이블 생성(pk 존재무)
+	 */
+	public abstract int datasetDefaultTableCreate(DataTable datatable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 커넥션된 데이터 베이스 데이터 업데이트(pk 존재무)
+	 */
+	public abstract void datasetDataUpdate(DataTable datatable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 데이터 셋의 ROW 삭제
+	 */
+	public abstract void datasetDataDelete(DataTable datatable) throws Exception;
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 커넥션된 데이터 베이스 중복체크 (pk 존재무)
+	 */
+	public abstract int duplicateCheckTableName(Map info) throws Exception;
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징)
+	 */
+	public abstract List<LinkedHashMap<String, Object>> getRowData (DataTable dataTable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(x)
+	 */
+	public abstract List<LinkedHashMap<String, Object>> getRowDataAll (DataTable dataTable) throws Exception;
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.12.09
+	 * 
+	 * 데이터 셋의 컬럼 정보 목록 총 갯수 조회 메소드 입니다.
+	 */
+	public abstract int getRowDataTotalRows (DataTable dataTable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.1.12
+	 * 
+	 *  데이터 셋의 비우기 (데이터 셋 내용삭제)
+	 */
+	public abstract int emptyDataset (DataTable dataTable) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.1.20
+	 * 
+	 *  실제 생성된 컬럼 변경
+	 */
+	public abstract int  tableColumnChange (TableBasicInfo tableBasicInfo) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.1.20
+	 * 
+	 *  실제 생성된 테이블 PK처리
+	 */
+	public abstract int  changePrimaryKey (TableBasicInfo tableBasicInfo) throws Exception;
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.1.20
+	 * 
+	 *  AI PK 생성 
+	 */
+	public abstract int  createAutoIncrement (TableBasicInfo tableBasicInfo) throws Exception;
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.09.30
+	 * 
+	 *  테이블 명 변경
+	 *   
+	 */
+	public abstract void updateTableMetaInfo(DataTable dataTable)  throws Exception;
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MariadbDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MariadbDAO.java
@@ -0,0 +1,291 @@
+package com.takensoft.taken_bi_manager.common.connection.db.dao;
+
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.stereotype.Repository;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+
+
+/**
+	 * @author 김성원
+	 * @since 2024.01.09
+ * 
+ * Mariadb 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다.
+ */
+@Repository
+public class MariadbDAO extends DatabaseDAO {
+	
+	public MariadbDAO () {}
+	
+	public MariadbDAO (ConnectionDB db) throws Exception {
+		this.createConnector(db);
+	}
+	
+	private DBConnectionConfig dbUtil = null;
+	
+	public DBConnectionConfig getDbUtil() {
+		return dbUtil;
+	}
+	public void setDbUtil(DBConnectionConfig dbUtil) {
+		this.dbUtil = dbUtil;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * SqlSessionTemplate 생성 메서드 입니다.
+	 */
+	@Override
+	public void createConnector (ConnectionDB db) throws Exception {
+		dbUtil = new DBConnectionConfig();
+		dbUtil.mybatisSqlTemplateCreate(db);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 접속한 데이터베이스의 테이블 목록 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	@Override
+	public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception {
+		try {
+			return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableList", db);
+		} catch (Exception e) {
+			return new ArrayList<Dataset>();
+		}
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등)
+	 */
+	@Override
+	public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception {
+		return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableColumnList", dataset);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	@Override
+	public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList (DataTable datatable) throws Exception {
+		return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableDataList", datatable);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	@Override
+	public int getDBConnectionTableDataTotalRows (DataTable datatable) throws Exception {
+		return dbUtil.getTemplate().selectOne("MariadbDAO.getDBConnectionTableDataTotalRows", datatable);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커스텀 테이블 데이터 조회 (페이징사용 유무에 따라 페이징 처리) SQL에 접근하는 메소드 입니다.
+	 */
+	@Override
+	public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList (DataTable datatable) throws Exception {
+		return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionCustomQueryDataList", datatable);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커스텀 테이블 데이터 목록 총 갯수 조회 SQL에 접근하는 메소드 입니다.
+	 */
+	@Override
+	public int getDBConnectionCustomQueryDataTotalRows (DataTable datatable) throws Exception {
+		return dbUtil.getTemplate().selectOne("MariadbDAO.getDBConnectionCustomQueryDataTotalRows", datatable);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴)
+	 */
+	@Override
+	public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList (DataTable datatable) throws Exception {
+		return dbUtil.getTemplate().selectList("MariadbDAO.getDBCollectionQueryDataList", datatable);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * DB연계 데이터 목록 총 갯수 조회
+	 */
+	@Override
+	public int getDBCollectionQueryDataTotalRows (DataTable datatable) throws Exception {
+		return dbUtil.getTemplate().selectOne("MariadbDAO.getDBCollectionQueryDataTotalRows", datatable);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) 
+	 */
+	@Override
+	public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception {
+		return dbUtil.getTemplate().selectOne("MariadbDAO.getCustomQueryPrimaryOverlapCount", datatable);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * SqlSessionTemplate Close
+	 */
+	@Override
+	public void dbConnectionClose() throws Exception {
+		dbUtil.close();
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 쿼리 실행후, 실행한 쿼리문 조회
+	 */
+	@Override
+	public String getQuery (String id, Object parameter) throws Exception {
+		SqlSessionTemplate template = dbUtil.getTemplate();
+		
+		id = "OracleDAO." + id;
+		
+	    String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql();
+	    List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings();
+	    
+	    ObjectMapper mapper = new ObjectMapper();
+	    String json = mapper.writeValueAsString(parameter);
+	    HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){});
+	    for (ParameterMapping par : paramMap) {
+	        String param = StringUtil.toString(params.get(par.getProperty()));
+	        if(parameter == null)
+	            sql = sql.replaceFirst("\\?", "NULL");
+	        else
+	            sql = sql.replaceFirst("\\?", "'" + param + "'");
+	    }
+
+	    return sql;
+	}
+
+	@Override
+	public int datasetTableCreate(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("MariadbDAO.datasetTableCreate", datatable);
+	}
+
+	@Override
+	public int datasetDefaultTableCreate(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("MariadbDAO.datasetDefaultTableCreate", datatable);
+	}
+
+	@Override
+	public void datasetDataUpdate(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		dbUtil.getTemplate().update("MariadbDAO.datasetDataUpdate", datatable);
+	}
+
+	@Override
+	public int duplicateCheckTableName(Map info) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("MariadbDAO.duplicateCheckTableName", info);
+	}
+
+	@Override
+	public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectList("MariadbDAO.getRowData", dataTable);
+	}
+
+	@Override
+	public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception {
+		return dbUtil.getTemplate().selectList("MariadbDAO.getRowDataAll", dataTable);		
+	}
+
+	@Override
+	public int getRowDataTotalRows(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("MariadbDAO.getRowDataTotalRows", dataTable);		
+	}
+
+	@Override
+	public int emptyDataset(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().delete("MariadbDAO.emptyDataset", dataTable);		
+	}
+
+	@Override
+	public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("MariadbDAO.tableColumnChange", tableBasicInfo);	
+	}
+
+
+	@Override
+	public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("MariadbDAO.changePromaryKey", tableBasicInfo);	
+	}
+
+
+	@Override
+	public void datasetDataDelete(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		dbUtil.getTemplate().delete("MariadbDAO.datasetDataDelete", datatable);	
+	}
+
+	@Override
+	public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception {
+		
+		return dbUtil.getTemplate().update("MariadbDAO.createAutoIncrement", tableBasicInfo);	
+
+	}
+
+	@Override
+	public int executeCustomQuery(DataTable datatable) throws Exception {
+	
+		return dbUtil.getTemplate().update("MariadbDAO.executeCustomQuery", datatable);	
+	}
+
+
+	@Override
+	public void updateTableMetaInfo(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MssqlDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MssqlDAO.java
@@ -0,0 +1,195 @@
+package com.takensoft.taken_bi_manager.common.connection.db.dao;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+
+/**
+ * @author 박민혁
+ * @since 2024.04.04
+ *
+ * MssqlDAO 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다.
+ */
+@Repository
+public class MssqlDAO extends DatabaseDAO {
+
+    public MssqlDAO () {}
+
+    public MssqlDAO (ConnectionDB db) throws Exception{
+        this.createConnector(db);
+    }
+
+    private DBConnectionConfig dbUtil = null;
+
+    public DBConnectionConfig getDbUtil() {
+        return dbUtil;
+    }
+    public void setDbUtil(DBConnectionConfig dbUtil) {
+        this.dbUtil = dbUtil;
+    }
+
+    @Override
+    public void createConnector (ConnectionDB db) throws Exception {
+        dbUtil = new DBConnectionConfig();
+        dbUtil.mybatisSqlTemplateCreate(db);
+    }
+
+    @Override
+    public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception {
+        try {
+            return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionTableList", db);
+        } catch (Exception e) {
+            return new ArrayList<Dataset>();
+        }
+    }
+
+    @Override
+    public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception {
+        return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionTableColumnList", dataset);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionTableDataList", datatable);
+    }
+
+    @Override
+    public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MssqlDAO.getDBConnectionTableDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionCustomQueryDataList", datatable);
+    }
+
+    @Override
+    public int executeCustomQuery(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("MssqlDAO.executeCustomQuery", datatable);
+    }
+
+    @Override
+    public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MssqlDAO.getDBConnectionCustomQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("MssqlDAO.getDBCollectionQueryDataList", datatable);
+    }
+
+    @Override
+    public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MssqlDAO.getDBCollectionQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MssqlDAO.getCustomQueryPrimaryOverlapCount", datatable);
+    }
+
+    @Override
+    public void dbConnectionClose() throws Exception {
+        dbUtil.close();
+    }
+
+    @Override
+    public String getQuery(String id, Object parameter) throws Exception {
+        SqlSessionTemplate template = dbUtil.getTemplate();
+
+        id = "MssqlDAO." + id;
+
+        String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql();
+        List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings();
+
+        ObjectMapper mapper = new ObjectMapper();
+        String json = mapper.writeValueAsString(parameter);
+        HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){});
+        for (ParameterMapping par : paramMap) {
+            String param = StringUtil.toString(params.get(par.getProperty()));
+            if(parameter == null)
+                sql = sql.replaceFirst("\\?", "NULL");
+            else
+                sql = sql.replaceFirst("\\?", "'" + param + "'");
+        }
+
+        return sql;
+    }
+
+    @Override
+    public int datasetTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("MssqlDAO.datasetTableCreate", datatable);
+    }
+
+    @Override
+    public int datasetDefaultTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("MssqlDAO.datasetDefaultTableCreate", datatable);
+    }
+
+    @Override
+    public void datasetDataUpdate(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().update("MssqlDAO.datasetDataUpdate", datatable);
+    }
+
+    @Override
+    public void datasetDataDelete(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().delete("MssqlDAO.datasetDataDelete", datatable);
+    }
+
+    @Override
+    public int duplicateCheckTableName(Map info) throws Exception {
+        return dbUtil.getTemplate().selectOne("MssqlDAO.duplicateCheckTableName", info);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("MssqlDAO.getRowData", dataTable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("MssqlDAO.getRowDataAll", dataTable);
+    }
+
+    @Override
+    public int getRowDataTotalRows(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MssqlDAO.getRowDataTotalRows", dataTable);
+    }
+
+    @Override
+    public int emptyDataset(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().delete("MssqlDAO.emptyDataset", dataTable);
+    }
+
+    @Override
+    public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("MssqlDAO.tableColumnChange", tableBasicInfo);
+    }
+
+    @Override
+    public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("MssqlDAO.changePromaryKey", tableBasicInfo);
+    }
+
+    @Override
+    public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("MssqlDAO.createAutoIncrement", tableBasicInfo);
+    }
+
+    @Override
+    public void updateTableMetaInfo(DataTable dataTable) throws Exception {
+        dbUtil.getTemplate().update("MssqlDAO.updateTableMetaInfo", dataTable);
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MysqlDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MysqlDAO.java
@@ -0,0 +1,193 @@
+package com.takensoft.taken_bi_manager.common.connection.db.dao;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+
+/**
+ * @author 박민혁
+ * @since 2024.03.28
+ *
+ * Mysql 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다.
+ */
+@Repository
+public class MysqlDAO extends DatabaseDAO {
+
+    public MysqlDAO (){}
+
+    public MysqlDAO (ConnectionDB db) throws Exception{
+        this.createConnector(db);
+    }
+    private DBConnectionConfig dbUtil = null;
+
+    public DBConnectionConfig getDbUtil() {
+        return dbUtil;
+    }
+    public void setDbUtil(DBConnectionConfig dbUtil) {
+        this.dbUtil = dbUtil;
+    }
+
+    @Override
+    public void createConnector (ConnectionDB db) throws Exception {
+        dbUtil = new DBConnectionConfig();
+        dbUtil.mybatisSqlTemplateCreate(db);
+    }
+
+    @Override
+    public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception {
+        try {
+            return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionTableList", db);
+        } catch (Exception e) {
+            return new ArrayList<Dataset>();
+        }
+    }
+
+    @Override
+    public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception {
+        return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionTableColumnList", dataset);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionTableDataList", datatable);
+    }
+
+    @Override
+    public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MysqlDAO.getDBConnectionTableDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionCustomQueryDataList", datatable);
+    }
+
+    @Override
+    public int executeCustomQuery(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("MysqlDAO.executeCustomQuery", datatable);
+    }
+
+    @Override
+    public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MysqlDAO.getDBConnectionCustomQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("MysqlDAO.getDBCollectionQueryDataList", datatable);
+    }
+
+    @Override
+    public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MysqlDAO.getDBCollectionQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MysqlDAO.getCustomQueryPrimaryOverlapCount", datatable);
+    }
+
+    @Override
+    public void dbConnectionClose() throws Exception {
+        dbUtil.close();
+    }
+
+    @Override
+    public String getQuery(String id, Object parameter) throws Exception {
+        SqlSessionTemplate template = dbUtil.getTemplate();
+
+        id = "MysqlDAO." + id;
+
+        String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql();
+        List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings();
+
+        ObjectMapper mapper = new ObjectMapper();
+        String json = mapper.writeValueAsString(parameter);
+        HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){});
+        for (ParameterMapping par : paramMap) {
+            String param = StringUtil.toString(params.get(par.getProperty()));
+            if(parameter == null)
+                sql = sql.replaceFirst("\\?", "NULL");
+            else
+                sql = sql.replaceFirst("\\?", "'" + param + "'");
+        }
+
+        return sql;
+    }
+
+    @Override
+    public int datasetTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("MysqlDAO.datasetTableCreate", datatable);
+    }
+
+    @Override
+    public int datasetDefaultTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("MysqlDAO.datasetDefaultTableCreate", datatable);
+    }
+
+    @Override
+    public void datasetDataUpdate(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().update("MysqlDAO.datasetDataUpdate", datatable);
+    }
+
+    @Override
+    public void datasetDataDelete(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().delete("MysqlDAO.datasetDataDelete", datatable);
+    }
+
+    @Override
+    public int duplicateCheckTableName(Map info) throws Exception {
+        return dbUtil.getTemplate().selectOne("MysqlDAO.duplicateCheckTableName", info);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("MysqlDAO.getRowData", dataTable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("MysqlDAO.getRowDataAll", dataTable);
+    }
+
+    @Override
+    public int getRowDataTotalRows(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectOne("MysqlDAO.getRowDataTotalRows", dataTable);
+    }
+
+    @Override
+    public int emptyDataset(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().delete("MysqlDAO.emptyDataset", dataTable);
+    }
+
+    @Override
+    public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("MysqlDAO.tableColumnChange", tableBasicInfo);
+    }
+
+    @Override
+    public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("MysqlDAO.changePromaryKey", tableBasicInfo);
+    }
+
+    @Override
+    public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("MysqlDAO.createAutoIncrement", tableBasicInfo);
+    }
+
+    @Override
+    public void updateTableMetaInfo(DataTable dataTable) throws Exception {
+        dbUtil.getTemplate().update("MysqlDAO.updateTableMetaInfo", dataTable);
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/OracleDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/OracleDAO.java
@@ -0,0 +1,194 @@
+package com.takensoft.taken_bi_manager.common.connection.db.dao;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+
+/**
+ * @author 박민혁
+ * @since 2024.03.28
+ *
+ * Oracle 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다.
+ */
+@Repository
+public class OracleDAO extends DatabaseDAO {
+    public OracleDAO(){}
+
+    public OracleDAO(ConnectionDB db) throws Exception{
+        this.createConnector(db);
+    }
+
+    private DBConnectionConfig dbUtil = null;
+
+    public DBConnectionConfig getDbUtil() {
+        return dbUtil;
+    }
+    public void setDbUtil(DBConnectionConfig dbUtil) {
+        this.dbUtil = dbUtil;
+    }
+
+    @Override
+    public void createConnector (ConnectionDB db) throws Exception {
+        dbUtil = new DBConnectionConfig();
+        dbUtil.mybatisSqlTemplateCreate(db);
+    }
+
+    @Override
+    public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception {
+        try {
+            return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionTableList", db);
+        } catch (Exception e) {
+            return new ArrayList<Dataset>();
+        }
+    }
+
+    @Override
+    public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception {
+        return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionTableColumnList", dataset);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionTableDataList", datatable);
+    }
+
+    @Override
+    public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("OracleDAO.getDBConnectionTableDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionCustomQueryDataList", datatable);
+    }
+
+    @Override
+    public int executeCustomQuery(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("OracleDAO.executeCustomQuery", datatable);
+    }
+
+    @Override
+    public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("OracleDAO.getDBConnectionCustomQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("OracleDAO.getDBCollectionQueryDataList", datatable);
+    }
+
+    @Override
+    public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("OracleDAO.getDBCollectionQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("OracleDAO.getCustomQueryPrimaryOverlapCount", datatable);
+    }
+
+    @Override
+    public void dbConnectionClose() throws Exception {
+        dbUtil.close();
+    }
+
+    @Override
+    public String getQuery(String id, Object parameter) throws Exception {
+        SqlSessionTemplate template = dbUtil.getTemplate();
+
+        id = "OracleDAO." + id;
+
+        String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql();
+        List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings();
+
+        ObjectMapper mapper = new ObjectMapper();
+        String json = mapper.writeValueAsString(parameter);
+        HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){});
+        for (ParameterMapping par : paramMap) {
+            String param = StringUtil.toString(params.get(par.getProperty()));
+            if(parameter == null)
+                sql = sql.replaceFirst("\\?", "NULL");
+            else
+                sql = sql.replaceFirst("\\?", "'" + param + "'");
+        }
+
+        return sql;
+    }
+
+    @Override
+    public int datasetTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("OracleDAO.datasetTableCreate", datatable);
+    }
+
+    @Override
+    public int datasetDefaultTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("OracleDAO.datasetDefaultTableCreate", datatable);
+    }
+
+    @Override
+    public void datasetDataUpdate(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().update("OracleDAO.datasetDataUpdate", datatable);
+    }
+
+    @Override
+    public void datasetDataDelete(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().delete("OracleDAO.datasetDataDelete", datatable);
+    }
+
+    @Override
+    public int duplicateCheckTableName(Map info) throws Exception {
+        return dbUtil.getTemplate().selectOne("OracleDAO.duplicateCheckTableName", info);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("OracleDAO.getRowData", dataTable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("OracleDAO.getRowDataAll", dataTable);
+    }
+
+    @Override
+    public int getRowDataTotalRows(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectOne("OracleDAO.getRowDataTotalRows", dataTable);
+    }
+
+    @Override
+    public int emptyDataset(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().delete("OracleDAO.emptyDataset", dataTable);
+    }
+
+    @Override
+    public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("OracleDAO.tableColumnChange", tableBasicInfo);
+    }
+
+    @Override
+    public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("OracleDAO.changePromaryKey", tableBasicInfo);
+    }
+
+    @Override
+    public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("OracleDAO.createAutoIncrement", tableBasicInfo);
+    }
+
+    @Override
+    public void updateTableMetaInfo(DataTable dataTable) throws Exception {
+        dbUtil.getTemplate().update("OracleDAO.updateTableMetaInfo", dataTable);
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/PostgresqlDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/PostgresqlDAO.java
@@ -0,0 +1,228 @@
+package com.takensoft.taken_bi_manager.common.connection.db.dao;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.mybatis.spring.SqlSessionTemplate;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+
+
+
+public class PostgresqlDAO  extends DatabaseDAO {
+
+	public PostgresqlDAO () {}
+	
+	public PostgresqlDAO (ConnectionDB db) throws Exception {
+		this.createConnector(db);
+	}
+	
+	private DBConnectionConfig dbUtil = null;
+	
+	public DBConnectionConfig getDbUtil() {
+		return dbUtil;
+	}
+	public void setDbUtil(DBConnectionConfig dbUtil) {
+		this.dbUtil = dbUtil;
+	}
+	
+	
+	@Override
+	public void createConnector(ConnectionDB db) throws Exception {
+		// TODO Auto-generated method stub
+		dbUtil = new DBConnectionConfig();
+		dbUtil.mybatisSqlTemplateCreate(db);
+	}
+
+	@Override
+	public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception {
+		// TODO Auto-generated method stub
+		try {
+			return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableList", db);
+		} catch (Exception e) {
+			return new ArrayList<Dataset>();
+		}
+	}
+
+	@Override
+	public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableColumnList", dataset);
+	}
+
+	@Override
+	public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableDataList", datatable);
+	}
+
+	@Override
+	public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBConnectionTableDataTotalRows", datatable);
+	}
+
+	@Override
+	public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable)
+			throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionCustomQueryDataList", datatable);
+	}
+
+	@Override
+	public int executeCustomQuery(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("PostgresqlDAO.executeCustomQueryDataList", datatable);
+	}
+
+	@Override
+	public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBConnectionCustomQueryDataTotalRows", datatable);
+	}
+
+	@Override
+	public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBCollectionQueryDataList", datatable);
+	}
+
+	@Override
+	public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBCollectionQueryDataTotalRows", datatable);
+	}
+
+	@Override
+	public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("getCustomQueryPrimaryOverlapCount.getCustomQueryPrimaryOverlapCount", datatable);
+	}
+
+	@Override
+	public void dbConnectionClose() throws Exception {
+		dbUtil.close();
+	}
+
+	@Override
+	public String getQuery(String id, Object parameter) throws Exception {
+		SqlSessionTemplate template = dbUtil.getTemplate();
+		
+		id = "PostgresqlDAO." + id;
+		
+	    String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql();
+	    List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings();
+	    
+	    ObjectMapper mapper = new ObjectMapper();
+	    String json = mapper.writeValueAsString(parameter);
+	    HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){});
+	    for (ParameterMapping par : paramMap) {
+	        String param = StringUtil.toString(params.get(par.getProperty()));
+	        if(parameter == null)
+	            sql = sql.replaceFirst("\\?", "NULL");
+	        else
+	            sql = sql.replaceFirst("\\?", "'" + param + "'");
+	    }
+
+	    return sql;
+	}
+
+	@Override
+	public int datasetTableCreate(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("PostgresqlDAO.datasetTableCreate", datatable);
+	}
+
+	@Override
+	public int datasetDefaultTableCreate(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("PostgresqlDAO.datasetDefaultTableCreate", datatable);
+	}
+
+	@Override
+	public void datasetDataUpdate(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		dbUtil.getTemplate().update("PostgresqlDAO.datasetDataUpdate", datatable);
+	}
+
+	@Override
+	public void datasetDataDelete(DataTable datatable) throws Exception {
+		// TODO Auto-generated method stub
+		dbUtil.getTemplate().update("PostgresqlDAO.datasetDataDelete", datatable);
+	}
+
+	@Override
+	public int duplicateCheckTableName(Map info) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("PostgresqlDAO.duplicateCheckTableName", info);
+	}
+
+	@Override
+	public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectList("PostgresqlDAO.getRowData", dataTable);
+	}
+
+	@Override
+	public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		
+		ObjectMapper mapper = new ObjectMapper();
+
+		
+		return dbUtil.getTemplate().selectList("PostgresqlDAO.getRowDataAll", dataTable);		
+	}
+
+	@Override
+	public int getRowDataTotalRows(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().selectOne("PostgresqlDAO.getRowDataTotalRows", dataTable);
+	}
+
+	@Override
+	public int emptyDataset(DataTable dataTable) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().delete("PostgresqlDAO.emptyDataset", dataTable);
+	}
+
+	@Override
+	public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception {
+		// TODO Auto-generated method stub
+		ObjectMapper mapper = new ObjectMapper();
+		
+
+		return dbUtil.getTemplate().update("PostgresqlDAO.tableColumnChange", tableBasicInfo);	
+	}
+
+	@Override
+	public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("PostgresqlDAO.changePromaryKey", tableBasicInfo);	
+	}
+
+	@Override
+	public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception {
+		// TODO Auto-generated method stub
+		return dbUtil.getTemplate().update("PostgresqlDAO.createAutoIncrement", tableBasicInfo);	
+	}
+	
+
+	@Override
+	public void updateTableMetaInfo(DataTable dataTable) throws Exception {
+		dbUtil.getTemplate().update("PostgresqlDAO.updateTableMetaInfo", dataTable);
+		
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/TiberoDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/TiberoDAO.java
@@ -0,0 +1,193 @@
+package com.takensoft.taken_bi_manager.common.connection.db.dao;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.util.*;
+
+/**
+ * @author 박민혁
+ * @since 2024.04.08
+ *
+ * Tebero 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다.
+ */
+@Repository
+public class TiberoDAO extends DatabaseDAO{
+    public TiberoDAO(){}
+
+    public TiberoDAO(ConnectionDB db) throws Exception{
+        this.createConnector(db);
+    }
+
+    private DBConnectionConfig dbUtil = null;
+
+    public DBConnectionConfig getDbUtil() {
+        return dbUtil;
+    }
+    public void setDbUtil(DBConnectionConfig dbUtil) {
+        this.dbUtil = dbUtil;
+    }
+
+    @Override
+    public void createConnector(ConnectionDB db) throws Exception {
+        dbUtil = new DBConnectionConfig();
+        dbUtil.mybatisSqlTemplateCreate(db);
+    }
+
+    @Override
+    public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception {
+        try {
+            return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionTableList", db);
+        } catch (Exception e) {
+            return new ArrayList<Dataset>();
+        }
+    }
+
+    @Override
+    public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception {
+        return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionTableColumnList", dataset);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionTableDataList", datatable);
+    }
+
+    @Override
+    public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("TiberoDAO.getDBConnectionTableDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionCustomQueryDataList", datatable);
+    }
+
+    @Override
+    public int executeCustomQuery(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("TiberoDAO.executeCustomQuery", datatable);
+    }
+
+    @Override
+    public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("TiberoDAO.getDBConnectionCustomQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectList("TiberoDAO.getDBCollectionQueryDataList", datatable);
+    }
+
+    @Override
+    public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("TiberoDAO.getDBCollectionQueryDataTotalRows", datatable);
+    }
+
+    @Override
+    public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().selectOne("TiberoDAO.getCustomQueryPrimaryOverlapCount", datatable);
+    }
+
+    @Override
+    public void dbConnectionClose() throws Exception {
+        dbUtil.close();
+    }
+
+    @Override
+    public String getQuery(String id, Object parameter) throws Exception {
+        SqlSessionTemplate template = dbUtil.getTemplate();
+
+        id = "TiberoDAO." + id;
+
+        String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql();
+        List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings();
+
+        ObjectMapper mapper = new ObjectMapper();
+        String json = mapper.writeValueAsString(parameter);
+        HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){});
+        for (ParameterMapping par : paramMap) {
+            String param = StringUtil.toString(params.get(par.getProperty()));
+            if(parameter == null)
+                sql = sql.replaceFirst("\\?", "NULL");
+            else
+                sql = sql.replaceFirst("\\?", "'" + param + "'");
+        }
+
+        return sql;
+    }
+
+    @Override
+    public int datasetTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("TiberoDAO.datasetTableCreate", datatable);
+    }
+
+    @Override
+    public int datasetDefaultTableCreate(DataTable datatable) throws Exception {
+        return dbUtil.getTemplate().update("TiberoDAO.datasetDefaultTableCreate", datatable);
+    }
+
+    @Override
+    public void datasetDataUpdate(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().update("TiberoDAO.datasetDataUpdate", datatable);
+    }
+
+    @Override
+    public void datasetDataDelete(DataTable datatable) throws Exception {
+        dbUtil.getTemplate().delete("TiberoDAO.datasetDataDelete", datatable);
+    }
+
+    @Override
+    public int duplicateCheckTableName(Map info) throws Exception {
+        return dbUtil.getTemplate().selectOne("TiberoDAO.duplicateCheckTableName", info);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("TiberoDAO.getRowData", dataTable);
+    }
+
+    @Override
+    public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectList("TiberoDAO.getRowDataAll", dataTable);
+    }
+
+    @Override
+    public int getRowDataTotalRows(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().selectOne("TiberoDAO.getRowDataTotalRows", dataTable);
+    }
+
+    @Override
+    public int emptyDataset(DataTable dataTable) throws Exception {
+        return dbUtil.getTemplate().delete("TiberoDAO.emptyDataset", dataTable);
+    }
+
+    @Override
+    public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("TiberoDAO.tableColumnChange", tableBasicInfo);
+    }
+
+    @Override
+    public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("TiberoDAO.changePromaryKey", tableBasicInfo);
+    }
+
+    @Override
+    public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception {
+        return dbUtil.getTemplate().update("TiberoDAO.createAutoIncrement", tableBasicInfo);
+    }
+
+    @Override
+    public void updateTableMetaInfo(DataTable dataTable) throws Exception {
+        dbUtil.getTemplate().update("TiberoDAO.updateTableMetaInfo", dataTable);
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionConfig.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionConfig.java
@@ -0,0 +1,180 @@
+package com.takensoft.taken_bi_manager.common.connection.db.util;
+
+import java.sql.SQLException;
+
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType;
+import com.zaxxer.hikari.HikariDataSource;
+
+/**
+ * @author 김성원
+ * @since 2024.01.02
+ * 
+ * 동적 데이터 베이스 연계 관리 클래스 입니다.
+ */
+public class DBConnectionConfig {
+	
+	//프로젝트 내부 Class Path 정보
+	// 한개 logger.debug(pathMatchingResourcePatternResolver.getResource("절대경로 혹은 classpath:이하경로").getFile().getAbsolutePath()); 
+	// 여러개 Resource[] resource = pathMatchingResourcePatternResolver.getResources("절대경로 혹은 classpath:이하경로");
+	private final static PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
+	
+	//동적 Mybatis 연계 - mybatis 설정 정보 파일 경로
+	private final static String DYNAMIC_MYBATIS_CONFIG = "spring/mapper/mybatis-config.xml";
+	
+	//동적 Mybatis 연계 - mybatis Mapper 문서 파일 경로 
+	private final static String DYNAMIC_MYBATIS_MAPPERS = "spring/mapper/sql/*-SQL.xml";
+	
+	private HikariDataSource dataSource = null;
+	
+	private SqlSessionFactoryBean sqlSession = null;
+	
+	private SqlSessionTemplate template = null;
+	
+	private DataSourceTransactionManager dataSourceTransaction = null;
+	
+	public HikariDataSource getDataSource() {
+		return dataSource;
+	}
+
+	public void setDataSource(HikariDataSource dataSource) {
+		this.dataSource = dataSource;
+	}
+
+	public SqlSessionFactoryBean getSqlSession() {
+		return sqlSession;
+	}
+
+	public void setSqlSession(SqlSessionFactoryBean sqlSession) {
+		this.sqlSession = sqlSession;
+	}
+
+	public SqlSessionTemplate getTemplate() {
+		return template;
+	}
+
+	public void setTemplate(SqlSessionTemplate template) {
+		this.template = template;
+	}
+
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.08
+	 * 
+	 * 동적 DB + Mybatis 객체 생성 -> Mapper에 접근하기위한 SQL 템플릿 반환
+	 */
+	public SqlSessionTemplate mybatisSqlTemplateCreate (ConnectionDB db) {
+		dataSource = dataSourceCreate(db);
+		sqlSession = sqlSessionCreate(dataSource);
+		template = sqlSessionTemplateCreate(sqlSession);		
+		dataSourceTransaction = getTransaction(dataSource);
+		
+		return template;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.08
+	 * 
+	 * 동적 DataSource 생성
+	 */
+	public HikariDataSource dataSourceCreate (ConnectionDB db) {
+		dataSource = null;
+		try {
+			dataSource = new HikariDataSource();
+			DatabaseType dataBaseType = db.getDatabaseType();
+			dataSource.setDriverClassName(dataBaseType.getDriverClassName());
+			dataSource.setJdbcUrl(dataBaseType.getUrl(db));
+			
+			dataSource.setUsername(db.getUserId());
+			dataSource.setPassword(db.getUserPassword());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		return dataSource;
+	}
+	
+	/**
+	  * @author 김성원
+	 * @since 2024.01.08
+	 * 
+	 * 동적으로 생성한 DataSource정보와 Mybatis 설정 정보 연계 생성
+	 */
+	private SqlSessionFactoryBean sqlSessionCreate (HikariDataSource dataSource) {
+		try {
+			sqlSession = new SqlSessionFactoryBean();
+			sqlSession.setDataSource(dataSource);
+			sqlSession.setConfigLocation(resourceResolver.getResource(DYNAMIC_MYBATIS_CONFIG));
+			sqlSession.setMapperLocations(resourceResolver.getResources(DYNAMIC_MYBATIS_MAPPERS));
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		return sqlSession;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.08
+	 * 
+	 * 동적 Mybatis Mapper에 접근하기위한 SQL 템플릿 생성
+	 */
+	private SqlSessionTemplate sqlSessionTemplateCreate (SqlSessionFactoryBean sqlSession) {
+		try {
+			template = new SqlSessionTemplate(sqlSession.getObject());
+			template.clearCache();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		return template;
+	}
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.08
+	 * 
+	 * 동적 Mybatis Mapper에 접근하기위한 SQL 템플릿 생성
+	 */
+	private DataSourceTransactionManager getTransaction (HikariDataSource dataSource) {
+		
+		this.dataSourceTransaction = new DataSourceTransactionManager(dataSource);
+	
+		return dataSourceTransaction;
+	}	
+	
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.08
+	 * 
+	 * 커넥션 닫기
+	 */
+	public void close() throws SQLException {
+		try {
+			if (dataSource != null) {
+				dataSource.evictConnection(dataSource.getConnection());
+				if (dataSource.getConnection() != null) {
+					dataSource.getConnection().close();
+				}
+				dataSource.close();
+			}
+		}catch(Exception e) {
+			if (dataSource != null) {
+				dataSource.close();
+			}
+		}
+		
+	}
+	
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionUtil.java
@@ -0,0 +1,762 @@
+package com.takensoft.taken_bi_manager.common.connection.db.util;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.takensoft.taken_bi_manager.common.connection.db.dao.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.common.vo.CheckMessage;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+
+
+
+/**
+ * @author 최정우
+ * @since 2019.11.12
+ * 
+ * 데이터 수집 - DB 데이터 연계 관련 Util 입니다. 
+ */
+@Transactional
+public class DBConnectionUtil {
+	
+	private Logger logger = LoggerFactory.getLogger(DBConnectionUtil.class);
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * 데이터베이스 접속 모듈 DAO 객체 생성 메서드입니다.
+	 */
+	public DatabaseDAO createDatabaseDAO (ConnectionDB db) throws Exception {
+		
+		DatabaseDAO databaseDao= null;
+		
+		if (db.getDatabaseType() == DatabaseType.MYSQL) {
+			databaseDao =  new MysqlDAO(db);
+		} else if (db.getDatabaseType() == DatabaseType.MARIADB) {
+			databaseDao =  new MariadbDAO(db);
+		} else if (db.getDatabaseType() == DatabaseType.ORACLE) {
+			databaseDao =  new OracleDAO(db);
+		} else if (db.getDatabaseType() == DatabaseType.MSSQL) {
+			databaseDao =  new MssqlDAO(db);
+		} else if (db.getDatabaseType() == DatabaseType.TIBERO) {
+		// databaseDao =  new TiberoDAO(db);
+		}else if (db.getDatabaseType() == DatabaseType.POSTGRESQL) {
+		 	return new PostgresqlDAO(db);
+		} else {
+			throw new Exception();
+		}
+		return databaseDao;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * DB 접속 테스트 입니다.
+	 */
+	public CheckMessage dbConnectionCheck (ConnectionDB dbCollection) throws Exception {
+		if(StringUtil.isEmpty(dbCollection.getConectIp()) == true) {
+			return new CheckMessage(false, "접속 IP를 입력해주세요");
+		} else if(StringUtil.isEmpty(dbCollection.getConectPort()) == true) {
+			return new CheckMessage(false, "접속 Port를 입력해주세요");
+		} else if(CommonUtil.isInt(dbCollection.getConectPort()) == false) {
+			return new CheckMessage(false, "접속 Port는 숫자로만 입력해주세요");
+		} else if(StringUtil.isEmpty(dbCollection.getDatabaseNm()) == true) {
+			return new CheckMessage(false, "DB명을 입력해주세요");
+		} else if(StringUtil.isEmpty(dbCollection.getConectIp()) == true) {
+			return new CheckMessage(false, "접속 ID를 입력해주세요.");
+		} else if(StringUtil.isEmpty(dbCollection.getUserPassword()) == true) {
+			return new CheckMessage(false, "접속 PW를 입력해주세요.");
+		} else {
+			/*if (CommonUtil.pingCheck(dbCollection.getIp()) == false) {
+				return new CheckMessage(false, "접속 IP(" + dbCollection.getIp() + ")와 연결할 수 없습니다");
+			}*/
+			if (CommonUtil.linkCheck(dbCollection.getConectIp(), Integer.parseInt(dbCollection.getConectPort())) == false) {
+				return new CheckMessage(false, "접속 IP(" + dbCollection.getConectIp() + ")의 Port(" + dbCollection.getConectPort() + ")와 연결할 수 없습니다");
+			} 
+			Connection connection = null;
+			DBConnectionConfig dbUtil = new DBConnectionConfig();
+			try {
+				dbUtil.dataSourceCreate(dbCollection);
+				connection = dbUtil.getDataSource().getConnection();
+				return new CheckMessage(true, "[" + dbCollection.getDatabaseType().getValue() + "] " + dbCollection.getDatabaseNm() + " 접속 성공");
+			} catch (SQLException e) {
+
+				return new CheckMessage(false, "접속 에러 : " + e.toString());
+			} catch (Exception e) {
+
+				return new CheckMessage(false, "접속 에러 : " + e.toString());
+			} finally {
+				if (connection != null) {
+					try {
+						connection.close();
+					} catch (Exception e) {
+
+						return new CheckMessage(false, "접속 에러 : " + e.toString());
+					}
+				} if (dbUtil != null) {
+					dbUtil.close();
+				}
+			}
+		}
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * DB 접속 - 테이블 목록 조회 메소드 입니다.
+	 */
+	public List<Dataset> getDBConnectionTableList (ConnectionDB dbCollection , CheckMessage message) throws Exception {
+		message = dbConnectionCheck(dbCollection);
+
+		if (message.isSuccess() == false) {
+			logger.info("getDbConnectionTableList DB연결실패 : " + message.getMessage());
+			return new ArrayList<Dataset>();
+		}
+		
+		List<Dataset> dbConnectionTableList = new ArrayList<Dataset>();
+		
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		try {
+			//테이블 목록 조회
+			 dbConnectionTableList = databaseDAO.getDBConnectionTableList(dbCollection);
+		}catch (Exception e){
+			message.setError(e.toString());
+		}
+		finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();	
+		}
+
+		return dbConnectionTableList;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등)
+	 */
+	public List<ColumnData> getDBConnectionTableColumnList(ConnectionDB dbCollection, Dataset dataset) throws Exception {
+		CheckMessage message = dbConnectionCheck(dbCollection);
+		
+		if (message.isSuccess() == false) {
+			logger.info("getDBConnectionTableColumnList DB연결실패 : " + message.getMessage());
+			return new ArrayList<ColumnData>();
+		}
+		
+		List<ColumnData> tableColumnList = new ArrayList<ColumnData>();
+		
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		try {
+			//테이블 컬럼 목록 조회
+			tableColumnList = databaseDAO.getDBConnectionTableColumnList(dataset);
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();	
+		}
+		
+		return tableColumnList;
+	}
+	
+	/**
+	 * @author 최정우
+	 * @since 2020.01.28
+	 * 
+	 * 커넥션된 데이터베이스의 테이블의 데이터에 대한 데이터 테이블 조회 메서드입니다.
+	 */
+	public void setDataTableByDBConnectionTable (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+		CheckMessage message = dbConnectionCheck(dbCollection);
+		
+		if (message.isSuccess() == false) {
+			dataTable.setCheckMessage(message);
+			logger.info("setDataTableByDBConnectionTable DB연결실패 : " + message.getMessage());
+			return;
+		}
+		
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		dataTable.setIsUsePaging(true);
+		
+		int tableDataTotalRows = 0;
+		
+		List<LinkedHashMap<String, Object>> tableDataMapList  = new ArrayList<LinkedHashMap<String, Object>>();
+		
+		try {
+			
+			//테이블 기본 Select 정보(데이터베이스명, 테이블명) 입력
+			Dataset dataset = new Dataset();
+
+			if (dbCollection.getDatabaseType() == DatabaseType.ORACLE) {
+				dataset.setDatabaseNm(dbCollection.getUserId());
+			} else {
+				dataset.setDatabaseNm(dbCollection.getDatabaseNm());
+			}
+			dataset.setTableNm(dataTable.getTableNm());
+
+
+			//테이블 컬럼 목록 조회
+			dataTable.setColumnDatas(databaseDAO.getDBConnectionTableColumnList(dataset));//테이블 컬럼 정보 set
+			dataTable.setColumnDatas( DataTypeUtil.convertDataTypeDbtoJavaList(dataTable.getColumnDatas(),dbCollection.getDatabaseType()));
+
+			//테이블 데이터 조회
+			if (dbCollection.getDatabaseType() == DatabaseType.ORACLE) {
+				dataTable.setDatabaseNm(dbCollection.getUserId());
+			}
+
+			tableDataMapList = databaseDAO.getDBConnectionTableDataList(dataTable);
+			dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList));//테이블 데이터 set
+
+			//테이블 데이터 총 개수 조회
+			tableDataTotalRows = databaseDAO.getDBConnectionTableDataTotalRows(dataTable);
+			dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set
+			
+			//SELECT 쿼리 생성
+			if (dbCollection.getDatabaseType() == DatabaseType.MSSQL) {
+				dataTable.makeQuery();
+			} else {
+				dataTable.setQuery();
+			}
+		}catch(Exception e) {
+			
+			logger.error(e.toString());
+			
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+				
+		//성공 메세지 입력
+		dataTable.getCheckMessage().setSuccess(true);
+		dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)");
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * 커스텀 쿼리를 통한 dataTable setting (페이징사용 유무에 따라 페이징 처리 - {rowDatas, columnDatas, query(이미 존재함)})
+	 */
+	public void setDataTableByDBConnectionCustomQuery (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+		CheckMessage message = dbConnectionCheck(dbCollection);
+		
+		if (message.isSuccess() == false) {
+			dataTable.setCheckMessage(message);
+			logger.info("setDataTableByDBConnectionCustomQuery DB연결실패 : " + message.getMessage());
+			return;
+		}
+		
+		int tableDataTotalRows = 0;
+		
+		List<LinkedHashMap<String, Object>> tableDataMapList  = new ArrayList<LinkedHashMap<String, Object>>();
+		
+		
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		try {
+			//테이블 데이터 조회
+			tableDataMapList = databaseDAO.getDBConnectionCustomQueryDataList(dataTable);
+			
+			//DataTable에 조회된 데이터에서 첫번째 행 값의 컬럼 분리 후, columnDatas에 세팅
+			//DataTable에 rowData 세팅
+			if (tableDataMapList != null && tableDataMapList.size() > 0) {				
+				
+				//테이블 데이터 set
+				dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList));
+				
+				//컬럼명 set
+				List<ColumnData> columnDatas = new ArrayList<ColumnData>();
+				LinkedHashMap<String, Object> map = tableDataMapList.get(0);
+				
+				for(String key : map.keySet()){					
+					ColumnData column = new ColumnData();
+					column.setColumnNm(key);
+					column.setDisplyColumnNm(key);
+					column.setOrginlColumnNm(key);				
+					// 데이터 타입 정의 기능 
+					column.dataTyDefine(map.get(key));					
+					columnDatas.add(column);	
+				}
+				
+				dataTable.setColumnDatas(columnDatas);				
+			}
+			
+			//테이블 데이터 총 개수 조회
+			tableDataTotalRows = databaseDAO.getDBConnectionCustomQueryDataTotalRows(dataTable);
+			dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set
+			//성공 메세지 입력
+			dataTable.getCheckMessage().setSuccess(true);
+			dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)");
+		}catch(Exception e) {
+			logger.error(e.toString());
+			dataTable.getCheckMessage().setError(e.toString());
+			throw new Exception(e);
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+		//DB연결 종료
+		databaseDAO.dbConnectionClose();
+		
+
+	}
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * 조회내용이 없는 실행형 커스텀 쿼리(update, delete 등)
+	 */
+	public int executeCustomQuery(ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+		
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		int result = 0;
+		try {
+			result = databaseDAO.executeCustomQuery(dataTable);
+		}catch(Exception e) {
+			
+		}finally{
+			databaseDAO.dbConnectionClose();	
+		}
+		
+		return result;
+	}
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * 커스텀 쿼리 지정된 PK로 테이블 생성이 가능한지 확인
+	 */
+	public void setCustomQueryPrimaryCreatePossibleCheck (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+		
+		if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) {
+			dataTable.getCheckMessage().setSuccess(false);
+			dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 테이블을 생성할 컬럼이 없습니다.");
+			return;
+		}
+		
+		String primaryColumns = "";
+		List<ColumnData> primaryColumnDatas = new ArrayList<ColumnData>();
+		
+		for (int i = 0; i < dataTable.getColumnDatas().size(); i++) {
+			if (dataTable.getColumnDatas().get(i).isPkAt() == true) {
+				primaryColumns += ("[" + dataTable.getColumnDatas().get(i).getColumnNm() + "]");
+				primaryColumnDatas.add(dataTable.getColumnDatas().get(i));
+			}
+		}
+		
+		if (primaryColumnDatas.size() == 0) {
+			dataTable.getCheckMessage().setSuccess(true);
+			dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - PK로 지정한 컬럼이 없습니다.(검사통과)");
+			return;
+		}
+		
+		//DB Connecting
+		CheckMessage message = dbConnectionCheck(dbCollection);
+		if (message.isSuccess() == false) {
+			dataTable.setCheckMessage(message);
+			logger.info("setDataTableByDBConnectionCustomQuery DB연결실패 : " + message.getMessage());
+			return;
+		}
+		
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		DataTable param = new DataTable();
+		param.setColumnDatas(primaryColumnDatas);
+		param.setQuery(dataTable.getQuery());
+		
+		//커스텀 쿼리 지정된 PK로 테이블 생성이 가능한지 확인
+		int totalOverlapCount = databaseDAO.getCustomQueryPrimaryOverlapCount(param);
+		
+		//DB연결 종료
+		databaseDAO.dbConnectionClose();
+		
+		//결과 메세지 입력
+		if (totalOverlapCount == 0) {
+			dataTable.getCheckMessage().setSuccess(true);
+			dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 지정한 컬럼(" + primaryColumns + ")으로 PrimaryKey 생성이 가능합니다.");
+		} else {
+			dataTable.getCheckMessage().setSuccess(false);
+			dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 지정한 컬럼(" + primaryColumns + ")으로 PrimaryKey 생성이 불가능합니다.(중복되는 데이터 수 :" + totalOverlapCount + ")");
+		}		
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * 커넥션된 데이터베이스의 테이블의 데이터에 대한 데이터 테이블 조회 메서드입니다.
+	 */
+	public void setDataTableByDBCollectionQuery (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+		if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) {
+			dataTable.getCheckMessage().setMessage("조회할 컬럼정보가 없습니다.");
+			dataTable.getCheckMessage().setSuccess(false);
+			logger.info("setDataTableByDBConnectionTable : " + dataTable.getCheckMessage().getMessage());
+			return;
+		}
+		
+		//DB연결 확인
+		CheckMessage message = dbConnectionCheck(dbCollection);
+		if (message.isSuccess() == false) {
+			dataTable.setCheckMessage(message);
+			logger.info("setDataTableByDBConnectionTable DB연결실패 : " + message.getMessage());
+			return;
+		}
+		
+		int tableDataTotalRows = 0;
+		
+		List<LinkedHashMap<String, Object>> tableDataMapList  = new ArrayList<LinkedHashMap<String, Object>>();
+		
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		try {
+			tableDataMapList = databaseDAO.getDBCollectionQueryDataList(dataTable);
+			dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList));//테이블 데이터 set
+			
+			//테이블 데이터 총 개수 조회
+			tableDataTotalRows = databaseDAO.getDBCollectionQueryDataTotalRows(dataTable);
+			dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set
+		}catch(Exception e) {
+			
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+		
+		
+		//성공 메세지 입력
+		dataTable.getCheckMessage().setSuccess(true);
+		dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)");
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.04
+	 * 
+	 * 데이터 셋 목록 Convert List<TableBasicInfo> to List<ColumnData>
+	 */
+	/*
+	public List<ColumnData> tableColumnToColumnData (List<TableBasicInfo> tableBasicList) throws Exception {
+		List<ColumnData> columnDataList = new ArrayList<ColumnData>();
+		for (int i = 0; i < tableBasicList.size(); i++) {
+			TableBasicInfo tableBasicInfo = tableBasicList.get(i);
+			ColumnData columnData = new ColumnData();
+		    columnData.setTableName(tableBasicInfo.getTableName());
+		    columnData.setColumnNm(tableBasicInfo.getColumnName());
+		    columnData.setOrginlColumnNm(tableBasicInfo.getColumnName());
+		    columnData.setDisplyColumnNm(tableBasicInfo.getColumnName());
+		    columnData.setDbDataType(tableBasicInfo.getDataType());
+		    columnData.setDataSize(tableBasicInfo.getSize());
+		    columnData.setPkAt(tableBasicInfo.isPrimary());
+		    
+			columnDataList.add(columnData);
+		}
+		return columnDataList;
+	}
+	*/
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 커넥션된 데이터베이스의 실제 테이블 생성
+	 */
+	public int datasetTableCreate(ConnectionDB dbCollection, DataTable datatable) throws Exception {
+			
+		int result = 0;
+
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		try {
+			//테이블 컬럼 목록 조회
+			result = databaseDAO.datasetTableCreate(datatable);
+		}catch (Exception e){
+			e.toString();
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();		
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 커넥션된 데이터베이스의 실제 테이블 생성
+	 */
+	public int datasetDefaultTableCreate(ConnectionDB dbCollection, DataTable datatable) throws Exception {
+			
+		int result = 0;
+				
+		//DAO 인스턴스 생성		
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		try {
+		//테이블 컬럼 목록 조회
+			result = databaseDAO.datasetDefaultTableCreate(datatable);
+		}catch(Exception e) {
+
+			e.printStackTrace();
+
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+
+		return result;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 *
+	 * 커넥션된 데이터베이스의 실제 테이블 업데이트
+	 */
+	public void datasetDataUpdate(ConnectionDB dbCollection, DataTable datatable) throws Exception {
+
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		//datatable.getColumnDatas().get(0).isAutoIncrement();
+		try {
+			//테이블 컬럼 목록 조회
+			databaseDAO.datasetDataUpdate(datatable);
+		}catch(Exception e) {
+			e.printStackTrace();
+			throw new Exception(e);
+		}
+		finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 *
+	 * 커넥션된 데이터베이스의 실제 테이블 이름 중복검사
+	 */
+	public int duplicateCheckTableName(ConnectionDB dbCollection, Map info) throws Exception {
+
+
+		int result = 0;
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		try {
+			//테이블 컬럼 목록 조회
+			result = databaseDAO.duplicateCheckTableName(info);
+		}catch (Exception e){
+			e.toString();
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+
+		return result;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 *
+	 * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징)
+	 */
+	public List<LinkedHashMap<String, Object>> getRowData (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+
+		List<LinkedHashMap<String, Object>> rowMapData = new ArrayList<LinkedHashMap<String, Object>>();
+
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		try {
+			//테이블 컬럼 목록 조회
+			rowMapData = databaseDAO.getRowData(dataTable);
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+
+		return rowMapData;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 *
+	 * 데이터 셋의 컬럼 정보 목록 조회 메소드 입니다.(페이징X)
+	 */
+	public List<LinkedHashMap<String, Object>> getRowDataAll (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+
+		List<LinkedHashMap<String, Object>> rowMapData = new ArrayList<LinkedHashMap<String, Object>>();
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+
+		try {
+			//테이블 컬럼 목록 조회
+			rowMapData = databaseDAO.getRowDataAll(dataTable);
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+
+		return rowMapData;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 *
+	 * 데이터 셋의 컬럼 정보 목록 총 갯수 조회 메소드 입니다.
+	 */
+	public int getRowDataTotalRows (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+
+		int result = 0;
+
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+
+		try {
+		//테이블 컬럼 목록 조회
+			result = databaseDAO.getRowDataTotalRows(dataTable);
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+
+		return result;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 *
+	 * 데이터 셋의 비우기 (데이터 셋 내용삭제)
+	 */
+	public int emptyDataset (ConnectionDB dbCollection, DataTable dataTable) throws Exception {
+
+		int result = 0;
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+
+		try {
+		//테이블 컬럼 목록 조회
+			result = databaseDAO.emptyDataset(dataTable);
+		}finally {
+			//DB연결 종료
+			databaseDAO.dbConnectionClose();
+		}
+
+		return result;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 *
+	 *  실제 생성된 컬럼 변경
+	 */
+	public int tableColumnChange (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception {
+
+		int result = 0;
+
+		//테이블 컬럼 목록 조회
+		result = databaseDAO.tableColumnChange(tableBasicInfo);
+
+		return result;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 *  실제 생성된 테이블 키변경
+	 */
+	public int changePromaryKey (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception {
+		
+		int result = 0;				
+		
+		//테이블 컬럼 목록 조회
+		result = databaseDAO.changePrimaryKey(tableBasicInfo);		
+	
+		return result;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 * 데이터 셋의 ROW 삭제
+	 */
+	public void datasetDataDelete (ConnectionDB dbCollection, DataTable dataTable) throws Exception {		
+	
+		//DAO 인스턴스 생성
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		//테이블 컬럼 목록 조회
+	    databaseDAO.datasetDataDelete(dataTable);
+		
+		//DB연결 종료
+		databaseDAO.dbConnectionClose();				
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 *   AI PK 생성 
+	 */
+	public int createAutoIncrement (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception {
+		
+		int result = 0;				
+		
+		//테이블 컬럼 목록 조회
+		result = databaseDAO.createAutoIncrement(tableBasicInfo);		
+	
+		return result;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2022.01.17
+	 * 
+	 *   테이블 메타정보 변경 (comments)
+	 */
+	public void updateTableMetaInfo(ConnectionDB dbCollection,DataTable dataTable) throws Exception {
+		
+		DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection);
+		
+		databaseDAO.updateTableMetaInfo(dataTable);
+		
+	}
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DataTypeUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DataTypeUtil.java
@@ -0,0 +1,375 @@
+package com.takensoft.taken_bi_manager.common.connection.db.util;
+
+import java.util.*;
+
+import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.ColumnValue;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+
+/**
+ * @author 김성원
+ * @since 2024.01.02
+ * 
+ * 데이터 타입별로 DB -> JAVA ,  JAVA -> DB 변경을 위한 인터페이스 입니다.
+ */
+public class DataTypeUtil {
+
+
+	public final static String COLUMN_NAME = "col";
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 데이터베이스 자료타입을 자바형태로 변환
+	 */
+	public static DataType convertDataTypeDbtoJava (ColumnData column, DatabaseType databaseType ) {
+    	
+		 DataType dataType = null;
+		 
+		if(databaseType.equals(DatabaseType.MARIADB) || databaseType.equals(DatabaseType.MYSQL)){
+			dataType = mariadbDataConvertDBtoJava(column);
+		}else {
+			dataType = postgresqlDbDataConvertDBtoJava(column);
+		}
+    	
+    	return dataType;	    	
+    }
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 *
+	 * 자바 자료형태를 DB 타입으로 변환 
+	 */
+	public static DataType convertDataTypeJavatoDB (ColumnData column, DatabaseType databaseType ) {
+    	
+    	
+    	return null;	    	
+    }
+	
+	public static List<ColumnData> convertDataTypeDbtoJavaList(List<ColumnData> ColumnDatas , DatabaseType databaseType){
+		
+		for(ColumnData item : ColumnDatas) {
+			item.setDataTy(convertDataTypeDbtoJava(item,databaseType));
+		}
+		
+		
+		return ColumnDatas;		
+	}
+
+
+	// 데이터 테이블 컬럼 DB 자료형으로 변환
+	public static void convertDataTableColumMeta(DataTable dataTable) throws Exception {
+		//데이터가 없을 때 return
+		if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) {
+			dataTable.getCheckMessage().setSuccess(false);
+			dataTable.getCheckMessage().setMessage("컬럼 정보가 없습니다.");
+			return;
+		} else {
+
+			try {
+				//한 행의 총 varchar size
+				int varcharTotalSize = 0;
+
+
+				// 맥스 사이즈 정하겠음
+				//컬럼 정보 세팅 (시작)
+				for (int cellIndex = 0; cellIndex < dataTable.getColumnDatas().size(); cellIndex++) {
+
+					int maxLength = 50;
+
+					//원본 컬럼명
+					String originColumnName = dataTable.getColumnDatas().get(cellIndex).getOrginlColumnNm();
+
+					//DB에 생성될 컬럼명 set
+					if (StringUtil.isEmpty(dataTable.getColumnDatas().get(cellIndex).getColumnNm()) == true) {
+						dataTable.getColumnDatas().get(cellIndex).setColumnNm(COLUMN_NAME + cellIndex);
+					}
+
+					//컬럼 Index set
+					dataTable.getColumnDatas().get(cellIndex).setOrdr(cellIndex);
+
+
+					dataTable.getColumnDatas().get(cellIndex).setDisplyColumnNm(originColumnName);
+
+
+					//열(컬럼)의 데이터 타입 (컬럼의 열 데이터가 없을 때, STRING 타입)
+					DataType dataType = dataTable.getColumnDatas().get(cellIndex).getDataTy();
+
+					//컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정)
+					Set<DataType> datatypes = new HashSet<DataType>();
+
+					//각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+
+					List<ColumnValue> columnValues = new ArrayList<ColumnValue>();
+					for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+
+						//cellIndex열 중 rowIndex행 값-value
+						//String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString();
+						Object cellValue = dataTable.getRowData().get(rowIndex).get(cellIndex);
+						String value = (cellValue != null) ? cellValue.toString() : null;
+
+						if (!StringUtil.isEmpty(value) && value.length() > maxLength) {
+							maxLength = value.length();
+						}
+
+						/*
+						 * 문자열이 비어있거나
+						 * 문자열이 Null or null or NULL인 경우 실제 null값 세팅
+						 * */
+						if (StringUtil.isEmpty(value) || StringUtil.isNullText(value) == true) {
+							dataTable.getRowData().get(rowIndex).set(cellIndex, null);
+							value = null;
+						}
+
+						//해당 '값'의 '데이터 타입 조회'
+						DataType type = DataType.getDataType(value);
+
+						//Cell 데이터 값 및 타입 세팅
+					/*	if(addData == true) {
+						ColumnValue columnValue = new ColumnValue();
+						columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅
+						columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅 //dataTable에 Cell 데이터 값  및 타입 세팅
+						columnValues.add(columnValue);
+					}*/
+
+
+						//컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력
+						datatypes.add(type);
+
+						if (rowIndex > 100000) {
+
+							if (dataTable.getRowData().size() > 10000 && rowIndex < dataTable.getRowData().size() - 10000) {
+								rowIndex = dataTable.getRowData().size() - 10000;
+							}
+							//	break;
+						}
+					}
+					//각 컬럼 목록 > 컬럼별 데이터 목록 세팅
+					//dataTable.getColumnDatas().get(cellIndex).setColumnValues(columnValues);
+
+					//해당 열(컬럼)의 데이터 타입이 지정되지 않았을 때 -> #읽은 컬럼 데이터를 바탕으로 데이터 타입지정#
+					if (dataType == null) {
+						dataType = getColumnDataType(datatypes);
+						dataTable.getColumnDatas().get(cellIndex).setDataTy(dataType);
+					}
+
+
+
+
+					/*DB데이터 타입 생성*/
+					if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기
+						ColumnValue columnValue = null;
+
+						//해당 열의 문자열 크기
+						int size = maxLength;
+
+						//컬럼의 열 데이터가 존재할 때, 가장 긴 문자열의 글자수 구하기
+						/*
+						 * if (columnValues.size() > 0) { //null값 제외한 목록 만들기 List<ColumnValue>
+						 * noneNullColumnValues = columnValues.stream().filter(s -> s.getValue() !=
+						 * null).collect(Collectors.toList());
+						 *
+						 * if (noneNullColumnValues != null && noneNullColumnValues.size() > 0) { //최대
+						 * 길이 값 구하기 columnValue = noneNullColumnValues.stream().max((s1, s2) ->
+						 * StringUtil.stringLength(s1.getValue()) -
+						 * StringUtil.stringLength(s2.getValue())).get(); //가장 긴 문자열의 글자수 size =
+						 * StringUtil.stringLength(columnValue.getValue()); } }
+						 */
+
+						//테이블 생성시에 필요한 DB데이터 타입으로 Convert
+						String dbDataType = DataType.convertDbDataType(dataType, size);
+
+						//DB데이터 타입 입력
+						dataTable.getColumnDatas().get(cellIndex).setDbDataType(dbDataType);
+						//DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력
+						if (dbDataType.equals("varchar")) {
+
+							dataTable.getColumnDatas().get(cellIndex).setDataSize(size);//데이터 타입 크기 입력
+
+							//varchar 총 사이즈에 추가
+							varcharTotalSize += size;
+						}
+					} else if (dataTable.getColumnDatas().get(cellIndex).getDataTy() == DataType.DATE) {
+
+						//text -> date형식으로 변경
+						for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+							//cellIndex열 중 rowIndex행 값-value
+							//String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString();
+							Object cellValue = dataTable.getRowData().get(rowIndex).get(cellIndex);
+							String value = (cellValue != null) ? cellValue.toString() : null;
+
+							String dateTextValue = CommonUtil.parseDateText(value);
+							dataTable.getRowData().get(rowIndex).set(cellIndex, dateTextValue);
+						}
+
+						dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null));
+						dataTable.getColumnDatas().get(cellIndex).setDataSize(100);
+					}
+//					}  else if (dataTable.getColumnDatas().get(cellIndex).getDataTy() == DataType.TIMESTAMP) {
+//
+//						//text -> date형식으로 변경
+//						for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) {
+//							//cellIndex열 중 rowIndex행 값-value
+//							String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString();
+//							String dateTextValue = CommonUtil.parseDateText(value);
+//							dataTable.getRowData().get(rowIndex).set(cellIndex, dateTextValue);
+//						}
+//
+//						dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null));
+//						dataTable.getColumnDatas().get(cellIndex).setDataSize(100);
+//
+//					}
+					else {//'문자열'도 아니고 '날짜'도아닐 때 => DB데이터 타입 입력
+						dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null));
+						if(maxLength > 20){
+							dataTable.getColumnDatas().get(cellIndex).setDataSize(maxLength);
+						}else{
+							dataTable.getColumnDatas().get(cellIndex).setDataSize(20);
+						}
+
+					}
+
+				}//cell for문 끝
+				dataTable.getCheckMessage().setSuccess(true);
+				dataTable.getCheckMessage().setMessage("컬럼 메타 정보 세팅 완료");
+			}catch (Exception e){
+				throw new Exception(e);
+			}
+		}
+
+	}
+	
+	 
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 마리아 및 myslq 데이터베이스 자료타입을 자바형태로 변환
+	 */
+	 private static DataType mariadbDataConvertDBtoJava(ColumnData column) {
+		 
+		 DataType dataType = null;
+		 
+		 // 스트링 타입 변환 
+		 if(Arrays.asList("TEXT", "VARCHAR", "TINYTEXT", "LONGTEXT","ENUM","SET","CHAR","LONGBLOB","BLOB","TINYBLOB","VARBINARY","BINARY","CHAR").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.STRING;
+		 }
+		 // boolean 타이 변환 
+		 else  if(Arrays.asList("BIT").contains(column.getDbDataType().toLowerCase().trim())) {
+			 dataType = DataType.INT;
+		 }
+		 // Integer 타이 변환 
+		 else  if(Arrays.asList("TINYINT", "SMALLINT").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.INT;
+		 }
+		// Long 타이 변환 
+		 else  if(Arrays.asList("MEDIUMINT", "INT","BIGINT").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.INT;
+		 }
+		 // float 타이 변환 
+		 else  if(Arrays.asList("FLOAT").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.FLOAT;
+		 }
+		 // double 타이 변환 
+		 else  if(Arrays.asList("DOUBLE").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.DOUBLE;
+		 }
+		 // DECIMAL  타이 변환 
+		 else  if(Arrays.asList("DECIMAL").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.DECIMAL;
+		 }
+		 // DATE  타이 변환 
+		 else  if(Arrays.asList("DATE").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.DATE;
+		 } 
+		 // TIMESTAMP  타이 변환 
+		 else  if(Arrays.asList("DATETIME,TIMESTAMP,TIME").contains(column.getDbDataType().toUpperCase().trim())) {
+			 dataType = DataType.TIMESTAMP;
+		 } 		
+		 
+		 return dataType;
+	 }
+	 
+	 /**
+		 * @author 김성원
+		 * @since 2024.01.09
+		 * 
+		 * 마리아 및 myslq 데이터베이스 자료타입을 자바형태로 변환
+		 */
+		 private static DataType postgresqlDbDataConvertDBtoJava(ColumnData column) {
+			 
+			 DataType dataType = null;
+			 
+			 // 스트링 타입 변환 
+			 if(Arrays.asList("character varying", "character","text").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.STRING;
+			 }
+			 // boolean 타이 변환 
+			 else  if(Arrays.asList("bit").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.BOOL;
+			 }
+			 // Integer 타이 변환 
+			 else  if(Arrays.asList("integer","smallint","serial").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.INT;
+			 }
+			 // Long 타이 변환 
+			 else  if(Arrays.asList("bigint", "bigserial").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.LONG;
+			 }			
+			 // float 타이 변환 
+			 else  if(Arrays.asList("real").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.FLOAT;
+			 }
+			 // double 타이 변환 
+			 else  if(Arrays.asList("double precision","numeric").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.DOUBLE;
+			 }			
+			 // DATE  타이 변환 
+			 else  if(Arrays.asList("date","time without time zone").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.DATE;
+			 } 
+			 // TIMESTAMP  타이 변환 
+			 else  if(Arrays.asList("time","timestamp","timestamp with time zone","timestamp without time zone", "time with time zone").contains(column.getDbDataType().toLowerCase().trim())) {
+				 dataType = DataType.TIMESTAMP;
+			 }else {
+				 dataType = DataType.STRING;
+			 }
+			 return dataType;
+		 }
+
+	/**
+	 * @author 최정우
+	 * @since 2019.11.27
+	 *
+	 * column의 데이터 타입 지정
+	 */
+	public static DataType getColumnDataType (Set<DataType> datatypes) throws Exception {
+		if (datatypes.contains(DataType.STRING)) {
+			return DataType.STRING;
+		} else if (datatypes.contains(DataType.DATE)) {
+			if (datatypes.contains(DataType.DOUBLE) || datatypes.contains(DataType.LONG)) {
+				return DataType.STRING;
+			} else {
+				return DataType.DATE;
+			}
+		} else if (datatypes.contains(DataType.DOUBLE)) {
+			return DataType.DOUBLE;
+		} else if (datatypes.contains(DataType.LONG)) {
+			return DataType.LONG;
+		} else {
+			return DataType.STRING;
+		}
+	}
+
+
+
+
+
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/ConnectionDB.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/ConnectionDB.java
@@ -0,0 +1,102 @@
+package com.takensoft.taken_bi_manager.common.connection.db.vo;
+
+
+
+
+import com.takensoft.taken_bi_manager.common.util.CryptoUtil;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Getter
+@Setter
+public class ConnectionDB {
+
+	// 커넥션 이름
+	private String dbConectId;
+		
+	// 커넥션 이름
+	private String conectNm;
+	
+	// 커넥션 설명
+	private String conectDc;
+	
+	// 데이터베이스명(데이터 베이스 > 스키마) 
+	private String databaseNm;
+	
+	// 스키마명
+	private String schemaNm;
+	
+	// 데이터 베이스 타입	
+	private DatabaseType databaseType;
+	
+	// IP or URL
+	private String conectIp;
+	
+	// 접속 포트 
+	private String conectPort;
+	
+	// 접속 아이디
+	private String userId;
+	
+	// 접속 비밀번호
+	private String userPassword;
+	
+	// 접속 옵션 
+	private String option;
+	
+	// 공통 사용여부
+	private boolean useType = true;
+		
+	// 사용여부
+	private boolean useAt = true;
+
+	// 불러오기 여부
+	private boolean loadAt = false;
+
+
+	//추가 dataset_post_id
+	private String dataset_post_id;
+		
+	
+	/**
+	 * 오라클
+	 * 	SERVICE: true 
+	 *  SID: false
+	 *  인지 아닌지
+	 */
+	private boolean isGroupDatabase = false;	
+	
+	// 생성일
+	private String creatDt;
+	
+	// 생성자ID
+	private String creatId;
+	
+	// 수정일 
+	private String updtDt;
+		
+	// 수정자 ID
+	private String updtId;
+
+	private String query;
+
+	private boolean execution;
+	
+	// 단방향 암호화 진행 
+	public void encodingData() {		
+		this.userPassword = CryptoUtil.encryptData(this.userPassword);				
+	}
+	
+	// 단방향 복호화 진행 
+	public void decodingData() {		
+		this.userPassword = CryptoUtil.decryptData(this.userPassword);				
+	}
+	
+	
+	
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/DataType.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/DataType.java
@@ -0,0 +1,281 @@
+package com.takensoft.taken_bi_manager.common.connection.db.vo;
+
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+
+/**
+ * @author 김성원
+ * @since 2024.01.02
+ * 
+ * 데이터 타입을 정의한 상수 Class 입니다.
+ * 상수명(java데이터타입, 초기값, mysql데이터타입, display데이터타입
+ */
+
+public enum DataType {
+	NULL(null, null)
+	, BYTE(Byte.class, 0)
+	, BOOL(Boolean.class, false)
+	, CHAR(Character.class, '\u0000')
+	, STRING(String.class, "")
+	, SHORT(Short.class, 0)
+	, INT(Integer.class, 0)
+	, DECIMAL(BigDecimal.class,0)
+	, LONG(Long.class, 0)
+	, FLOAT(Float.class, 0.0)
+	, DOUBLE(Double.class, 0.0)
+	, DATE(Date.class, "")
+	, DATETIME(Date.class, "")
+	, TIMESTAMP(Timestamp.class, "")
+	, ENTER(Character.class,'\n');
+
+	/**
+	 * enum(열거형데이터)의 생성자 
+	 * 1. 상수에 나열된 parameter와 형태가 똑같이 만들어줘야함.
+	 * 2. 접근제한자는 private로만 다른 접근제한자는 허용하지 않음
+	 */
+	private DataType (Class<?> javaType, Object iniValue) {
+        this.javaType = javaType;
+        this.initValue = iniValue;
+    }
+	
+	/**
+	 * java데이터타입
+	 */
+	final private Class<?> javaType;
+	
+	/**
+	 * 초기값
+	 */
+	final private Object initValue;
+	
+    public Class<?> getJavaType() {
+        return javaType;
+    }
+    public Object getInitValue() {
+        return initValue;
+    }
+    	 
+    
+    /**
+	 * 데이터 타입 검사, DataType 조회
+	 */
+    public static Map<DataType, String> getDataTypeList () {
+    	Map<DataType, String> info = new LinkedHashMap<DataType, String>();
+    	info.put(STRING, "문자열");
+    	info.put(LONG, "정수");
+    	info.put(DOUBLE, "실수");
+    	info.put(DATE, "날짜");
+    	info.put(DATETIME,"날짜,시간");
+    	return info;
+	}
+
+	/**
+	 * 숫자형 타입 여부 검사
+	 */
+	public static boolean checkTypeNumber (DataType type) {
+		boolean result = false;
+
+		if(type.equals(INT) || type.equals(LONG) || type.equals(DOUBLE) || type.equals(FLOAT)){
+			result  = true;
+		}
+		return result;
+	}
+    
+    
+    /**
+	 * 데이터 타입 검사, DataType 조회
+	 */
+    public static List<DataType> getDataTypeArray () {
+    	List<DataType> info = new ArrayList<DataType>();
+    	info.add(STRING);
+    	info.add(LONG);
+    	info.add(DOUBLE);
+    	info.add(DATE);
+    	info.add(DATETIME);
+    	info.add(BOOL);
+    	return info;
+	}
+    
+    /**
+	 * 데이터 타입 검사, DataType 조회
+	 */
+    public static DataType getDataType (String text) {
+    	/*
+    	 * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정
+    	 * 
+    	 * 
+    	 * 전화번호 정규식*/
+    	String regExp = "^\\d{2,3}-\\d{3,4}-\\d{4}$";
+    	String regDateTime = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) (0[1-9]|1[0-9]|2[0-4]):(0[1-9]|[1-5][0-9]):(0[1-9]|[1-5][0-9])";
+    	String regDate = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])";
+    			
+		if(StringUtil.isEmpty(text)) {
+			return NULL;
+		} else if(CommonUtil.isLong(text)) {
+			/*
+			 * 숫자로 변환 가능 하지만 앞에 '0'이 붙어 있으면 문자열로 봄
+			 * ex) 0102 -> String, 1102 -> Long
+			 */
+			if (text.length() > 1 && text.indexOf("0") == 0) {
+				return STRING;
+			} else {
+				return LONG;
+			}
+		}else if(CommonUtil.isDouble(text)) {
+			
+			return DOUBLE;
+			
+		} else if (CommonUtil.isDate(text)) {
+			/*
+	    	 * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정
+	    	 * 
+	    	 * 
+	    	 * 전화번호 정규식*/
+	    	boolean expResult = Pattern.matches(regExp, text);
+	    	boolean dateTimeResult = Pattern.matches(regDateTime, text);
+	    	boolean dateResult = Pattern.matches(regDate, text);
+	    	
+			if(expResult) {
+				return STRING;
+			}else if(dateResult) {				
+				return DATE;
+			}else {
+				return DATETIME;
+			}
+			
+		} else {
+			return STRING;
+		}
+	}
+    
+    /**
+	 * 데이터 타입 검사, dbDataType 조회
+	 */
+    public static String convertDbDataType (DataType datatype, Integer size) {
+    	final int MAX_VARCHAR_SIZE = 765;
+    	
+    	if (datatype == STRING) {
+    		if (size == null || size <= MAX_VARCHAR_SIZE) {
+    			return "varchar";
+    		} else {
+    			return "text";
+    		}
+    	} else if (datatype == DATE) {
+    		return "date";
+    	} else if (datatype == DATETIME){
+    		return "datetime";
+    	} else if (datatype == LONG) {
+    		return "bigint";
+    	} else if (datatype == DOUBLE) {
+    		return "double";
+    	} else {
+    		return "varchar";
+    	}
+    }
+    
+    /**
+	 * 데이터 타입 검사, dbDataType -> javaType 조회
+	 */
+    public static DataType convertDataTypeDbtoJava (DataType datatype, Integer size) {
+    	
+    	
+    	return null;	    	
+    }
+    
+    
+    /**
+	 * 데이터 타입 형태로 값 변경
+	 */
+	public static Object parse(DataType dataType, Object value) {
+		if (CommonUtil.isNull(value) == true) {
+			return null;
+		}
+		
+		Class<?> javaType = dataType.getJavaType();
+		try {
+			if (javaType.getSimpleName().equals("Byte")) {
+				return Byte.parseByte(value.toString());
+			} else if (javaType.getSimpleName().equals("Boolean")) {
+				return Boolean.parseBoolean(value.toString());
+			} else if (javaType.getSimpleName().equals("Character")) {
+				return value.toString().toCharArray();
+			} else if (javaType.getSimpleName().equals("String")) {
+				return value.toString();
+			} else if (javaType.getSimpleName().equals("Short")) {
+				//Short.parseShort(value.toString().replaceAll("[^0-9]",""));
+				return Short.parseShort(value.toString());
+			} else if (javaType.getSimpleName().equals("Integer")) {
+				//Integer.parseInt(value.toString().replaceAll("[^0-9]",""));
+				return Integer.parseInt(value.toString());
+			} else if (javaType.getSimpleName().equals("Long")) {
+				//Long.parseLong(value.toString().replaceAll("[^0-9]",""));
+				return Long.parseLong(value.toString());
+			} else if (javaType.getSimpleName().equals("Float")) {
+				//Float.parseFloat(value.toString().replaceAll("[^0-9]",""));
+				return Float.parseFloat(value.toString());
+			} else if (javaType.getSimpleName().equals("Double")) {
+				//Double.parseDouble(value.toString().replaceAll("[^0-9]",""));
+				return Double.parseDouble(value.toString());
+			} else {
+				return value;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			return dataType.getInitValue();
+		}
+	}
+	
+	/**
+	 * 데이터 타입 형태로 값 변경
+	 */
+	public static boolean parseCheck (DataType dataType, Object value) {
+		if (CommonUtil.isNull(value) == true) {
+			return false;
+		}
+		
+		Class<?> javaType = dataType.getJavaType();
+		try {
+			if (javaType.getSimpleName().equals("Byte")) {
+				Byte.parseByte(value.toString());
+			} else if (javaType.getSimpleName().equals("Boolean")) {
+				Boolean.parseBoolean(value.toString());
+			} else if (javaType.getSimpleName().equals("Character")) {
+				value.toString().toCharArray();
+			} else if (javaType.getSimpleName().equals("String")) {
+				value.toString();
+			} else if (javaType.getSimpleName().equals("Short")) {
+				//Short.parseShort(value.toString().replaceAll("[^0-9]",""));
+				Short.parseShort(value.toString());
+			} else if (javaType.getSimpleName().equals("Integer")) {
+				//Integer.parseInt(value.toString().replaceAll("[^0-9]",""));
+				Integer.parseInt(value.toString());
+			} else if (javaType.getSimpleName().equals("Long")) {
+				//Long.parseLong(value.toString().replaceAll("[^0-9]",""));
+				Long.parseLong(value.toString());
+			} else if (javaType.getSimpleName().equals("Float")) {
+				//Float.parseFloat(value.toString().replaceAll("[^0-9]",""));
+				Float.parseFloat(value.toString());
+			} else if (javaType.getSimpleName().equals("Double")) {
+				//Double.parseDouble(value.toString().replaceAll("[^0-9]",""));
+				Double.parseDouble(value.toString());
+			}
+			
+			return true;
+		} catch (Exception e) {
+			//e.printStackTrace();
+			return false;
+		}
+	}
+	
+	
+}
+
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicColumn.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicColumn.java
@@ -0,0 +1,56 @@
+package com.takensoft.taken_bi_manager.common.connection.db.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.01.04
+ * 
+ * 데이터 베이스 기본 정보를 담는 Class 입니다.
+ */
+@Getter
+@Setter
+public class TableBasicColumn implements Cloneable{
+	
+	public TableBasicColumn () {}
+	
+	public TableBasicColumn (TableBasicInfo tableBasicInfo) {
+		this.columnName = tableBasicInfo.getColumnName();
+		this.tobeColumnName = tableBasicInfo.getTobeColumnName();
+		this.dataType = tableBasicInfo.getDataType();
+		this.size = tableBasicInfo.getSize();
+	}
+	
+	/**
+	 * 컬럼명
+	 */
+	private String columnName;
+	
+	/**
+	 * 바뀔 컬럼명
+	 */
+	private String tobeColumnName;
+	
+	/**
+	 * 컬럼의 데이터 타입(DB기준)
+	 */
+	private String dataType;
+	
+	/**
+	 * 컬럼의 데이터 size
+	 */
+	private long size;
+	
+	/**
+	 * 해당 열의 PK인지 아닌지에 대한 여부
+	 */
+	private boolean isPrimary;
+
+
+	
+	public TableBasicColumn clone() throws CloneNotSupportedException {
+        return (TableBasicColumn)super.clone();
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicInfo.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicInfo.java
@@ -0,0 +1,85 @@
+package com.takensoft.taken_bi_manager.common.connection.db.vo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.01.04
+ * 
+ * 데이터 베이스 기본 설정 변경시 사용할 class 입니다.
+ */
+@Getter
+@Setter
+public class TableBasicInfo {
+	
+	public TableBasicInfo () {}
+	
+	public TableBasicInfo (String databaseName, String tableName, String columnName) {
+		this.databaseName = databaseName;
+		this.tableName = tableName;
+		this.columnName = columnName;
+	}
+
+	/**
+	 * 데이터 베이스 명 (스키마명)
+	 */
+	private String databaseName;
+	
+	/**
+	 * 데이터 베이스 접속 아이디
+	 */
+	private String id;
+	
+	/**
+	 * 테이블명
+	 */
+	private String tableName;
+	
+	/**
+	 * 컬럼명
+	 */
+	private String columnName;
+	
+	/**
+	 * 바뀔 컬럼명
+	 */
+	private String tobeColumnName;
+	
+	/**
+	 * 컬럼의 데이터 타입(DB기준)
+	 */
+	private String dataType;
+	
+	/**
+	 * 컬럼의 데이터 size
+	 */
+	private long size;
+	
+	/**
+	 * 해당 열의 PK인지 아닌지에 대한 여부
+	 */
+	private boolean isPrimary;
+		
+	/**
+	 * PK 리스트 
+	 */
+	private List<String> primaryList;		
+	
+	/**
+	 * PK 리스트 
+	 */
+	private String process;
+		
+
+	/**
+	 * 컬럼의 데이터 목록
+	 */
+	List<TableBasicColumn> tableBasicColumns = new ArrayList<TableBasicColumn>(); 
+
+	
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/dao/ConnectEhojoPlusDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/dao/ConnectEhojoPlusDAO.java
@@ -0,0 +1,66 @@
+package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.dao;
+
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.EhojoPlusParamVO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.*;
+
+@Mapper
+public interface ConnectEhojoPlusDAO {
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 등록
+     */
+    public int ehojoPlusInfoInsert(ConnectionEhojoVO connectionEhojoVO) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 헤더 정보 등록
+     */
+    public int ehojoPlusHeadersInfoInsert(EhojoPlusParamVO ehojoPlusParamVO) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 바디 정보 등록
+     */
+    public int ehojoPlusBodysInfoInsert(EhojoPlusParamVO ehojoPlusParamVO) throws Exception;
+    
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 조회
+     */
+    public ConnectionEhojoVO selectEhojoPlusInfo(String ehpInfoId) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 삭제
+     */
+    public int deleteEhojoPlusInfo(String ehpInfoId) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 헤더 정보 삭제
+     */
+    public int deleteEhojoPlusHeadersInfo(String ehpInfoId) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 바디 정보 삭제
+     */
+    public int deleteEhojoPlusBodysInfo(String ehpInfoId) throws Exception;
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/service/ConnectEhojoPlusService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/service/ConnectEhojoPlusService.java
@@ -0,0 +1,38 @@
+package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service;
+
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+
+public interface ConnectEhojoPlusService {
+    /**
+     * @author 하관우
+     * @since 2024.12.26
+
+     * 차세대지방재정 Api 호출
+     */
+    public CustomeResultMap openFisCal(ConnectionEhojoVO connectionEhojoVO) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 등록
+     */
+    public int ehojoPlusInfoInsert(ConnectionEhojoVO connectionEhojoVO) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 조회
+     */
+    public ConnectionEhojoVO selectEhojoPlusInfo(String ehpInfoId) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 삭제
+     */
+    public int deleteEhojoPlusInfo(String ehpInfoId) throws Exception;
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/service/impl/ConnectEhojoPlusServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/service/impl/ConnectEhojoPlusServiceImpl.java
@@ -0,0 +1,89 @@
+package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service.impl;
+
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.dao.ConnectEhojoPlusDAO;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service.ConnectEhojoPlusService;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.util.OpenFisCal;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.EhojoPlusParamVO;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@RequiredArgsConstructor
+public class ConnectEhojoPlusServiceImpl implements ConnectEhojoPlusService {
+    private final ConnectEhojoPlusDAO connectEhojoPlusDAO;
+
+    /**
+     * @author 하관우
+     * @since 2024.12.26
+
+     * 차세대지방재정 Api 호출
+     */
+    @Override
+    public CustomeResultMap openFisCal(ConnectionEhojoVO connectionEhojoVO) throws Exception {
+        //상주시
+        connectionEhojoVO.setApiKey("ccef9d3b5e2c1d2d16177898a54e9cc1ff8551b9416c1a8baf33f71db7599cb1");
+        connectionEhojoVO.setEncKey("4PTPHNQC8F");
+        connectionEhojoVO.setUrl("http://10.60.76.53:26002/");
+        OpenFisCal openFisCal = new OpenFisCal();
+        return openFisCal.openFisCal(connectionEhojoVO);
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 등록
+     */
+    @Override
+    public int ehojoPlusInfoInsert(ConnectionEhojoVO connectionEhojoVO) throws Exception {
+        int result = 0;
+        // 차세대 지방재정관리시스템 연결 정보 등록
+        result += connectEhojoPlusDAO.ehojoPlusInfoInsert(connectionEhojoVO);
+
+        for (EhojoPlusParamVO header : connectionEhojoVO.getHeaders()) {
+            // 차세대 지방재정관리시스템 헤더 정보 등록
+            result += connectEhojoPlusDAO.ehojoPlusHeadersInfoInsert(header);
+        }
+        for (EhojoPlusParamVO body : connectionEhojoVO.getBodys()) {
+            // 차세대 지방재정관리시스템 바디 정보 등록
+            result += connectEhojoPlusDAO.ehojoPlusBodysInfoInsert(body);
+        }
+
+        return result;
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 조회
+     */
+    public ConnectionEhojoVO selectEhojoPlusInfo(String ehpInfoId) throws Exception {
+        return connectEhojoPlusDAO.selectEhojoPlusInfo(ehpInfoId);
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 삭제
+     */
+    @Override
+    public int deleteEhojoPlusInfo(String ehpInfoId) throws Exception {
+        int result = 0;
+
+        // 차세대 지방재정관리시스템 연결 정보 삭제
+        result += connectEhojoPlusDAO.deleteEhojoPlusInfo(ehpInfoId);
+
+        // 차세대 지방재정관리시스템 헤더 정보 삭제
+        result += connectEhojoPlusDAO.deleteEhojoPlusHeadersInfo(ehpInfoId);
+
+        // 차세대 지방재정관리시스템 바디 정보 삭제
+        result += connectEhojoPlusDAO.deleteEhojoPlusBodysInfo(ehpInfoId);
+
+        return result;
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/util/OpenFisCal.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/util/OpenFisCal.java
@@ -0,0 +1,204 @@
+package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.util;
+
+import com.takensoft.taken_bi_manager.common.connection.api.util.DataUtil;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.EhojoPlusParamVO;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil;
+import com.takensoft.taken_bi_manager.common.vo.CheckMessage;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import net.sf.json.JSONObject;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import com.indigo.util.EncryptionUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class OpenFisCal {
+    public CustomeResultMap openFisCal(ConnectionEhojoVO connectionEhojoVO) throws Exception {
+        // HTTP Client
+        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
+        HttpClient httpClient = httpClientBuilder.build();
+        // HTTP Method
+        String url = connectionEhojoVO.getUrl() + connectionEhojoVO.getTaskCode() + "/openAPI/" + connectionEhojoVO.getTableName();
+        HttpPost httpPost = new HttpPost(url);
+        // HTTP Header
+        // API 인증키 (외부기관에서 요청 시 필요)
+        httpPost.setHeader("API_KEY", connectionEhojoVO.getApiKey());
+        httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
+        // JSON 요청 메시지
+        JSONObject jsonReq = new JSONObject();
+        // Header
+        JSONObject header = new JSONObject();
+        // body
+        JSONObject body = new JSONObject();
+
+        // Header 설정
+        for(EhojoPlusParamVO item : connectionEhojoVO.getHeaders()) {
+            if(item.getKey().equals("tranId")) {
+                header.put(item.getKey(), EncryptionUtils.makeTxId(connectionEhojoVO.getIfId())); // 트랜잭션 아이디
+            } else {
+                header.put(item.getKey(), item.getValue()); // 다른 값들은 원래 값 그대로 넣기
+            }
+        }
+
+        /**********************************************************************
+         * 조회 조건 필수 값 설정(인터페이스 정의서 확인 필요)
+         *********************************************************************/
+        // body 설정
+        for(EhojoPlusParamVO item : connectionEhojoVO.getBodys()) {
+            String key = item.getKey();
+            body.put(key, item.getValue()); // 다른 값들은 원래 값 그대로 넣기
+        }
+
+        /**********************************************************************
+         * 인터페이스 정의서를 참고하여 추가로 필요한 항목 설정 추가
+         *
+         * 많은 경우 loop 처리하여 페이지 순차 호출
+         *
+         * 조회 조건 필수 값 설정 끝
+         *********************************************************************/
+
+        // JSON 요청 메시지 설정
+        jsonReq.put("header", header);
+        // body 암호화 (외부기관에서 요청 시 필요)
+        jsonReq.put("body", EncryptionUtils.encryptStringAria(body.toString(), connectionEhojoVO.getEncKey()));
+        System.out.println("요청 전문" + jsonReq.toString());
+
+        // Request → Response
+        httpPost.setEntity(new StringEntity(jsonReq.toString(), "UTF-8"));
+        HttpResponse httpResponse = httpClient.execute(httpPost);
+        HttpEntity httpEntity = httpResponse.getEntity();
+
+        List<Map<String,Object>> dataList = new ArrayList<>();
+        CustomeResultMap customeResultMap = new CustomeResultMap();
+
+        if (httpResponse != null) {
+            int statusCode = httpResponse.getStatusLine().getStatusCode();
+            switch (statusCode) {
+                case 200:
+                    try {
+                        // 응답 메시지
+                        String strRes = EntityUtils.toString(httpEntity, "UTF-8");
+                        // JSON Parsing
+                        JSONObject jsonRes = JSONObject.fromObject(strRes);
+
+                        // 응답 코드 확인
+                        String responseCode = jsonRes.optString("code", "");
+                        String message = "";
+                        boolean isSuccess = false;
+
+                        switch (responseCode) {
+                            case "0000":
+                                message = "정상";
+                                isSuccess = true;
+                                // 정상 처리 시에만 body 복호화
+                                JSONObject resBody = JSONObject.fromObject(EncryptionUtils.decryptStringAria(
+                                        jsonRes.getString("body"),
+                                        connectionEhojoVO.getEncKey()));
+                                jsonRes.put("body", resBody);
+                                dataList.add(jsonRes);
+                                break;
+                            case "N011": message = "네트워크 오류"; break;
+                            case "D011": message = "DB 접속 오류"; break;
+                            case "D012": message = "DB SQL 오류"; break;
+                            case "F011": message = "파일 IO 오류"; break;
+                            case "G011": message = "대상 시스템 오류"; break;
+                            case "4001": message = "요청 헤더 오류"; break;
+                            case "4002": message = "요청 파라미터 오류"; break;
+                            case "4011": message = "유효하지 않는 API 키"; break;
+                            case "4012": message = "API 사용 권한 없음"; break;
+                            case "4031": message = "일시적인 서비스 제한"; break;
+                            case "4032": message = "기관코드 확인 불가"; break;
+                            case "4041": message = "서비스가 존재하지 않음"; break;
+                            case "4042": message = "인터페이스ID 미 존재"; break;
+                            case "4043": message = "트랜잭션ID 미 존재"; break;
+                            case "4291": message = "정보제공 요청한도 초과"; break;
+                            case "5001": message = "시스템 장애"; break;
+                            case "5002": message = "API 요청 처리 실패"; break;
+                            case "5003": message = "처리시간 초과 에러"; break;
+                            case "5004": message = "알 수 없는 에러"; break;
+                            case "6011": message = "응용프로그램 호출 실패"; break;
+                            case "6012": message = "응용프로그램 타임 아웃"; break;
+                            case "6021": message = "업무 반영 실패"; break;
+                            default: message = "알 수 없는 응답 코드: " + responseCode;
+                        }
+
+                        CheckMessage checkMessage = new CheckMessage(isSuccess, message, responseCode);
+                        customeResultMap.setCheckMessage(checkMessage);
+
+                        // 로깅
+                        System.out.println("요청 결과 :: " + jsonRes.toString());
+                        System.out.println("응답 코드 :: " + responseCode + ", 메시지 :: " + message);
+
+                    } catch (Exception e) {
+                        System.err.println("응답 처리 중 오류 발생: " + e.getMessage());
+                        CheckMessage errorMessage = new CheckMessage(false, "응답 처리 중 오류 발생", "5004");
+                        customeResultMap.setCheckMessage(errorMessage);
+                    }
+                    break;
+
+                case 400:
+                    customeResultMap.setCheckMessage(new CheckMessage(false, "잘못된 요청", "4002"));
+                    break;
+                case 401:
+                    customeResultMap.setCheckMessage(new CheckMessage(false, "인증 실패", "4011"));
+                    break;
+                case 403:
+                    customeResultMap.setCheckMessage(new CheckMessage(false, "접근 권한 없음", "4012"));
+                    break;
+                case 404:
+                    customeResultMap.setCheckMessage(new CheckMessage(false, "리소스를 찾을 수 없음", "4041"));
+                    break;
+                case 500:
+                    customeResultMap.setCheckMessage(new CheckMessage(false, "서버 내부 오류", "5001"));
+                    break;
+                case 503:
+                    customeResultMap.setCheckMessage(new CheckMessage(false, "서비스 일시적 사용 불가", "5002"));
+                    break;
+                default:
+                    customeResultMap.setCheckMessage(new CheckMessage(false,
+                            "예상치 못한 HTTP 상태 코드: " + statusCode, "5004"));
+            }
+        } else {
+            customeResultMap.setCheckMessage(new CheckMessage(false, "HTTP 응답이 null입니다", "5004"));
+        }
+
+        int max = 0;
+        int indx = 0;
+
+        // 최대 길이의 키값을 가진 객체 구하기
+        for(int i = 0 ; i < dataList.size() ; i++){
+            if(dataList.get(i).keySet().size() > max) {
+                max = dataList.get(i).keySet().size();
+                indx = i;
+            }
+        }
+        // 빈정보 공백으로 채우기
+        for(Map<String, Object> item : dataList ) {
+            if(max != item.size()) {
+                for (Map.Entry<String, Object> entry : dataList.get(indx).entrySet())
+                {
+                    if(item.get(entry.getKey()) == null) {
+                        item.put(entry.getKey(),"");
+                    }
+                }
+            }
+        }
+        DataTable dataTable = DataUtil.setMaptoDataTable(dataList);
+        DataUtil.setColumnMetaData(dataTable, false);
+        DataTypeUtil.convertDataTableColumMeta(dataTable);
+        HashMap<String, Object> dataMap = new HashMap<>();
+        dataMap.put("dataTable", dataTable); // 또는 적절한 키 이름 사용
+        customeResultMap.setResultData(dataMap);
+        return customeResultMap;
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/vo/ConnectionEhojoVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/vo/ConnectionEhojoVO.java
@@ -0,0 +1,39 @@
+package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo;
+
+import com.takensoft.taken_bi_manager.jobs.vo.item.JobReadConItm;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.*;
+
+@Getter
+@Setter
+public class ConnectionEhojoVO extends JobReadConItm implements Serializable {
+    // 차세대 지방재정관리시스템 연결 정보 아이디
+    private String ehpInfoId;
+
+    // front에서 설정하는 정보
+    // 인터페이스 ID
+    private String ifId;
+    // 송신기관 코드
+    private String lafCode;
+    // 업무구분 코드
+    private String taskCode;
+    // 테이블 명
+    private String tableName;
+
+    // back에서 설정하는 정보
+    // 호출 url 설정
+    private String url;
+    // apiKey 설정
+    private String apiKey;
+    // 암복호화 key 설정
+    private String encKey;
+
+    // 헤더 키, 값 목록
+    private List<EhojoPlusParamVO> headers = new ArrayList<>();
+
+    // 바디 키, 값 목록
+    private List<EhojoPlusParamVO> bodys = new ArrayList<>();
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/vo/EhojoPlusParamVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/vo/EhojoPlusParamVO.java
@@ -0,0 +1,20 @@
+package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class EhojoPlusParamVO {
+    // 차세대 지방재정관리시스템 연결 정보 아이디
+    private String ehpInfoId;
+
+    // 인덱스
+    private int index;
+    // 키
+    private String key;
+    // 값
+    private String value;
+    // 필수 여부 (프론트에서 사용)
+    private String required;
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/web/ConnectEhojoPlusController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/web/ConnectEhojoPlusController.java
@@ -0,0 +1,68 @@
+package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.web;
+
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service.ConnectEhojoPlusService;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+@RequiredArgsConstructor
+public class ConnectEhojoPlusController {
+    private final ConnectEhojoPlusService connectEhojoPlusService;
+
+    /**
+     * @author 하관우
+     * @since 2024.12.26
+
+     * 차세대지방재정 Api 호출
+     */
+    @RequestMapping(value ="/openfiscal.json", method = RequestMethod.POST)
+    public ModelAndView openFisCal(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{
+        ModelAndView mav = new ModelAndView("jsonView");
+        mav.addObject("customeResultMap", connectEhojoPlusService.openFisCal(connectionEhojoVO));
+        return mav;
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 등록
+     */
+    @RequestMapping(value ="/ehojoConnectionInfoInsert.json", method = RequestMethod.POST)
+    public ModelAndView ehojoPlusInfoInsert(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{
+        ModelAndView mav = new ModelAndView("jsonView");
+        mav.addObject("dataTableResult", connectEhojoPlusService.ehojoPlusInfoInsert(connectionEhojoVO));
+        return mav;
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 조회
+     */
+    @RequestMapping(value ="/ehojoConnectionInfoSelect.json", method = RequestMethod.POST)
+    public ModelAndView selectEhojoPlusInfo(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{
+        ModelAndView mav = new ModelAndView("jsonView");
+        mav.addObject("dataTableResult", connectEhojoPlusService.selectEhojoPlusInfo(connectionEhojoVO.getEhpInfoId()));
+        return mav;
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.12.27
+     *
+     * 차세대 지방재정관리시스템 연결 정보 삭제
+     */
+    @RequestMapping(value ="/ehojoConnectionInfoDelete.json", method = RequestMethod.POST)
+    public ModelAndView ehojoPlusInfoDelete(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{
+        ModelAndView mav = new ModelAndView("jsonView");
+        mav.addObject("dataTableResult", connectEhojoPlusService.deleteEhojoPlusInfo(connectionEhojoVO.getEhpInfoId()));
+        return mav;
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/connection/util/DataTableCreate.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/util/DataTableCreate.java
@@ -0,0 +1,124 @@
+package com.takensoft.taken_bi_manager.common.connection.util;
+
+import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode;
+import com.takensoft.taken_bi_manager.data.dao.DatasetDAO;
+import com.takensoft.taken_bi_manager.data.service.DataService;
+import com.takensoft.taken_bi_manager.data.service.DatasetService;
+import com.takensoft.taken_bi_manager.data.util.DataTableConvert;
+import com.takensoft.taken_bi_manager.data.vo.*;
+import com.takensoft.taken_bi_manager.jobs.util.JobUtil;
+import com.takensoft.taken_bi_manager.jobs.vo.JobItm;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Component
+public class DataTableCreate {
+
+    @Autowired
+    private DataService dataService;
+
+    @Autowired
+    private DatasetService datasetService;
+
+    @Autowired
+    private DatasetDAO datasetDAO;
+
+    /**
+     * @author 김성원
+     * @since 2024.02.15
+     * <p>
+     * 데이터 테이블 생성 Background 실행
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void dataTableCreateTable(DatasetPost datasetPost, Dataset tempDataset, ConnectionDB connectionDB, JobItm itm, String member) throws Exception {
+
+        String datasetPostId = datasetPost.getDataset_post_id();
+        try {
+            DataTable resultTable;
+            if(itm.getDataTable().getQuery().equals("") || itm.getDataTable().getQuery() == null){
+                resultTable = (DataTable)itm.getDataTable().clone();
+            } else {
+                List<Boolean> keyList = DataTableConvert.pkList(itm.getDataTable());
+                resultTable = JobUtil.dbConnectionExec(itm);
+                DataTableConvert.setPkist(keyList,resultTable);
+            }
+
+            resultTable.setDatasetPostId(datasetPostId);
+            resultTable.setDatabaseNm(connectionDB.getDatabaseNm());
+            DataTypeUtil.convertDataTableColumMeta(resultTable);
+            resultTable.setTableNm(tempDataset.getTableNm().toLowerCase());
+            resultTable.setTableNmKr(tempDataset.getTableNmKr());
+            resultTable.setDatasetSj(datasetPost.getPost_sj());
+
+            for(ColumnData data : resultTable.getColumnDatas()) {
+                if(StringUtil.isEmpty(data.getColumnNm())){
+                    data.setColumnNm(data.getOrginlColumnNm());
+                }
+            }
+
+            connectionDB.setLoadAt(true);
+
+            // 테이블 생성
+            dataService.datasetTableCreate(resultTable, SystemCode.DatasetType.RAW, connectionDB);
+
+            String connectionId = "";
+
+            // 커넥션 아이디 없을때
+            if(StringUtil.isEmpty(connectionDB.getDbConectId())){
+               CustomeResultMap resultMap =  dataService.conflictInsertDbConnection(connectionDB);
+                connectionId =  resultMap.getResultData().get("dbConectId").toString();
+            }else{
+                connectionId = connectionDB.getDbConectId();
+            }
+
+            // 데이터셋 등록
+            Dataset dataset = new Dataset();
+            dataset.setDbConectId(connectionDB.getDbConectId());
+            dataset.setDatasetId(resultTable.getDatasetId());//datasetTableCreate 생성시 datasetId를 받아옴
+            dataset.setTableNm(resultTable.getTableNm());//datasetTableCreate 생성시 DB에 생성된 Table명을 받아옴
+            dataset.setCreatTableAt(true);
+            dataset.setDatasetSj(datasetPost.getPost_sj());//데이터 셋 명(데이터명)
+            dataset.setTableNmKr(resultTable.getTableNmKr());
+            dataset.setDatasetPostId(datasetPostId);
+           // dataset.setDatasetDataType(DataUtil.getDatasetDataType(tempTable.getColumnDatas()));//해당 데이터 셋의 데이터 타입
+            datasetService.conflictInsertDataset(dataset);
+
+            //컬럼 정보 등록 (컬럼이 존재할 때만 등록 가능)
+            for (int j = 0; j < resultTable.getColumnDatas().size(); j++) {
+                ColumnData columnData = resultTable.getColumnDatas().get(j);
+                columnData.setDatasetId(dataset.getDatasetId());
+                datasetService.conflictInsertCoulmnInfo((Column) columnData);
+            }
+
+            /*데이터 등록*/
+            dataService.datasetDataUpdate(resultTable,connectionDB, "user");
+
+            /*업데이트 로그 생성*/
+            //데이터 업데이트 로그 저장 처리
+            DatasetPostLog datasetPostLog = new DatasetPostLog(datasetPostId, member);
+            datasetPostLog.setSuccess("C");
+            datasetPostLog.setCRUD(resultTable.getTotalRows(), 0, 0);
+            datasetPostLog.setLog_sttus("C");
+
+            datasetDAO.insertDatasetPostLog(datasetPostLog);
+
+        }catch (Exception e){
+            /*업데이트 로그 생성*/
+            //데이터 업데이트 로그 저장 처리
+            DatasetPostLog datasetPostLog = new DatasetPostLog(datasetPostId,member);
+            datasetPostLog.setError(e.toString(),"C");
+            datasetPostLog.setCRUD(0, 0, 0);
+            datasetPostLog.setLog_sttus("E");
+            datasetDAO.insertDatasetPostLog(datasetPostLog);
+            throw new Exception(e);
+        }
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/file/dao/FileDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/dao/FileDAO.java
@@ -0,0 +1,73 @@
+package com.takensoft.taken_bi_manager.common.file.dao;
+
+import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile;
+import com.takensoft.taken_bi_manager.common.file.vo.FileManage;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.HashMap;
+import java.util.List;
+
+@Mapper
+public interface FileDAO {
+    /**
+     * @author 방선주
+     * @since 2024.04.22
+     *
+     * file manager 등록
+     */
+    void fileManagerInsert(FileManage fileManage);
+    /**
+     * @author 방선주
+     * @since 2024.04.22
+     *
+     * cmmn_file 등록
+     */
+    void fileInsert(CmmnFile fileInfo);
+    /**
+     * @author 방선주
+     * @since 2024.04.22
+     *
+     * 이미지 경로 cmmnfile에서 가져오기
+     */
+    CmmnFile cmmnfileSelect(String fileManagerId);
+    /**
+     * @author 방선주
+     * @since 2024.04.22
+     *
+     * cmmnfile에서 이미지 경로 삭제
+     */
+    void cmmnfileDelete(String fileManagerId);
+    /**
+     * @author 방선주
+     * @since 2024.04.22
+     *
+     * fileManager에서 이미지 경로 삭제
+     */
+    void fileManagerDelete(String fileManagerId);
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 이미지 경로 cmmnfile에서 파일 여러개 가져오기
+     */
+    public List<CmmnFile> cmmnfilesSelect(String fileManagerId);
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 파일 정보 삭제
+     */
+    public int deleteCmmnFileToDataSetPost(String fileManagerId);
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 파일 매니저 삭제
+     */
+    public int deleteFileManagerToDataSetPost(String fileManagerId);
+
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/file/handler/Sheet2ListHandler.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/handler/Sheet2ListHandler.java
@@ -0,0 +1,242 @@
+package com.takensoft.taken_bi_manager.common.file.handler;
+
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import org.xml.sax.SAXException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class Sheet2ListHandler implements SheetHandler.SheetContentsHandler2 {
+//public class Sheet2ListHandler implements SheetHandler{
+	//collection 객체
+	private List<List<Object>> rows;
+	//collection에 추가될 객체 startRow에서 초기화함.
+	private List<Object> row;
+
+	//collection 내 객체를 String[]로 잡았기 때문에 배열의 길이를 생서시 받도록 설계
+//	private int columnCnt;
+	private int currentRowIndex = 0;
+	
+	private int maxCellLength = 0;
+	
+	/* 정우 추가 */
+	
+	//생략된 row Index's
+	private List<Integer> skipRowIndexs = new ArrayList<Integer>();
+	
+	//데이터 영역
+	private int firstRow = 0;
+	private int firstColumn = 0;
+	private int lastRow = 0;
+	private int lastColumn = 0;
+	
+	private List<Map<String, Integer>> mergeCellInfoList;
+	
+	//행에 열데이터가 1개라도 존재하는지 체크 (row 시작할 때, false로 초기화 시켜야됨)
+	boolean isRowDataExist = false;
+	private List<Integer> rowDataNoneExistIndexs = new ArrayList<Integer>();
+
+	// 하석형 추가
+	private int limit = 0; // 미리보기 전용 limit
+	private int rowCount = 0; // 처리한 row의 수를 카운팅
+	
+	/* 정우 추가 */	
+	//외부 collection과 배열 size를 받기 위해 추가한 부분
+	public Sheet2ListHandler(List<List<Object>> rows/*, int columnsCnt*/, int limit) {
+		this.rows = rows;
+		this.limit = limit;
+	}
+	
+	//Row의 시작 부분에서 발생하는 이벤트를 처리하는 method
+	public void startRow(String currentRowIndex) throws SAXException {
+		if(this.rowCount >= this.limit) {
+//			throw new LimitReachedException("Limit reached");
+			throw new SAXException("limit");
+//			return;
+		}
+		this.currentRowIndex = CommonUtil.parseInt(currentRowIndex);
+
+		//처음 데이터 읽기 시작한 엑셀의 행 Index (0부터 시작)
+		this.row = new ArrayList<Object>();
+		//*행에 열데이터가 1개라도 존재하는지 체크값 '초기화'*
+		this.isRowDataExist = false;
+	}
+	
+	//Row의 끝에서 발생하는 이벤트를 처리하는 method
+	public void endRow() {
+		//최대 열 개수 '최신화'
+		if (this.maxCellLength < row.size()) {
+			this.maxCellLength = row.size();
+		}
+		//row데이터 추가
+		this.rows.add(this.row);
+
+		//행에 열데이터가 1개라도 존재하지 않을 때 -> Index 추가
+		if (this.isRowDataExist == false) {
+			rowDataNoneExistIndexs.add((this.rows.size() - 1));
+		}
+		this.rowCount++; // 처리한 row의 수를 카운팅
+	}
+	
+	public void cellDataAdd(String value) {
+		//cell 이벤트 발생 시 해당 cell의 주소와 값을 받아옴.
+		//입맛에 맞게 처리하면 됨.
+		
+		if (StringUtil.isEmpty(value) == true) {
+			this.row.add(null);
+		} else {
+			this.row.add(value);
+			this.isRowDataExist = true;
+		}
+	}
+	
+	/* 정우 추가 */
+	public void findMerge () {
+		this.mergeCellInfoList = new ArrayList<Map<String, Integer>>();
+	}
+	
+	public void addMergeInfo (int firstRow, int firstColumn, int lastRow, int lastColumn) {
+		Map<String, Integer> info = new HashMap<String, Integer>();
+		info.put("firstRow", firstRow);
+		info.put("firstColumn", firstColumn);
+		info.put("lastRow", lastRow);
+		info.put("lastColumn", lastColumn);
+		
+		this.mergeCellInfoList.add(info);
+	}
+	/* 정우 추가 */
+	
+	public String overriddenFormat(String cellRef, int formatIndex, String formatString, String value) {
+		if(formatString != null && (formatString.equals("reserved-0x1f")||formatString.equals("m/d/yy")||formatString.equals("yy/mm/dd")
+				||formatString.equals("[$-F800]dddd\\,\\ mmmm\\ dd\\,\\ yyyy"))) {
+			return "yyyy-mm-dd;@";
+		}
+
+	    return null;
+	}
+	
+	public void headerFooter(String paramString1, boolean paramBoolean, String paramString2) {
+
+	}
+	
+	/* 정우 추가 */
+	public void endEvent () {	
+		
+		if (mergeCellInfoList != null && mergeCellInfoList.size() > 0) {
+			for (int i = 0; i < mergeCellInfoList.size(); i++) {
+				int firstRow = mergeCellInfoList.get(i).get("firstRow") - this.firstRow;
+				int firstColumn = mergeCellInfoList.get(i).get("firstColumn") - this.firstColumn;
+				int lastRow = mergeCellInfoList.get(i).get("lastRow") - this.firstRow;
+				int lastColumn = mergeCellInfoList.get(i).get("lastColumn") - this.firstColumn;
+				
+				String value = (String) rows.get(firstRow).get(firstColumn);
+				
+				for (int j = firstRow; j <= lastRow; j++) {
+					for (int z = firstColumn; z <= lastColumn; z++) {
+						rows.get(j).set(z, value);
+					}
+				}
+			}
+		}
+		
+		for (int removeCount = 0; removeCount < this.rowDataNoneExistIndexs.size(); removeCount++) {
+			int removeIndex = this.rowDataNoneExistIndexs.get(removeCount);
+			if (removeIndex > -1) {
+				rows.remove(removeIndex - removeCount);
+			}
+		}
+	}
+
+	
+	/* 정우 추가 */
+	public List<List<Object>> getRows() {
+		return rows;
+	}
+
+	public void setRows(List<List<Object>> rows) {
+		this.rows = rows;
+	}
+
+	public List<Object> getRow() {
+		return row;
+	}
+
+	public void setRow(List<Object> row) {
+		this.row = row;
+	}
+
+	public int getMaxCellLength() {
+		return maxCellLength;
+	}
+
+	public void setMaxCellLength(int maxCellLength) {
+		this.maxCellLength = maxCellLength;
+	}
+
+	public List<Integer> getSkipRowIndexs() {
+		return skipRowIndexs;
+	}
+
+	public void setSkipRowIndexs(List<Integer> skipRowIndexs) {
+		this.skipRowIndexs = skipRowIndexs;
+	}
+
+	public int getFirstRow() {
+		return firstRow;
+	}
+
+	public void setFirstRow(int firstRow) {
+		this.firstRow = firstRow;
+	}
+
+	public int getFirstColumn() {
+		return firstColumn;
+	}
+
+	public void setFirstColumn(int firstColumn) {
+		this.firstColumn = firstColumn;
+	}
+
+	public int getLastRow() {
+		return lastRow;
+	}
+
+	public void setLastRow(int lastRow) {
+		this.lastRow = lastRow;
+	}
+
+	public int getLastColumn() {
+		return lastColumn;
+	}
+
+	public void setLastColumn(int lastColumn) {
+		this.lastColumn = lastColumn;
+	}
+
+	public List<Map<String, Integer>> getMergeCellInfoList() {
+		return mergeCellInfoList;
+	}
+
+	public void setMergeCellInfoList(List<Map<String, Integer>> mergeCellInfoList) {
+		this.mergeCellInfoList = mergeCellInfoList;
+	}
+	
+	public List<Integer> getRowDataNoneExistIndexs() {
+		return rowDataNoneExistIndexs;
+	}
+
+	public void setRowDataNoneExistIndexs(List<Integer> rowDataNoneExistIndexs) {
+		this.rowDataNoneExistIndexs = rowDataNoneExistIndexs;
+	}
+
+	// 사용자 정의 예외
+	public class LimitReachedException  extends RuntimeException  {
+		public LimitReachedException(String message) {
+			super(message);
+		}
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/file/handler/SheetHandler.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/handler/SheetHandler.java
@@ -0,0 +1,456 @@
+package com.takensoft.taken_bi_manager.common.file.handler;
+
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import org.apache.poi.ss.usermodel.BuiltinFormats;
+import org.apache.poi.ss.usermodel.DataFormatter;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
+import org.apache.poi.xssf.model.SharedStringsTable;
+import org.apache.poi.xssf.model.StylesTable;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+//import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.xssfDataType;
+
+public class SheetHandler extends DefaultHandler {
+
+	enum xssfDataType {
+		BOOLEAN, ERROR, FORMULA, INLINE_STRING, SST_STRING, NUMBER, NULL// 정우 추가
+	}
+
+	/**
+	 * Table with the styles used for formatting
+	 */
+	private StylesTable stylesTable;
+
+	private ReadOnlySharedStringsTable sharedStringsTable;
+
+	/**
+	 * Where our text is going
+	 */
+	private final Sheet2ListHandler output;
+
+	// Set when V start element is seen
+	private boolean vIsOpen;
+	// Set when F start element is seen
+	private boolean fIsOpen;
+	// Set when an Inline String "is" is seen
+	private boolean isIsOpen;
+	// Set when a header/footer element is seen
+	private boolean hfIsOpen;
+
+	// Set when cell start element is seen;
+	// used when cell close element is seen.
+	private xssfDataType nextDataType;
+
+	// Used to format numeric cell values.
+	private short formatIndex;
+	private String formatString;
+	private final DataFormatter formatter;
+	
+	
+	//현재 cell or row의 위치
+	private String excelRowPosition;
+	private String excelCellPosition;
+	
+	private String cellRef;
+
+	private boolean formulasNotResults;
+
+	// Gathers characters as they are seen.
+	private StringBuffer value = new StringBuffer();
+	private StringBuffer formula = new StringBuffer();
+	private StringBuffer headerFooter = new StringBuffer();
+
+	private SharedStringsTable sst;
+	private String lastContents;
+	private boolean nextIsString;
+	
+	//정우추가
+	//private static final char[] EXCEL_CELL_NAMES = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
+	public static final List<Character> EXCEL_CELL_NAMES = Arrays.asList('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
+	
+	//이전에 처리 완료(데이터 담기 완료)한 row Index
+	private int proccessCompleteRowIndex = -1;
+	//이전에 처리 완료(데이터 담기 완료)한 Cell Index
+	private int proccessCompleteCellIndex = -1;
+
+	public SheetHandler(StylesTable styles, ReadOnlySharedStringsTable strings, Sheet2ListHandler sheet2ListHandler,
+                        DataFormatter dataFormatter, boolean formulasNotResults) {
+		this.stylesTable = styles;
+		this.sharedStringsTable = strings;
+		this.output = sheet2ListHandler;
+		this.formulasNotResults = formulasNotResults;
+		this.nextDataType = xssfDataType.NUMBER;
+		this.formatter = dataFormatter;
+	}
+
+	public SheetHandler(StylesTable styles, ReadOnlySharedStringsTable strings, Sheet2ListHandler sheet2ListHandler,
+                        boolean formulasNotResults) {
+		this(styles, strings, sheet2ListHandler, new DataFormatter(), formulasNotResults);
+	}
+
+	private boolean isTextTag(String name) {
+		if ("v".equals(name)) {
+			// Easy, normal v text tag
+			return true;
+		}
+		if ("inlineStr".equals(name)) {
+			// Easy inline string
+			return true;
+		}
+		if ("t".equals(name) && isIsOpen) {
+			// Inline string <is><t>...</t></is> pair
+			return true;
+		}
+		// It isn't a text tag
+		return false;
+	}
+
+	public void startElement(String url, String localName, String name, Attributes attributes) throws SAXException {
+
+		name = StringUtil.replaceOnce(name, "x:", "");
+
+		if (isTextTag(name)) {
+			vIsOpen = true;
+			// Clear contents cache
+			value.setLength(0);
+		} else if ("is".equals(name)) {
+			// Inline string outer tag
+			isIsOpen = true;
+		} else if ("f".equals(name)) {
+			// Clear contents cache
+			formula.setLength(0);
+
+			// Mark us as being a formula if not already
+			if (nextDataType == xssfDataType.NUMBER) {
+				nextDataType = xssfDataType.FORMULA;
+			}
+
+			// Decide where to get the formula string from
+			String type = attributes.getValue("t");
+			if (type != null && type.equals("shared")) {
+				// Is it the one that defines the shared, or uses it?
+				String ref = attributes.getValue("ref");
+				String si = attributes.getValue("si");
+
+				if (ref != null) {
+					// This one defines it
+					// TODO Save it somewhere
+					fIsOpen = true;
+				} else {
+					// This one uses a shared formula
+					// TODO Retrieve the shared formula and tweak it to
+					// match the current cell
+					if (formulasNotResults) {
+						System.err.println("Warning - shared formulas not yet supported!");
+					} else {
+						// It's a shared formula, so we can't get at the formula string yet
+						// However, they don't care about the formula string, so that's ok!
+					}
+				}
+			} else {
+				fIsOpen = true;
+			}
+		} else if ("oddHeader".equals(name) || "evenHeader".equals(name) || "firstHeader".equals(name)
+				|| "firstFooter".equals(name) || "oddFooter".equals(name) || "evenFooter".equals(name)) {
+			hfIsOpen = true;
+			// Clear contents cache
+			headerFooter.setLength(0);
+		} else if ("row".equals(name)) {
+			//현재 row 엑셀 위치(1부터 시작)
+			this.excelRowPosition = attributes.getValue("r");
+
+			//row 생성
+			output.startRow(this.excelRowPosition);
+			
+			//proccessCompleteCellIndex *초기화* - 'cell의 최초 시작 Index - 1' 값 담기
+			this.proccessCompleteCellIndex = output.getFirstColumn() - 1;			
+		
+		}
+		// c => cell
+		else if ("c".equals(name)) {
+			// Set up defaults.
+			this.nextDataType = xssfDataType.NUMBER;
+			this.formatIndex = -1;
+			this.formatString = null;
+			this.excelCellPosition = attributes.getValue("r");
+			
+			String cellType = attributes.getValue("t");
+			String cellStyleStr = attributes.getValue("s");
+
+			// cell 데이터 타입을 확인
+			if ("b".equals(cellType))
+				nextDataType = xssfDataType.BOOLEAN;
+			else if ("e".equals(cellType))
+				nextDataType = xssfDataType.ERROR;
+			else if ("inlineStr".equals(cellType))
+				nextDataType = xssfDataType.INLINE_STRING;
+			else if ("s".equals(cellType))
+				nextDataType = xssfDataType.SST_STRING;
+			else if ("str".equals(cellType))
+				nextDataType = xssfDataType.FORMULA;
+			else if (cellStyleStr != null) {
+				// Number, but almost certainly with a special style or format
+				int styleIndex = Integer.parseInt(cellStyleStr);
+				XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
+				if (style != null) {
+					this.formatIndex = style.getDataFormat();
+					this.formatString = style.getDataFormatString();
+					if (this.formatString == null)
+						this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
+				}
+			} else if (cellType == null) {// 정우 추가
+				nextDataType = xssfDataType.NULL;// 정우 추가
+			} 
+
+
+
+		} else if ("mergeCells".equals(name)) {			
+			output.findMerge();
+		} else if ("mergeCell".equals(name)) {		
+			for (int i = 0; i < attributes.getLength(); i++) {
+
+				CellRangeAddress cra = CellRangeAddress.valueOf(attributes.getValue("ref"));
+				output.addMergeInfo(cra.getFirstRow(), cra.getFirstColumn(), cra.getLastRow(), cra.getLastColumn());
+			}
+		} else if ("dimension".equals(name)) {
+			CellRangeAddress cra = CellRangeAddress.valueOf(attributes.getValue("ref"));
+			output.setFirstRow(cra.getFirstRow());
+			output.setFirstColumn(cra.getFirstColumn());
+			output.setLastRow(cra.getLastRow());
+			output.setLastColumn(cra.getLastColumn());
+			
+			//sheet 최초 시작시, 'row의 최초 시작 Index - 1' 값 담기
+			this.proccessCompleteRowIndex = cra.getFirstRow() - 1;
+			//sheet 최초 시작시, 'cell의 최초 시작 Index - 1' 값 담기
+			this.proccessCompleteCellIndex = cra.getFirstColumn() - 1;
+			
+		} else {
+
+		}
+	}
+
+	public void endElement(String uri, String localName, String name) throws SAXException {
+		name = StringUtil.replaceOnce(name, "x:", "");
+		
+		String thisStr = null;
+
+		// v => contents of a cell
+		if (isTextTag(name)) {
+			vIsOpen = false;
+
+			if (nextDataType != null) {
+				// Process the value contents as required, now we have it all
+				switch (nextDataType) {
+				case BOOLEAN:
+					char first = value.charAt(0);
+					thisStr = first == '0' ? Boolean.valueOf(false).toString() : Boolean.valueOf(true).toString();
+					break;
+
+				case ERROR:
+					thisStr = value.toString();
+					break;
+
+				case FORMULA:
+					if (formulasNotResults) {
+						thisStr = value.toString();
+					} else {
+						String fv = value.toString();
+
+						if (this.formatString != null) {
+							try {
+								// Try to use the value as a formattable number
+								double d = Double.parseDouble(fv);
+								thisStr = formatter.formatRawCellContents(d, this.formatIndex, this.formatString);
+							} catch (NumberFormatException e) {
+								// Formula is a String result not a Numeric one
+								thisStr = fv;
+							}
+						} else {
+							// No formating applied, just do raw value in all cases
+							thisStr = fv;
+						}
+					}
+					break;
+
+				case INLINE_STRING:
+					// TODO: Can these ever have formatting on them?
+					XSSFRichTextString rtsi = new XSSFRichTextString(value.toString());
+					thisStr = rtsi.toString();
+					break;
+				case SST_STRING:
+					String sstIndex = value.toString();
+					int idx = Integer.parseInt(sstIndex);
+//					XSSFRichTextString rtss = new XSSFRichTextString(sharedStringsTable.getItemAt(idx));
+					thisStr = sharedStringsTable.getItemAt(idx).toString();
+					break;
+				default:
+					XSSFRichTextString rtsi1 = new XSSFRichTextString(value.toString());
+					thisStr = rtsi1.toString();
+					break;
+				}
+			}
+			
+			/*현재 바라보고있는 row에서 [('이전의 cell Index(데이터 등록작업이 끝난 cell Index)' + 1) ~ ('현재 cell Index 전') 까지] cell 채우기*/
+			fillCellsToCurrentCellIndex();
+			
+			/*row에 'cell 데이터 추가'*/ 
+			output.cellDataAdd(thisStr);
+			
+			/*처리 완료(데이터 담기 완료)된 cell Index 담기*/
+			this.proccessCompleteCellIndex = getCurrentCellIndex();
+			
+		} else if ("c".equals(name)) {// 정우 추가
+			
+		} else if ("f".equals(name)) {
+			fIsOpen = false;
+		} else if ("is".equals(name)) {
+			isIsOpen = false;
+		} else if ("row".equals(name)) {
+			
+			/*현재 바라보고있는 sheet에서 [('이전의 row Index(데이터 등록작업이 끝난 row Index)' + 1) ~ ('현재 row Index' - 1) 까지] row 채우기 (현재 row 관련)*/
+			fillRowsToCurrentRowIndex();
+			
+			/*현재 row 데이터 추가전, 마지막 cell까지 다 채우기  (현재 cell 관련)*/
+			fillCellsToCurrentCellIndex(this.proccessCompleteCellIndex, output.getLastColumn() + 1);
+			
+			/*rows(수집 데이터)에 'row 데이터 추가'*/
+			output.endRow();
+			
+			/*처리 완료(데이터 담기 완료)된 Row Index 담기*/
+			this.proccessCompleteRowIndex = getCurrentRowIndex();
+			
+		} else if ("oddHeader".equals(name) || "evenHeader".equals(name) || "firstHeader".equals(name)) {
+			hfIsOpen = false;
+			output.headerFooter(headerFooter.toString(), true, name);
+		} else if ("oddFooter".equals(name) || "evenFooter".equals(name) || "firstFooter".equals(name)) {
+			hfIsOpen = false;
+			output.headerFooter(headerFooter.toString(), false, name);
+		} else if ("worksheet".equals(name)) {
+			output.endEvent();
+		} else {
+
+		}
+
+		nextDataType = null;
+	}
+
+
+	/**
+	 * Captures characters only if a suitable element is open. Originally was just
+	 * "v"; extended for inlineStr also.
+	 */
+	public void characters(char[] ch, int start, int length) throws SAXException {
+		if (vIsOpen) {
+			value.append(ch, start, length);
+		}
+		if (fIsOpen) {
+			formula.append(ch, start, length);
+		}
+		if (hfIsOpen) {
+			headerFooter.append(ch, start, length);
+		}
+	}
+	
+	/**
+	 * 정우추가(cell관련)
+	 * 현재 cell Index 가지고오기 
+	 *  - 기능 : excel cell 이름을 순번으로 바꾸기 ex)A -> 0, AA -> 27, ZZ -> 702
+	 */
+	public int getCurrentCellIndex () {
+		//최종 Index
+		int index = -1;
+		
+		//A3 -> A
+		String cellName = CommonUtil.getOnlyText(this.excelCellPosition);
+		
+		//지수
+		int quotient = 0;
+		
+		//맨 뒤에서 부터 한 문자씩 풀기
+		for (int i = cellName.length() - 1; i >= 0; i--) {
+			char c = cellName.charAt(i);
+			int c_index = SheetHandler.EXCEL_CELL_NAMES.indexOf(c) + 1;
+			index += (int) Math.pow(SheetHandler.EXCEL_CELL_NAMES.size(), quotient++) * c_index;
+		}
+		
+		return index;
+	}
+	/**
+	 * 정우추가(cell관련)
+	 * 현재 바라보고있는 row에서 [('이전의 cell Index(데이터 등록작업이 끝난 cell Index)' + 1) ~ ('현재 cell Index' - 1) 까지] cell 채우기
+	 */
+	public void fillCellsToCurrentCellIndex () {
+		fillCellsToCurrentCellIndex(this.proccessCompleteCellIndex, getCurrentCellIndex());
+	}
+	/**
+	 * 정우추가(cell관련)
+	 * 현재 바라보고있는 row에서 [('startIndex' + 1) ~ ('endIndex 전') 까지] cell 채우기
+	 */
+	public void fillCellsToCurrentCellIndex (int startIndex, int endIndex) {
+		if (endIndex - startIndex > 1) {
+			for (int i = startIndex + 1; i < endIndex; i++) {
+				output.getRow().add(null);
+			}
+		}
+	}
+		
+	/**
+	 * 정우추가(row관련)
+	 * 현재 row Index 가지고오기 
+	 */
+	public int getCurrentRowIndex () {
+		return (CommonUtil.parseInt((this.excelRowPosition)) - 1);
+	}
+	/**
+	 * 정우추가(row관련)
+	 * 현재 바라보고있는 sheet에서 [('이전의 row Index(데이터 등록작업이 끝난 row Index)' + 1) ~ ('현재 row Index' - 1) 까지] row 채우기
+	 */
+	public void fillRowsToCurrentRowIndex () {
+		fillRowsToCurrentRowIndex(this.proccessCompleteRowIndex, getCurrentRowIndex());
+	}
+	/**
+	 * 정우추가(row관련)
+	 * 현재 바라보고있는 sheet에서 [('startIndex' + 1) ~ ('endIndex 전') 까지] row 채우기
+	 */
+	public void fillRowsToCurrentRowIndex (int startIndex, int endIndex) {
+		if (endIndex - startIndex > 1) {
+			for (int i = startIndex + 1; i < endIndex; i++) {
+				List<Object> row = new ArrayList<Object>();
+				for (int j = output.getFirstColumn(); j <= output.getLastColumn(); j++) {
+					row.add(null);
+				}
+				output.getRows().add(row);
+				
+				//빈 Row Index 추가
+				output.getRowDataNoneExistIndexs().add((output.getRows().size() - 1));
+			}
+		}
+	}
+
+	/**
+	 * You need to implement this to handle the results of the sheet parsing.
+	 */
+	public interface SheetContentsHandler2 {
+		/** A row with the (zero based) row number has started */
+		public void startRow(String currentRowIndex) throws SAXException;
+
+		/** A row with the (zero based) row number has ended */
+		public void endRow() throws Exception;
+
+		/** A cell, with the given formatted value, was encountered */
+		public void cellDataAdd(String formattedValue);
+
+		/** A header or footer has been encountered */
+		public void headerFooter(String text, boolean isHeader, String tagName);
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/file/service/FileManagerService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/service/FileManagerService.java
@@ -0,0 +1,33 @@
+package com.takensoft.taken_bi_manager.common.file.service;
+
+import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile;
+import com.takensoft.taken_bi_manager.common.vo.CheckMessage;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface FileManagerService {
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 파일 정보 조회하기
+     */
+    public CustomeResultMap cmmnfileSelect(String fileManagerId) throws Exception;
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 멀티 파일 업로드
+     */
+    public CustomeResultMap cmmnfileUpload (MultipartFile[] files) throws Exception;
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 파일 삭제
+     */
+    public CustomeResultMap cmmnfileDelete(CmmnFile cmmnFile) throws Exception;
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/file/service/impl/FileManagerServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/service/impl/FileManagerServiceImpl.java
@@ -0,0 +1,138 @@
+package com.takensoft.taken_bi_manager.common.file.service.impl;
+
+import com.jcraft.jsch.ChannelSftp;
+import com.takensoft.taken_bi_manager.common.file.dao.FileDAO;
+import com.takensoft.taken_bi_manager.common.file.service.FileManagerService;
+import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile;
+import com.takensoft.taken_bi_manager.common.file.vo.FileManage;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.SftpUtil;
+import com.takensoft.taken_bi_manager.common.vo.CheckMessage;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode;
+import com.takensoft.taken_bi_manager.host.service.SftpService;
+import com.takensoft.taken_bi_manager.host.vo.ConnectionVO;
+import com.takensoft.taken_bi_manager.host.vo.SftpVO;
+import org.json.simple.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+
+@Transactional
+@Service
+public class FileManagerServiceImpl implements FileManagerService {
+
+    @Autowired
+    private FileDAO fileDAO;
+    @Autowired
+    private SftpService sftpService;
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 파일 정보 조회하기
+     */
+    @Override
+    public CustomeResultMap cmmnfileSelect(String fileManagerId) throws Exception{
+        CustomeResultMap resultMap = new CustomeResultMap();
+        resultMap.getResultData().put("cmmnFileList", fileDAO.cmmnfilesSelect(fileManagerId));
+
+        return resultMap;
+    }
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 멀티 파일 업로드
+     */
+    @Override
+    public CustomeResultMap cmmnfileUpload (MultipartFile[] files) throws Exception{
+        CustomeResultMap resultMap = new CustomeResultMap();
+
+        List<CmmnFile> fileList = new ArrayList<>();
+        FileManage fileManage = new FileManage();
+        fileManage.setFileManagerId(CommonUtil.getRandKey("MFILE"));
+        fileManage.setFileType(SystemCode.FileType.ALL_FILE);
+        fileManage.setContentType("dataset");
+        fileDAO.fileManagerInsert(fileManage);
+
+        for (MultipartFile file : files) {
+            try {
+                String originalFileName = file.getOriginalFilename();
+                String path = "C:\\Taken_BI_Manager\\cmmmfile\\";
+                String fileName = UUID.randomUUID().toString() + "_" + originalFileName;
+
+                File tempDir = new File(path);
+                if (!tempDir.exists()) {
+                    tempDir.mkdirs();
+                }
+
+                Path savePath = Paths.get(path + fileName);
+
+                // 파일 저장
+                Files.copy(file.getInputStream(), savePath);
+
+                CmmnFile fileInfo = new CmmnFile();
+                fileInfo.setFileId(CommonUtil.getRandKey("FILE"));
+                fileInfo.setName(originalFileName);
+                fileInfo.setMaskName(fileName);
+                fileInfo.setSize(file.getSize());
+                fileInfo.setContentType(null);
+                fileInfo.setFullPath(savePath.toString());
+                fileInfo.setExtention(fileName.substring(fileName.lastIndexOf(".") + 1));
+                fileInfo.setFileManagerId(fileManage.getFileManagerId());
+                fileDAO.fileInsert(fileInfo);
+
+                fileList.add(fileInfo);
+            } catch (Exception e) {
+                resultMap.getCheckMessage().setError("등록 실패 관리자에게 문의해주세요.");
+            }
+        }
+        resultMap.getResultData().put("fileManage", fileManage);
+        resultMap.getResultData().put("fileList", fileList);
+        resultMap.getCheckMessage().setMessage("success");
+
+        return resultMap;
+    }
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 파일 삭제
+     */
+    @Override
+    public CustomeResultMap cmmnfileDelete(CmmnFile cmmnFile) throws Exception{
+        CustomeResultMap resultMap = new CustomeResultMap();
+
+        try{
+            Path filePath = Paths.get(cmmnFile.getFullPath());
+            if (Files.exists(filePath)) {
+                Files.delete(filePath);
+
+            } else {
+
+            }
+
+            fileDAO.deleteCmmnFileToDataSetPost(cmmnFile.getFileManagerId());
+            fileDAO.deleteFileManagerToDataSetPost(cmmnFile.getFileManagerId());
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return resultMap;
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/file/vo/CmmnFile.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/CmmnFile.java
@@ -0,0 +1,48 @@
+package com.takensoft.taken_bi_manager.common.file.vo;
+
+import java.sql.Timestamp;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2023-12-28
+ * 
+ * 공통파일 관리 객체
+ */
+@Getter
+@Setter
+public class CmmnFile {
+
+	// 파일ID 
+	private String fileId;
+	
+	// 파일명
+	private String name;
+	
+	// 파일 마스크 먕
+	private String maskName;
+	
+	// 파일사이즈
+	private long size;
+	
+	// 콘텐츠 타입? 
+	private String contentType;
+	
+	// 파일 경로 
+	private String fullPath;
+	
+	// 파일 서브 경로 
+	private String subPath;
+	
+	// 파일 확장자
+	private String extention;
+	
+	// 생성일 
+	private Timestamp creatDt;
+	
+	// 파일매니저 ID
+	private String fileManagerId;
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileInfo.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileInfo.java
@@ -0,0 +1,182 @@
+package com.takensoft.taken_bi_manager.common.file.vo;
+
+import java.io.File;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @author 김성원
+ * @since 2024.01.12
+ * 
+ * 파일변환 관련 Object입니다. 
+ */
+@Getter
+@Setter
+@ToString
+public class FileInfo {
+
+	/**
+	 * 기본 생성자
+	 */
+	public FileInfo() {}
+
+	/**
+	 * 생성자(파일)
+	 */
+	public FileInfo(File file) {
+
+		this.file = file;
+		this.path = file.getPath();
+		this.fileName = file.getName();
+
+	}
+	
+	/**
+	 * 생성자(파일, 확장자)
+	 */
+	public FileInfo(File file, String fileFome) {
+		this.file = file;
+		this.fileFom = fileFome;
+	}
+	
+	
+	/**
+	 * 생성자(파일및, 확장자, 구분자)
+	 */
+	public FileInfo(File file, String fileFome, String suffix) {
+		this.file = file;
+		this.fileFom = fileFome;
+		this.suffix = suffix;
+		
+	}
+
+	/*
+	* 생성자 (fileInfo)
+	 */
+	public FileInfo(FileInfo fileInfo){
+		this.file = fileInfo.getFile();
+		this.path = fileInfo.getPath();
+		this.fileName = fileInfo.getFileName();
+		this.extension = fileInfo.getExtension();
+		this.type = fileInfo.getType();
+		this.lastData = fileInfo.isLastData();
+		this.datasetAfter = fileInfo.isDatasetAfter();
+		this.datasetId = fileInfo.getDatasetId();
+		this.rowDataColumnIndex = fileInfo.getRowDataColumnIndex();
+		this.startRowIndex = fileInfo.getStartRowIndex();
+		this.startCellIndex = fileInfo.getStartCellIndex();
+		this.streOptn = fileInfo.isStreOptn();
+		this.fileFom = fileInfo.getFileFom();
+		this.suffix = fileInfo.getSuffix();
+		this.addDay = fileInfo.getAddDay();
+		this.addMonth = fileInfo.getAddMonth();
+		this.delimiter = fileInfo.getDelimiter();
+		this.viewMode = fileInfo.isViewMode();
+	}
+
+	/** 
+	 * 관리 파일
+	 */
+	private File file;
+
+	/**
+	 *  파일 경로
+	 */
+	private String path;
+
+	/**
+	 *  파일 명
+	 */
+	private String fileName;
+
+	/**
+	 * 파일 확장자
+	 */
+	private String extension;
+
+	/**
+	 *  파일 수집 타입 : 전체, 포함, 특정
+	 */
+	private String type;	
+	
+	/**
+	 *  마지막  파일 옵션
+	 */
+	private boolean lastData;
+	
+	/**
+	 *  데이터셋 업데이트 보다 최신 파일만 선택 옵션
+	 */
+	private boolean datasetAfter;	
+	
+	/**
+	 *  데이터셋 아이디
+	 */
+	private String datasetId;
+	
+	/**
+	 * 데이터(행,열)의 컬럼인 Row의 Index
+	 */
+	private int rowDataColumnIndex;
+	
+	/**
+	 * 데이터(행,열)의 Row 시작 Index
+	 */
+	private int startRowIndex;
+	
+	/**
+	 * 데이터(행,열)의 Cell 시작 Index
+	 */
+	private int startCellIndex;
+	
+	/**
+	 *  파일 쓰기 옵션
+	 */
+	private boolean streOptn = false;
+	
+	/**
+	 *   파일 타입 : xlsx, xls, csv, text, json, xml ... 
+	 */
+	private String fileFom = "xlsx";
+	
+	/**
+	 *  날짜시간 형식
+	 */
+	private String suffix = "_YYYYMMDDHHmmss";
+	
+	/**
+	 * 일계산
+	 */
+	private int addDay = 0;
+
+	/**
+	 * 월계산 (하석형 추가)
+	 */
+	private int addMonth = 0;
+
+	/**
+	 * file 구분자
+	 */
+	private String delimiter = ",";
+
+	/**
+	 * 파일 미리보기 옵션
+	 */
+	private boolean viewMode;
+
+	//추가 dataset_post_id
+	private String dataset_post_id;
+
+
+
+
+	public void fileToFileInfo(File file) {
+
+		this.file = file;
+		this.path = file.getPath();
+		this.fileName = file.getName();
+
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileManage.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileManage.java
@@ -0,0 +1,132 @@
+package com.takensoft.taken_bi_manager.common.file.vo;
+
+
+import java.sql.Timestamp;
+import java.util.Date;
+
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.FileType;
+
+import lombok.Getter;
+import lombok.Setter;
+
+
+
+/**
+ * @author 김성원
+ * @since 2023.12.29
+ * 
+ * File 관리 Domain 입니다.
+ */
+@Getter
+@Setter
+public class FileManage {
+	
+	public FileManage() {};
+	
+	public FileManage(String fileManagerId) {
+		this.fileManagerId = fileManagerId;
+	};
+	
+	public FileManage(long fileSeq) {
+		this.fileId = fileSeq;
+	};
+	
+	public FileManage(String fileManagerId, long fileSeq) {
+		this.fileManagerId = fileManagerId;
+		this.fileId = fileSeq;
+	};
+	
+	public FileManage(FileType fileType) {
+		this.fileType = fileType;
+	};
+	
+	public FileManage(FileType fileType, String contentType) {
+		this.fileType = fileType;
+		this.contentType = contentType;
+	};
+	
+	public FileManage(String fileManagerId, FileType fileType) {
+		this.fileManagerId = fileManagerId;
+		this.fileType = fileType;
+	};
+	
+	public FileManage(String fileManagerId, FileType fileType, String contentType) {
+		this.fileManagerId = fileManagerId;
+		this.fileType = fileType;
+		this.contentType = contentType;
+	};
+
+	/**
+	 * 파일 관리 아이디
+	 */
+	private String fileManagerId;
+	
+	/**
+	 * 파일 타입
+	 */
+	private FileType fileType;
+	
+	/**
+	 * 등록한 컨텐츠 타입
+	 */
+	private String contentType;
+	
+	/**
+	 * 파일 SEQ
+	 */
+	private long fileId;
+
+	/**
+	 * 파일명
+	 */
+	private String name;
+
+	/**
+	 * 마스크 파일명
+	 */
+	private String maskName;
+
+	/**
+	 * 파일 사이즈.
+	 */
+	private long size;
+
+	/**
+	 * 서브 디렉토리.
+	 */
+	private String subDir;
+	
+	/**
+	 * 데이터 셋 파일 절대 경로
+	 */
+	private String fullDir;
+
+	/**
+	 * 파일 확장자.
+	 */
+	private String extension;
+
+	/**
+	 * 파일 생성일.
+	 */
+	private Date createDate;
+	
+	
+	
+	
+	
+	/**
+	 * file 관련 메세지
+	 */
+	//private CheckMessage checkMessage = new CheckMessage();	
+
+//	public CheckMessage getCheckMessage() {
+//		return checkMessage;
+//	}
+//
+//	public void setCheckMessage(CheckMessage checkMessage) {
+//		this.checkMessage = checkMessage;
+//	}
+
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/file/web/FileManagerController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/web/FileManagerController.java
@@ -0,0 +1,66 @@
+package com.takensoft.taken_bi_manager.common.file.web;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.file.service.FileManagerService;
+import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/fileManage")
+public class FileManagerController {
+    private final FileManagerService fileManagerService;
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.24
+     *
+     * 파일 정보 조회하기
+     */
+    @PostMapping("/read")
+    public CustomeResultMap cmmnfileUpload (@RequestParam("files") MultipartFile[] files) throws Exception {
+        CustomeResultMap map = fileManagerService.cmmnfileUpload(files);
+        return map;
+    }
+
+    /**
+     * @author 박민혁
+     * @since 2024.04.25
+     *
+     * 파일 정보 다운로드
+     */
+    @PostMapping("/download")
+    public void cmmnfileDownload (@RequestBody HashMap<String ,Object> params, HttpServletResponse response) throws Exception {
+        CustomeResultMap map = fileManagerService.cmmnfileSelect((String) params.get("fileManagerId"));
+        File downloadFile = null;
+        List<CmmnFile> cmmnFiles = (List<CmmnFile>) map.getResultData().get("cmmnFileList");
+        if(cmmnFiles != null){
+            String filePath = cmmnFiles.get(0).getFullPath();
+            downloadFile = new File(filePath);
+
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(cmmnFiles.get(0).getName(), "UTF-8") + "\"");
+            response.setHeader("Content-Transfer-Encoding", "binary");
+
+            try (OutputStream out = response.getOutputStream(); FileInputStream fis = new FileInputStream(downloadFile)) {
+                byte[] buffer = new byte[1024];
+                int bytesRead;
+                while ((bytesRead = fis.read(buffer)) != -1) {
+                    out.write(buffer, 0, bytesRead);
+                }
+            }
+        }
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/schedule/dao/ScheduleDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/dao/ScheduleDAO.java
@@ -0,0 +1,68 @@
+package com.takensoft.taken_bi_manager.common.schedule.dao;
+
+import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SearchVO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.HashMap;
+import java.util.List;
+
+@Mapper
+public interface ScheduleDAO {
+	/**
+	 * @author 김성원
+	 * @since 2021.01.24
+	 *
+	 * 스케줄 등록
+	 */
+	 public int conflictInsertSchedule (Schedule schedule) throws Exception;
+
+	/**
+	 * @author 김성원
+	 * @since 2021.01.24
+	 *
+	 * 스케줄 목록 조회
+	 */
+	public List<Schedule> selectScheduleList (SearchVO searchVO) throws Exception;
+
+	/**
+	 * @author 김성원
+	 * @since 2021.01.24
+	 *
+	 * 스케줄 목록 개수 조회
+	 */
+	public int selectScheduleListCount (SearchVO searchVO) throws Exception;
+
+	/**
+	 * @author 김성원
+	 * @since 2021.01.24
+	 *
+	 * 스케줄 상세 조회
+	 */
+	public Schedule selectSchedule (String id) throws Exception;
+
+	/**
+	 * @author 박정하
+	 * @since 2024.10.04
+	 *
+	 * Diagram Id로 Schedule Id 구하기
+	 */
+	public String selectScheduleIdRead(String diagramId) throws Exception;
+
+	/**
+	 * @author 박정하
+	 * @since 2024.10.04
+	 *
+	 * 스케줄 정보 삭제
+	 */
+	public int deleteSchedule(String schdulId) throws Exception;
+
+	/**
+	 * @author 박정하
+	 * @since 2024.10.04
+	 *
+	 * 스케줄 상태 변경
+	 */
+	public int scheduleSttusChange(HashMap<String, Object> params) throws Exception;
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/schedule/service/ScheduleService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/service/ScheduleService.java
@@ -0,0 +1,47 @@
+package com.takensoft.taken_bi_manager.common.schedule.service;
+
+import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SearchVO;
+
+public interface ScheduleService {
+    /**
+     * @author 김성원
+     * @since 2021.01.24
+     *
+     * 스케줄 등록
+     */
+    public int conflictInsertSchedule (Schedule schedule) throws Exception;
+
+    /**
+     * @author 김성원
+     * @since 2021.01.24
+     *
+     * 스케줄 목록 조회
+     */
+    public CustomeResultMap selectScheduleList (SearchVO searchVO) throws Exception;
+
+    /**
+     * @author 김성원
+     * @since 2021.01.24
+     *
+     * 스케줄 상세 조회
+     */
+    public Schedule selectSchedule (Schedule schedule) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.10.04
+     *
+     * 스케줄 정보 삭제
+     */
+    public CustomeResultMap deleteSchedule(String schdulId) throws Exception;
+
+    /**
+     * @author 박정하
+     * @since 2024.10.04
+     *
+     * 스케줄 상태 변경
+     */
+    public CustomeResultMap scheduleSttusChange(String schdulId, String schdulSttus) throws Exception;
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/schedule/service/impl/ScheduleServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/service/impl/ScheduleServiceImpl.java
@@ -0,0 +1,91 @@
+package com.takensoft.taken_bi_manager.common.schedule.service.impl;
+
+import com.takensoft.taken_bi_manager.common.schedule.dao.ScheduleDAO;
+import com.takensoft.taken_bi_manager.common.schedule.service.ScheduleService;
+import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SearchVO;
+import com.takensoft.taken_bi_manager.jobs.service.JobService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+
+@Service
+public class ScheduleServiceImpl implements ScheduleService {
+    @Autowired
+    private ScheduleDAO scheduleDAO;
+
+    @Autowired
+    private JobService jobService;
+
+    /*
+     * 스케줄 등록
+     */
+    @Override
+    public int conflictInsertSchedule(Schedule schedule) throws Exception {
+        String group_id = jobService.insertJobGroup(schedule.getJobGroup()).getResultData().get("group_id").toString();
+        schedule.setGroup_id(group_id);
+        if(StringUtil.isEmpty(schedule.getSchdul_id())){
+            schedule.setSchdul_id(CommonUtil.getRandKey("SCHEDULE"));
+            schedule.setCreatId(CommonUtil.getLoginUserId());
+        }else{
+            schedule.setUpdtId(CommonUtil.getLoginUserId());
+        }
+        return scheduleDAO.conflictInsertSchedule(schedule);
+    }
+
+    /*
+     * 스케줄 목록 조회
+     */
+    @Override
+    public CustomeResultMap selectScheduleList(SearchVO searchVO) throws Exception {
+        int totalRows = scheduleDAO.selectScheduleListCount(searchVO);
+        searchVO.setTotalRows(totalRows);
+        CustomeResultMap map = new CustomeResultMap();
+        map.getResultData().put("scheduleList", scheduleDAO.selectScheduleList(searchVO));
+        map.getResultData().put("searchVO", searchVO);
+        return map;
+    }
+
+    /*
+     * 스케줄 상세 조회
+     */
+    @Override
+    public Schedule selectSchedule(Schedule schedule) throws Exception {
+        Schedule sc = scheduleDAO.selectSchedule(schedule.getSchdul_id());
+        sc.setJobGroup(jobService.selectJobGroup(sc.getGroup_id()));
+        return sc;
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.10.04
+     *
+     * 스케줄 정보 삭제
+     */
+    @Override
+    public CustomeResultMap deleteSchedule(String schdulId) throws Exception {
+        CustomeResultMap result = new CustomeResultMap();
+        result.getResultData().put("updateResult", scheduleDAO.deleteSchedule(schdulId));
+        return result;
+    }
+
+    /**
+     * @author 박정하
+     * @since 2024.10.04
+     *
+     * 스케줄 상태 변경
+     */
+    @Override
+    public CustomeResultMap scheduleSttusChange(String schdulId, String schdulSttus) throws Exception {
+        CustomeResultMap result = new CustomeResultMap();
+        HashMap<String, Object> params = new HashMap<>();
+        params.put("schdulId", schdulId);
+        params.put("schdulSttus", schdulSttus);
+        result.getResultData().put("updateResult", scheduleDAO.scheduleSttusChange(params));
+        return result;
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/schedule/vo/Schedule.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/vo/Schedule.java
@@ -0,0 +1,86 @@
+package com.takensoft.taken_bi_manager.common.schedule.vo;
+
+import com.takensoft.taken_bi_manager.jobs.vo.JobGroup;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+import java.util.*;
+
+/**
+ * @author 김성원 
+ * @since 2021.12.28
+ * 
+ * 스케줄러  Domain 입니다.
+ */
+@Getter
+@Setter
+public class Schedule implements Serializable {
+	// 시리얼 버전
+	private static final long serialVersionUID = 1L;
+
+	// 스케줄러 고유 ID
+	private String schdul_id;
+
+	// 스케줄러 그룹 id
+	private String group_id;
+
+	// 스케줄러 명
+	private String sj;
+
+	// 스케줄러 명
+	private String dc;
+
+	// 스케쥴링
+	private String cron;
+
+	// cron 스케쥴링 한글
+	private String cron_chrctr;
+	
+	// 스케쥴링 상태
+	private String schdul_sttus = "run";
+
+	// 생성일
+	private Timestamp creatDt;
+
+	// 생성자ID
+	private String creatId;
+
+	// 수정일
+	private Timestamp updtDt;
+
+	// 수정자 ID
+	private String updtId;
+	
+	/**
+	 * 주기적 인지 아닌지
+	 * true: 주기적
+	 * false: 일시적
+	 */
+	private boolean cycle_at;
+	
+	/**
+	 * 사용여부(삭제 여부)
+	 */
+	private boolean use_at = true;
+	
+	/**
+	 * 에러 존재 유무
+	 */
+	private boolean error_at = false;
+
+	private boolean isUsehighClassOption = false;
+
+	private JobGroup jobGroup;
+	
+	/**
+	 * 에러 로그 리스트
+	 */
+	private List<ScheduleLog> ScheduleLogs;
+
+	public Schedule(){
+		ScheduleLogs = new ArrayList<>();
+		jobGroup = new JobGroup();
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/schedule/vo/ScheduleLog.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/vo/ScheduleLog.java
@@ -0,0 +1,66 @@
+package com.takensoft.taken_bi_manager.common.schedule.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * @author 김성원 
+ * @since 2024 02.26
+ * 
+ * 스케줄러  Domain 상세정보 입니다.
+ */
+@Getter
+@Setter
+public class ScheduleLog implements Serializable {
+
+	/**
+	 * 시리얼 버전
+	 */	
+	private static final long serialVersionUID = 1L;
+	
+	/**
+	 * 스케줄러 고유 ID 
+	 */	
+	private String schdulId;
+	
+	
+	/**
+	 * 실행일
+	 */	
+	private String executDe;
+	
+	
+	/**
+	 * 스케쥴링 상태
+	 */	
+	private String schdulSttus;
+	
+	
+	/**
+	 * 로그정보
+	 */	
+	private String logInfo;
+	
+	
+	/**
+	 *  Job 의 타입코드입니다.(공통코드 참조예정)
+	 */
+	private String jobCode;
+	
+	
+	/**
+	 *  실행 순서
+	 */
+	private int indx;
+	
+		
+	/**
+	 *  오류 사항 확인 유무
+	 */
+	private boolean success;
+
+	
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/Background_style.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/Background_style.java
@@ -0,0 +1,45 @@
+package com.takensoft.taken_bi_manager.common.stylesheet.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.02.27
+ *
+ * 백그라운드 옵션
+ */
+
+@Getter
+@Setter
+public class Background_style {
+
+    // 스타일 시트 ID
+    private String stylesheet_id;
+
+    // 스타일 인덱스
+    private int indx;
+
+    // 백그라운드 타입
+    private boolean image_at;
+
+    // 백그라운드 타입
+    private boolean imageType;
+
+    // 색상
+    private String background_color;
+
+    // 투명도
+    private int opacity;
+
+    // 이미지 url
+    private String imageUrl;
+
+    public Background_style(){
+        this.image_at = false;
+        this.opacity = 0;
+        this.background_color = "#ffffff";
+        this.imageType = false;
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/BorderStyle.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/BorderStyle.java
@@ -0,0 +1,43 @@
+package com.takensoft.taken_bi_manager.common.stylesheet.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 김성원
+ * @since 2024.02.27
+ *
+ * 보더 옵션 관련 스타일 시트
+ */
+@Getter
+@Setter
+public class BorderStyle {
+
+    // 스타일 시트 ID
+    private String stylesheet_id;
+
+    // 스타일 인덱스
+    private int indx;
+
+    // 보더 스타일
+    private String border_style;
+
+    private String border_color;
+
+    // 스타일 아이템
+    private List<BorderStyleItm> border_item;
+
+    public BorderStyle(){
+        this.border_style = "none";
+        this.border_color = "#8e8e8e";
+        border_item = new ArrayList<>();
+        border_item.add(new BorderStyleItm());
+        border_item.add(new BorderStyleItm());
+        border_item.add(new BorderStyleItm());
+        border_item.add(new BorderStyleItm());
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/BorderStyleItm.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/BorderStyleItm.java
@@ -0,0 +1,20 @@
+package com.takensoft.taken_bi_manager.common.stylesheet.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class BorderStyleItm {
+
+    // 보더 두께
+    private int border_width;
+
+    // 보더 라운드
+    private int border_radius;
+
+    public BorderStyleItm(){
+        this.border_width = 2;
+        this.border_radius = 0;
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/FontStyle.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/FontStyle.java
@@ -0,0 +1,62 @@
+package com.takensoft.taken_bi_manager.common.stylesheet.vo;
+
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.02.27
+ *
+ * 폰트 옵션 관리 VO 입니다.
+ */
+@Getter
+@Setter
+public class FontStyle {
+
+    // 스타일 시트 ID
+    private String stylesheet_id;
+
+    // 스타일 인덱스
+    private int indx;
+
+    // 폰트
+    private String font;
+
+    // 폰트 사이즈
+    private double font_size;
+
+    // 폰트 컬러
+    private String font_color;
+
+    // 볼드 유무
+    private boolean bold_at;
+
+    // 기울기 유무
+    private boolean italic_at;
+
+    // 언더라인 유무
+    private boolean underline_at;
+
+    // 가운데라인 유무
+    private boolean line_through_at;
+
+    // 폰트 정렬(좌우)
+    private String text_align;
+
+    // 폰트 정렬(상하)
+    private String vertical_align;
+
+    public FontStyle(){
+        this.font = "Pretendard";
+        this.font_size = 11;
+        this.font_color = "#000000";
+        this.bold_at = false;
+        this.italic_at = false;
+        this.underline_at = false;
+        this.line_through_at = false;
+        this.text_align = "left";
+        this.vertical_align = "middle";
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/PaddingAndMargin.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/PaddingAndMargin.java
@@ -0,0 +1,58 @@
+package com.takensoft.taken_bi_manager.common.stylesheet.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.02.27
+ *
+ * 패딩 마진 옵션
+ */
+@Getter
+@Setter
+public class PaddingAndMargin {
+
+    // 스타일 시트 ID
+    private String stylesheet_id;
+
+    // 스타일 인덱스
+    private int indx;
+
+    // 마진
+    private double margin_top;
+
+    // 패딩
+    private double padding_top;
+
+    // 마진
+    private double margin_left;
+
+    // 패딩
+    private double padding_left;
+
+    // 마진
+    private double margin_right;
+
+    // 패딩
+    private double padding_right;
+
+    // 마진
+    private double margin_bottom;
+
+    // 패딩
+    private double padding_bottom;
+
+    // 생성자
+    public PaddingAndMargin(){
+        this.margin_top = 0;
+        this.padding_top = 0;
+        this.margin_left = 0;
+        this.padding_left = 0;
+        this.margin_right = 0;
+        this.padding_right = 0;
+        this.margin_bottom = 0;
+        this.padding_bottom = 0;
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/StyleSheet.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/StyleSheet.java
@@ -0,0 +1,44 @@
+package com.takensoft.taken_bi_manager.common.stylesheet.vo;
+
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 김성원
+ * @since 2024.02.27
+ *
+ * 레이아웃및 스타일 관련 처리 데이터 VO
+ */
+@Getter
+@Setter
+public class StyleSheet {
+
+    // 스타일 시트 아이디
+    private String stylesheet_id;
+
+    // 폰트 스타일 리스트
+    private FontStyle fontStyle;
+
+    // 보더 스타일
+    private BorderStyle borderStyle;
+
+    // 백그라운드 스타일
+    private Background_style background_style;
+
+    // 패딩
+    private PaddingAndMargin paddingAndMargin;
+
+    // 생성자
+    public StyleSheet(){
+       // this.fontStyleList = new FontStyle<>();
+       // this.borderStyle = new ArrayList<>();
+        //this.BorderStyle.add(new BorderStyle());
+       // this.background_style = new ArrayList<>();
+       // this.paddingAndMargin = new ArrayList<>();
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/AsyncUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/AsyncUtil.java
@@ -0,0 +1,54 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+
+import com.takensoft.taken_bi_manager.common.util.reflection.ReflectionUtil;
+
+import java.util.concurrent.Callable;
+
+/*
+public class AsyncUtil implements Runnable {
+*/
+public class AsyncUtil implements Callable<Object> {
+
+	String classFilePath, packageName, className, methodName;
+	Object[] paramValues;
+	Class<?>[] paramTypes;
+	
+	public AsyncUtil(String classFilePath, String packageName, String className, String methodName, Object[] paramValues, Class<?>[] paramTypes) {
+		this.classFilePath = classFilePath;
+		this.packageName = packageName;
+		this.className = className;
+		this.methodName = methodName;
+		this.paramValues = paramValues;
+		this.paramTypes = paramTypes;
+	}
+	
+	public AsyncUtil(String packageName, String className, String methodName, Object[] paramValues, Class<?>[] paramTypes) {
+		this.packageName = packageName;
+		this.className = className;
+		this.methodName = methodName;
+		this.paramValues = paramValues;
+		this.paramTypes = paramTypes;
+	}
+	
+	@Override
+	public Object call() throws Exception {
+		try {
+			// 객체 생성 및 메소드 실행
+			Object clazz = ReflectionUtil.classAndBeanLoad(classFilePath, (packageName + "." + className));
+			ReflectionUtil.invokeByMethodName(clazz, methodName, paramValues, paramTypes);
+			return null;
+		} catch (Exception e) {
+			throw new Exception(e);
+		}
+	}
+/*
+    public void run () {
+		//객체 생성
+		Object clazz = ReflectionUtil.classAndBeanLoad(classFilePath, (packageName + "." + className));
+		//메서드 실행
+		ReflectionUtil.invokeByMethodName(clazz, methodName, paramValues, paramTypes);
+    }
+*/
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/AuthUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/AuthUtil.java
@@ -0,0 +1,100 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jakarta.servlet.http.HttpSession;
+
+import java.util.HashMap;
+
+public class AuthUtil {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AuthUtil.class);
+
+    //Session에 등록된 Login User ID Key
+    public static final String LOGIN_USER_SESSION = "loginUsers";
+
+    //중복 로그인가능 여부
+    public static final boolean IS_POSSIBLE_DUPLICATION_LOGIN = false;
+
+    //Session Max 시간(초)
+    public static final int SESSION_MAX_TIME = 60*60*6;//6시간
+
+    public static HashMap<String, Object> getLoginUser () {
+        try {
+            //현재 client의 HttpSession 조회
+            HttpSession session = CommonUtil.getHttpSession(false);
+            if(session == null || session.getAttribute(LOGIN_USER_SESSION) == null || ((HashMap<String, Object>) session.getAttribute(LOGIN_USER_SESSION)).get("user_id") == null) {
+                return null;
+            }else {
+                return (HashMap<String, Object>) session.getAttribute(LOGIN_USER_SESSION);
+            }
+        } catch(NullPointerException e) {
+            LOGGER.error(e.toString());
+
+         //   e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static String getLoginUserId () {
+        HashMap<String, Object> user = getLoginUser();
+        if (user != null) {
+            return (String) user.get("user_id");
+        } else {
+            return null;
+        }
+    }
+    public static HashMap<String, Object> getKey () {
+        try {
+            //현재 client의 HttpSession 조회
+            HttpSession session = CommonUtil.getHttpSession(true);
+            if(session == null || session.getAttribute("key") == null || ((HashMap<String, Object>) session.getAttribute("key")).get("salt") == null) {
+                return null;
+            }else {
+                return ((HashMap<String, Object>) session.getAttribute("key"));
+            }
+        } catch(NullPointerException e) {
+            LOGGER.error(e.toString());
+            return null;
+        }
+    }
+
+    public static String getKeySaltKey () {
+        HashMap<String, Object> key = getKey();
+        if (key != null ) {
+            if(key.get("salt") != null) {
+                return key.get("salt").toString();
+            }else {
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+    public static String getKeyIvtKey () {
+        HashMap<String, Object> key = getKey();
+        if (key != null ) {
+            if(key != null) {
+                return key.get("iv").toString();
+            }else {
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+    public static String getKeyENC_KEY () {
+        HashMap<String, Object> key = getKey();
+        if (key != null ) {
+            if(key.get("ENC_KEY") != null) {
+                return key.get("ENC_KEY").toString();
+            }else{
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/CommonUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/CommonUtil.java
@@ -0,0 +1,803 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpSession;
+
+import org.json.XML;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.takensoft.taken_bi_manager.user.member.vo.Member;
+
+public class CommonUtil {
+
+	/**
+     * @author 최정우
+     * @since 2019.12.11
+     * 
+     * 데이터의 표준화 사용 유무 
+     */
+	private static boolean IS_USE_STANDARD = true;
+	
+	public static void setIsUseStandard (boolean isUseStandard) {
+		IS_USE_STANDARD = isUseStandard;
+	}
+	
+	public static boolean getIsUseStandard () {
+		return IS_USE_STANDARD;
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 빈 문자열 검사
+     */
+    public static boolean isNull(Object obj) {
+        return obj == null;
+    }
+    
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * string to int check
+     */
+    public static boolean isInt (String text) {
+		try {
+			Integer.parseInt(text);
+			return true;
+		} catch(NumberFormatException e) {
+			return false;
+		}
+	}
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * string to int check
+     */
+    public static boolean isLong (String text) {
+		try {
+			Long.parseLong(text);
+			return true;
+		} catch(NumberFormatException e) {
+			return false;
+		}
+	}
+	
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * string to double check
+     */
+	public static boolean isDouble (String text) {
+		try {
+			Double.parseDouble(text);
+			return true;
+		} catch (NumberFormatException e) {
+			return false;
+		} catch (Exception e) {
+			return false;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * object to int
+     */
+	public static int parseInt (Object obj) {
+		try {
+			return Integer.parseInt(obj.toString());
+		} catch(Exception e) {
+			return 0;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * string to int
+     */
+	public static int parseInt (String text) {
+		try {
+			return Integer.parseInt(text);
+		} catch(NumberFormatException e) {
+			return 0;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * int to double 
+     */
+	public static long parseLong (int number) {
+		try {
+			return (long) number;
+		} catch(Exception e) {
+			return 0;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * object to double 
+     */
+	public static long parseLong (String text) {
+		try {
+			return Long.parseLong(text);
+		} catch(Exception e) {
+			return 0;
+		}
+	}
+
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * object to double 
+     */
+	public static long parseLong (Object obj) {
+		try {
+			if (obj instanceof Integer) {
+				return (long) obj;
+			} else {
+				return Long.parseLong(obj.toString());
+			}
+		} catch(Exception e) {
+			return 0;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * int to double 
+     */
+	public static double parseDouble (int number) {
+		try {
+			return (double) number;
+		} catch(Exception e) {
+			return 0.0;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * object to double 
+     */
+	public static double parseDouble (String text) {
+		try {
+			return Double.parseDouble(text);
+		} catch(Exception e) {
+			return 0.0;
+		}
+	}
+
+	/**
+     * @author 최정우
+     * @since 2020.01.08
+     * 
+     * object to double 
+     */
+	public static double parseDouble (Object obj) {
+		try {
+			if (obj instanceof Integer) {
+				return (double) obj;
+			} else {
+				return Double.parseDouble(obj.toString());
+			}
+		} catch(Exception e) {
+			return 0.0;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열의 모든 공백 제거
+     */
+	public static String allTrim(String text) {
+		return text.replaceAll("\\p{Z}", "");
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열 앞뒤 공백 제거후, 문자열 사이에 존재하는 공백을 한개의 공백으로 치환
+     * ex) " abcd     efg    hijk   " => "abcd efg hijk" 
+     */
+	public static String normalizeSpace(String text) {
+		return text.trim().replaceAll("\\s+", " ");
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 숫자 빼고 모든 문자 제거
+     */
+	public static String getOnlyNumber (String text) {
+		return text.replaceAll("[^0-9]", "");
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자 빼고 모든 숫자 제거
+     */
+	public static String getOnlyText (String text) {
+		return text.replaceAll("[0-9]", "");
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 특정 문자열 개수 check
+     */
+	public static int getWordCount (String text, String word) {
+		int size = 0;
+		int fromIndex = -1;
+		while ((fromIndex = text.indexOf(word, fromIndex + 1)) >= 0) {
+			size++;
+		}
+		return size;
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열 to Date문자열
+     */
+	public static boolean isDate (String text) {
+		if (StringUtil.isEmpty(text) == true || StringUtil.isEmpty(getOnlyNumber(text)) == true || getOnlyNumber(text).length() < 6) {
+			return false;
+		}
+		
+		//공백을 제외한 문자얻기, 대문자로 치환
+		String newText = allTrim(text).toUpperCase();
+		
+		try {
+			//문자열의 날짜 패턴 생성
+			String pattern = createDatePattern(newText);
+			if (pattern == null) {
+				return false;
+			}
+		
+			SimpleDateFormat newPattern = new SimpleDateFormat(pattern);
+			//문자열 날짜 형태로 변환
+			newPattern.parse(newText);
+			return true;
+		} catch (Exception e) {
+			//e.printStackTrace();
+			return false;
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열 to Date문자열
+     */
+	public static String parseDateText (String text) {
+		if (StringUtil.isEmpty(text) == true || StringUtil.isEmpty(getOnlyNumber(text)) == true || getOnlyNumber(text).length() < 6) {
+			return null;
+		}
+		
+		//공백을 제외한 문자얻기, 대문자로 치환
+		String newText = allTrim(text).toUpperCase();
+		
+		//문자열의 날짜 패턴 생성 
+		String pattern = createDatePattern(newText);
+		if (pattern == null) {
+			return null;
+		}
+
+		Date date = null;
+		String dateText = null;
+		try {
+			SimpleDateFormat newPattern = new SimpleDateFormat(pattern);
+			
+			//문자열 날짜 형태로 변환
+			date = newPattern.parse(newText);
+			
+			//DB에 저장할 날짜 패턴
+			SimpleDateFormat defalutPattern = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+			dateText = defalutPattern.format(date);
+		} catch (Exception e) {
+			//e.printStackTrace();
+		}
+		return dateText;
+	}
+	
+	public static <T> List<T> mapToList (Map<?, T> map) {
+		List<T> items = new ArrayList<T>();
+		
+		if (map != null) {
+			for(Map.Entry<?, T> item : map.entrySet()) {
+				items.add(item.getValue());
+	        }
+		}
+		
+		return items;
+	}
+	
+	public static Map objectToMap(Object obj) {
+		if (obj != null) {
+			try {
+				return (Map) obj;
+			} catch (Exception e) {
+				return new HashMap();
+			}
+		} else {
+			return new HashMap();
+		}
+	}
+	
+	
+	/*
+	 * 시간 타입
+	 * PM, AM
+	 */
+	public final static List<String> TIME_TYPES = Arrays.asList(new String[] {"AM", "PM", "오전", "오후"});
+	
+	/*
+	 * 날짜 포맷 패턴's
+	 */
+	public final static List<Character> DATE_PATTERNS = Arrays.asList(new Character[] {'y', 'M', 'd', 'H', 'm', 's'});
+	
+	/*
+	 * 날짜 포맷 패턴's의 최대 문자열 수
+	 */
+	public final static List<Integer> DATE_PATTERNS_MAX_LENGTH = Arrays.asList(new Integer[] {4, 2, 2, 2, 2, 2});
+	
+	/**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열의 날짜 패턴 생성
+     */
+	public static String createDatePattern (String date) {
+		
+		List<Character> DATE_PATTERNS = Arrays.asList(new Character[] {'y', 'M', 'd', 'H', 'm', 's'});
+		
+		//시간 표기가 (0~12 -> AM, PM사용)인지 (0~23)인지 확인 후, 날짜 포맷 패턴's에 있는 시간 패턴 변경
+		int timeTypeFindIndex = -1;
+		for (int i = 0; i < TIME_TYPES.size(); i++) {
+			//("AM", "PM", "오전", "오후" 중 1개)가 포함된 단어가 있는지 확인, Index 위치를 담기(없으면 -1)
+			if ((timeTypeFindIndex = date.indexOf(TIME_TYPES.get(i))) > -1) {
+				//문자열에 포함된 ("AM", "PM", "오전", "오후" 중 1개) 삭제
+				date = date.replaceAll(TIME_TYPES.get(i), "");
+				//시간 패턴 변경 [H -> h]
+				DATE_PATTERNS.set(3, 'h');
+				break;
+			}
+		}
+		
+		//숫자를 뺀 나머지 문자열 가지고오기 ex) "2020.08.03" -> ".."
+		//숫자를 뺀 나머지 문자열 가지고오기 ex) "2020.08.03 19:20:21" -> "..::"
+		final char[] separators = getOnlyText(date).toCharArray();
+		
+	
+		
+		//사용할 최대 패턴 수
+		int maxPatterSize = 0;
+		if (DATE_PATTERNS.size() <= separators.length) {
+			maxPatterSize = DATE_PATTERNS.size();
+		} else {
+			maxPatterSize = separators.length;
+		}
+		
+		//구분자별 Index 위치's (사용할 최대 패턴 수 + 시작점:-1, 종료점:date문자열의 최종 길이)
+		List<Integer> sizeByPatterns = new ArrayList<Integer>();
+		
+		
+		//구분자 별 Index 위치 파악 후, 앞에 있는 문자열의 수 찾은 후, 추가 (마지막 패턴 뒤에 있는 문자열을 따로 처리해줘야함)
+		int fromIndex = -1;
+		for (int i = 0; i < maxPatterSize; i++) {
+			//구분자
+			char separator = separators[i];
+			
+			//'현재 찾은 위치' : 이전에 찾은 위치(찾기 시작할 위치 => fromIndex) + 1 부터 찾기 시작함
+			int currentFromIndex = date.indexOf(separator, fromIndex + 1);
+			
+			//현재 패턴의 문자열 수 = '현재 찾은 위치' - '이전에 찾은 위치' - 1 [추가]
+			sizeByPatterns.add(currentFromIndex - fromIndex - 1);			
+			
+			//'현재 찾은 위치'는 '이전에 찾은 위치'가 됨
+			fromIndex = currentFromIndex;
+		}
+		//마지막 패턴 뒤에 있는 문자열 = '문자열의 길이' - '마지막에 찾은 위치(이전에 찾은 위치)' - 1 [추가]
+		sizeByPatterns.add(date.length() - fromIndex - 1);
+		
+		
+		//패턴을 담을 변수
+		StringBuilder pattern = new StringBuilder();
+		
+		//DATE_PATTERS 순서 대로, 각 구분자 별 Index 위치 크기만큼 문자열에 패턴 삽입 + 구분자 삽입
+		//마지막 전까지만 for문 돌림
+		for (int i = 0, patternIndex = 0; i < sizeByPatterns.size() && patternIndex < DATE_PATTERNS.size(); i++, patternIndex++) {
+			
+			//패턴 추가
+			int usingSize = 0;
+			for (int j = 0; j < sizeByPatterns.get(i); j++) {
+				if (j >= usingSize + DATE_PATTERNS_MAX_LENGTH.get(patternIndex)) {
+					usingSize += DATE_PATTERNS_MAX_LENGTH.get(patternIndex++);
+					
+					/*단 한개의 패턴이라도 '최대 문자열 수'를 넘어서면 -> '날짜 아님'*/
+					if (i >= sizeByPatterns.size() || patternIndex >= DATE_PATTERNS.size()) {
+						return null;
+					}
+				}
+				
+				pattern.append(DATE_PATTERNS.get(patternIndex));
+			}
+			
+			//날짜 구분자 추가 (마지막 구분자까지만) 
+			if (i < separators.length) {
+				pattern.append(separators[i]);
+			}
+			
+			
+		}
+		
+		if (timeTypeFindIndex > -1) {
+			pattern.insert(timeTypeFindIndex, 'a');
+		}
+		
+		if(!(pattern.toString().equals("-") || pattern.toString().equals("/") || pattern.toString().equals("."))){
+			pattern = null;
+		}
+		
+		return pattern.toString();
+	}
+	
+	
+	/**
+     * @author 최정우
+     * @since 2020.01.26
+     * 
+     * ping 체크
+     */
+	public static boolean pingCheck (String ip) {
+		InetAddress inetAddress;
+		try {
+			inetAddress = InetAddress.getByName(ip);
+			return inetAddress.isReachable(1000);
+		} catch (UnknownHostException e) {
+			return false;
+		} catch (IOException e) {
+			return false;
+		} catch (Exception e) {
+			return false;
+		}
+	}
+	
+	/**
+     * @author 김성원
+     * @since 2024.01.04
+     * 
+     * 접속 체크 (ip + port)
+     */
+	public static boolean linkCheck(String ip, int port) {
+		Socket socket = new Socket();
+		try {
+			socket.connect(new InetSocketAddress(ip, port), 1000);
+			boolean isConnect = socket.isConnected();
+			socket.close();
+			return isConnect;
+		} catch (UnknownHostException e) {
+			return false;
+		} catch (IOException e) {
+			return false;
+		} catch (Exception e) {
+			return false;
+		}
+	}	
+	
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.12.09
+	 * 
+	 * 데이터 셋 목록 Convert LinkedHashMap<String, Object> to List<String>
+	 */
+	public static List<List<Object>> rowDataMapToList (List<LinkedHashMap<String, Object>> rowMapData) throws Exception {
+		List<List<Object>> rowData = new ArrayList<List<Object>>();
+		for (int i = 0; i < rowMapData.size(); i++) {
+			List<Object> row = new ArrayList<Object>();
+			LinkedHashMap<String, Object> mapdata = rowMapData.get(i);
+
+	        for( String key : mapdata.keySet() ){
+	        	if (mapdata.get(key) == null) {
+	        		row.add("");//null값 대체
+	        	} else {
+	        		row.add(mapdata.get(key).toString());
+	        	}
+	        }
+	        rowData.add(row);
+		}
+		return rowData;
+	}
+
+	/**
+	 * @author 최정우
+	 * @since 2019.12.09
+	 *
+	 * 데이터 셋 목록 Convert LinkedHashMap<String, Object> to List<String>
+	 */
+	public static List<List<Object>> rowDataMapToListOnject (List<LinkedHashMap<String, Object>> rowMapData) throws Exception {
+		List<List<Object>> rowData = new ArrayList<List<Object>>();
+		for (int i = 0; i < rowMapData.size(); i++) {
+			List<Object> row = new ArrayList<Object>();
+			LinkedHashMap<String, Object> mapdata = rowMapData.get(i);
+			for( String key : mapdata.keySet() ){
+				if (mapdata.get(key) == null) {
+					row.add(null);//null값 대체
+				} else {
+					row.add(mapdata.get(key));
+				}
+			}
+			rowData.add(row);
+		}
+		return rowData;
+	}
+	
+	/**
+	 * @author 최정우
+	 * @since 2020.01.26
+	 *
+	 * 현재 client의 HttpServletRequest 조회
+	 */
+	public static HttpServletRequest getHttpServletRequest () {
+		try {
+			ServletRequestAttributes servletRequestAttribute = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
+			return servletRequestAttribute.getRequest();
+		} catch (NullPointerException e) {
+			return null;
+		}
+	}
+	
+	
+	/**
+	 * @author 최정우
+	 * @since 2020.01.26
+	 *
+	 * 현재 client의 HttpSession 조회
+	 */
+	public static HttpSession getHttpSession (boolean create) {
+		try {
+			HttpServletRequest request = getHttpServletRequest();
+			if (request != null) {
+				return request.getSession(create);
+			} else {
+				return null;
+			}
+		} catch (NullPointerException e) {
+			return null;
+		}
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.10
+	 *
+	 * 사용자 세션 정보 조회
+	 */
+	public static HashMap<String, Object> getHttpSessionMember () {
+		try {
+			HttpServletRequest request = getHttpServletRequest();
+			if(request.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) {				
+				return (HashMap<String, Object>)request.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION);	
+			}else {
+				return null;
+			}	
+		} catch (NullPointerException e) {
+			return null;
+		}
+	}
+	
+	/**
+	 * @author 최정우
+	 * @since 2020.01.26
+	 *
+	 * HttpServletRequest를 활용한 Client IP 가지고오기
+	 * Header의 X-FORWARDED-FOR 값을 통해 IP 조회, 만약 Header에 X-FORWARDED-FOR가 없으면 getRemoteAddr() 이걸로 조회
+	 */
+	public static String getClientIp () {
+		try {
+			HttpServletRequest request = getHttpServletRequest();
+			if (null != request.getHeader("X-FORWARDED-FOR")) {
+				return request.getHeader("X-FORWARDED-FOR");
+			} else {
+				return request.getRemoteAddr();
+			}
+		} catch (NullPointerException e) {
+			return null;
+		}
+	}
+	
+
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.12.09
+	 * 
+	 * JSONObject to Map<String, Object>
+	 */
+	public static Map<String, Object> jsonObjectToMap( JSONObject jsonObj ) {
+        Map<String, Object> map = null;
+        try {
+            map = new ObjectMapper().readValue(jsonObj.toJSONString(), Map.class) ;
+            	
+        } catch (JsonParseException e) {
+            e.printStackTrace();
+        } catch (JsonMappingException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return map;
+    }
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.12.09
+	 * 
+	 * JSONObject to List<Map<String, Object>>
+	 */
+	public static List<Map<String, Object>> jsonArrayToMap( JSONArray jsonObj ) {
+		List<Map<String, Object>> map = null;
+        try {
+            map = new ObjectMapper().readValue(jsonObj.toJSONString(), new TypeReference<List<Map<String, Object>>>(){}) ;
+            	
+        } catch (JsonParseException e) {
+            e.printStackTrace();
+        } catch (JsonMappingException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return map;
+    }
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.12.09
+	 * 
+	 * xmlStr to JsonStr
+	 */
+	public static String xmlStrToJsonStr(String xmlStr) throws Exception {
+ 	    org.json.JSONObject jObject = XML.toJSONObject(xmlStr);
+ 	    ObjectMapper mapper = new ObjectMapper();
+ 	    mapper.enable(SerializationFeature.INDENT_OUTPUT);
+ 	    Object json = mapper.readValue(jObject.toString(), Object.class);
+ 	    String output = mapper.writeValueAsString(json);
+ 	    return output;
+	}
+	
+	
+	
+	/**
+     * @author 김성원 
+	 * @since 2024.01.10
+     * 
+     * 데이터베이스 난수생성
+     */
+	public static String getRandKey(String prifix) {
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+		long timeInMillis =System.currentTimeMillis();
+		Date timeInDate = new Date(timeInMillis);		
+		return prifix+"_"+sdf.format(timeInDate)+UUID.randomUUID().toString().substring(0,5);
+	}
+	
+	/**
+     * @author 김성원 
+	 * @since 2024.01.10
+     * 
+     * 로그인된 사용자 ID 조회
+     */
+	public static String getLoginUserId() {
+		 String resultId = "";
+		 HashMap<String, Object> LoginUserInfo = new HashMap<>();
+		 HttpServletRequest request = CommonUtil.getHttpServletRequest();
+		 HttpSession session = request.getSession(false);
+		 
+		 if(session != null &&  session.getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) {
+			 LoginUserInfo = (HashMap<String, Object>)session.getAttribute(AuthUtil.LOGIN_USER_SESSION);	
+			 resultId = LoginUserInfo.get("user_id").toString();
+		 }
+		 
+		return resultId;
+	}
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.10
+	 *
+	 * 로그인된 사용자 ID 조회
+	 */
+	public static String getLoginUserDeptCode() {
+		String resultId = "";
+		HashMap<String, Object> LoginUserInfo = new HashMap<>();
+		HttpServletRequest request = CommonUtil.getHttpServletRequest();
+		HttpSession session = request.getSession(false);
+
+		if(session != null &&  session.getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) {
+			LoginUserInfo = (HashMap<String, Object>)session.getAttribute(AuthUtil.LOGIN_USER_SESSION);
+			Object deptCodeObj = LoginUserInfo.get("dept_code");
+			resultId = (deptCodeObj != null) ? deptCodeObj.toString() : null; // null일 때 null 반환
+		}
+
+		return resultId;
+	}
+	
+	/**
+     * @author 김성원 
+	 * @since 2024.01.10
+     * 
+     * 로그인된 사용자 권한 조회
+     */
+	public static List<String> getLoginUserAuth() {
+		 List<String> authList = new  ArrayList<>();
+		 HashMap<String, Object> LoginUserInfo = new HashMap<>();
+		 HttpServletRequest request = CommonUtil.getHttpServletRequest();
+		 HttpSession session = request.getSession(false);		 
+		 if(session != null &&  session.getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) {
+			 LoginUserInfo = (HashMap<String, Object>)session.getAttribute(AuthUtil.LOGIN_USER_SESSION);	
+			 authList = (List<String>)LoginUserInfo.get("user_auth");			
+		 }		 
+		return authList;
+	}
+
+	
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/CryptoUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/CryptoUtil.java
@@ -0,0 +1,221 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.Base64.Decoder;
+import java.util.Base64.Encoder;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.encrypt.AesBytesEncryptor;
+import org.springframework.security.crypto.factory.PasswordEncoderFactories;
+import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+/**
+ * @author 김성원
+ * @since 2024.01.02
+ * 
+ * 암호화 관련 클래스 
+ */
+public class CryptoUtil {
+	
+
+	private final static String encoderKey = "bcrypt";
+	private final static String secret = "takenbmsc!@#";
+	private final static String salt = "70726574657374";
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 기본 단방향 엔코드 생성
+	 */
+	public static PasswordEncoder createDelegatingPasswordEncoder() {	
+		Map<String, PasswordEncoder> encoders = new HashMap<>();
+		encoders.put(encoderKey, new BCryptPasswordEncoder());	
+		return new DelegatingPasswordEncoder(encoderKey, encoders);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커스텀 key기반의  단방향 엔코드 생성
+	 */
+	public static PasswordEncoder createDelegatingPasswordEncoder(String key) {	
+		Map<String, PasswordEncoder> encoders = new HashMap<>();
+		encoders.put(key, new BCryptPasswordEncoder());	
+		return new DelegatingPasswordEncoder(key, encoders);
+	}
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 기본 단방향 암호화 
+	 */
+	public static String PasswordEncoder(String data) {	
+		
+		PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
+		Encoder encoder = Base64.getEncoder();       
+		return  encoder.encodeToString(passwordEncoder.encode(data).getBytes(StandardCharsets.UTF_8)) ;
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커스텀 key기반의  단방향 암호화 
+	 */
+	public static String PasswordEncoder(String key , String data) {	
+		
+		if(StringUtil.isEmpty(data)) {
+			return data;
+		}
+		
+		PasswordEncoder passwordEncoder = createDelegatingPasswordEncoder(key);
+		
+		return passwordEncoder.encode(data);
+	}
+		
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 단방향 암호화 비교구문 
+	 */
+	public static boolean passwordMatch(String data, String checkData) {
+		
+		PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
+		Decoder decoder = Base64.getDecoder();		
+		return passwordEncoder.matches(data,new String(decoder.decode(checkData), StandardCharsets.UTF_8) );
+		
+	}
+	
+
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 기본 key, salt 기반의 양방향 암호화 객체 생성  
+	 */
+	public static AesBytesEncryptor aesBytesEncryptor() {
+	    return new AesBytesEncryptor("232323", salt);
+	}
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커스텀 key, salt 기반의 양방향 암호화 객체 생성  
+	 */
+	public static AesBytesEncryptor aesBytesEncryptor(String key, String salt) {
+	    return new AesBytesEncryptor(key, salt);
+	    
+	}	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 기본 key, salt 기반의 양방향 암호화 
+	 */
+	public static String encryptData(String data) {
+		if(StringUtil.isEmpty(data)) {
+			return data;
+		}
+		AesBytesEncryptor  bytesEncryptor =  aesBytesEncryptor();
+        byte[] encrypt = bytesEncryptor.encrypt(data.getBytes(StandardCharsets.UTF_8));
+        Encoder encoder = Base64.getEncoder();       
+        return encoder.encodeToString(encrypt); 
+    }
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커스텀  key, salt 기반의 양방향 암호화 
+	 */
+	public static String encryptData(String key, String salt, String data) {
+		if(StringUtil.isEmpty(data)) {
+			return data;
+		}
+		AesBytesEncryptor  bytesEncryptor =  aesBytesEncryptor(key, salt);
+        byte[] encrypt = bytesEncryptor.encrypt(data.getBytes(StandardCharsets.UTF_8));
+        Encoder encoder = Base64.getEncoder();       
+        return encoder.encodeToString(encrypt); 
+    }
+	
+	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 기본 key, salt 기반의 양방향 복호화
+	 */
+	public static String decryptData(String data) {
+		if(StringUtil.isEmpty(data)) {
+			return data;
+		}
+		AesBytesEncryptor  bytesEncryptor =  aesBytesEncryptor();
+		Decoder decoder = Base64.getDecoder();		
+        byte[] decrypt = bytesEncryptor.decrypt(decoder.decode(data));
+        return new String(decrypt, StandardCharsets.UTF_8);
+    }	
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 커스텀 key, salt 기반의 양방향 복호화
+	 */
+	public static String decryptData(String key, String salt, String data) {
+		if(StringUtil.isEmpty(data)) {
+			return data;
+		}
+		AesBytesEncryptor  bytesEncryptor =  aesBytesEncryptor(key, salt);
+		Decoder decoder = Base64.getDecoder();		
+        byte[] decrypt = bytesEncryptor.decrypt(decoder.decode(data));
+        return new String(decrypt, StandardCharsets.UTF_8);
+    }	
+	
+	 
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 	* 바이트 스트링 변환
+	*/
+	public static String byteArrayToString(byte[] bytes) {
+        StringBuilder sb = new StringBuilder();
+        for (byte abyte :bytes){
+            sb.append(abyte);
+            sb.append(" ");
+        }
+        return sb.toString();
+    }
+	
+	/**
+	 * @author 김성원
+	 * @since 2024.01.09
+	 * 
+	 * 스트링 바이트 변환
+	*/
+	public static byte[] stringToByteArray(String byteString) {
+        String[] split = byteString.split("\\s");
+        ByteBuffer buffer = ByteBuffer.allocate(split.length);
+        for (String s : split) {
+            buffer.put((byte) Integer.parseInt(s));
+        }
+        return buffer.array();
+    }
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/HTTPUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/HTTPUtil.java
@@ -0,0 +1,344 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam;
+
+
+/**
+ * @author 최정우
+ * @since 2020.07.21
+ *
+ * 데이터 수집 - HTTP통신 관련 Util 입니다.
+ */
+public class HTTPUtil {
+
+	/**
+	 * @author 최정우
+	 * @throws Exception
+	 * @since 2020.07.21
+	 *
+	 * [GET] HTTP 통신
+	 */
+	public synchronized String HttpGetConnection (String urlText, Map<String, Object> parameter) {
+		StringBuffer response = new StringBuffer();
+
+		URL url = null;
+		try {
+			if (parameter.isEmpty() == false) {
+				urlText += "?" + createUrlQuery(parameter, "UTF-8");
+			}
+			url = new URL(urlText);
+		} catch (MalformedURLException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		HttpURLConnection httpCon = null;
+		try {
+
+			/* Connection */
+			httpCon = (HttpURLConnection) url.openConnection();
+			httpCon.setRequestMethod("GET");
+			httpCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36");
+			httpCon.setConnectTimeout(1000 * 60);//http통신 최대 커넥션 시간(1분)
+			httpCon.setReadTimeout(1000 * 60);//http통신 커넥션 이후, 데이터를 받아오는데 걸리는 최대 시간(1분)
+			httpCon.setDoInput(true);//받아올 데이터가 있을 때, 사용
+
+			//HTTP Request 결과 코드
+			int responseCode = httpCon.getResponseCode();
+			if (responseCode == 200) {
+				//Response 결과 데이터 받기
+				BufferedReader input = new BufferedReader(new InputStreamReader(httpCon.getInputStream(), "UTF-8"));
+
+				//Response 결과 데이터를 문자열로 만들기
+				String result = null;
+				while ((result = input.readLine()) != null) {
+					response.append(result);
+				}
+
+				//InputStream, BufferedReader 종료
+				input.close();
+
+				//HTTP Connection 종료
+				httpCon.disconnect();
+
+			} else {
+
+			}
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		//문자열로된 Response 결과 return
+		return response.toString();
+	}
+
+	/**
+	 * @author 최정우
+	 * @throws Exception
+	 * @since 2020.07.21
+	 *
+	 * [POST] HTTP 통신
+	 */
+	public synchronized String HttpPostConnection (String urlText, Map<String, Object> parameter) {
+		StringBuffer response = new StringBuffer();
+
+		URL url = null;
+		try {
+			url = new URL(urlText);
+		} catch (MalformedURLException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		HttpURLConnection httpCon = null;
+		try {
+			/* Connection */
+			httpCon = (HttpURLConnection) url.openConnection();
+			httpCon.setRequestMethod("POST");
+			httpCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36");
+			httpCon.setConnectTimeout(1000 * 60);//http통신 최대 커넥션 시간(1분)
+			httpCon.setReadTimeout(1000 * 60);//http통신 커넥션 이후, 데이터를 받아오는데 걸리는 최대 시간(1분)
+			httpCon.setDoInput(true);//받아올 데이터가 있을 때, 사용
+
+			//보낼 파라메터 데이터가 있을 때
+			if (parameter.isEmpty() == false) {
+				String dataQuery = createUrlQuery(parameter, null);
+
+				httpCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//보낼 데이터의 형태
+				httpCon.setRequestProperty("Content-Length", String.valueOf(dataQuery.length()));
+				httpCon.setDoOutput(true);
+
+				DataOutputStream wr = new DataOutputStream(httpCon.getOutputStream());
+				wr.writeBytes(dataQuery);
+				wr.flush();
+				wr.close();
+			}
+
+			//HTTP Request 결과 코드
+			int responseCode = httpCon.getResponseCode();
+			if (responseCode == 200) {
+				//Response 결과 데이터 받기
+				BufferedReader input = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
+
+				//Response 결과 데이터를 문자열로 만들기
+				String result = null;
+				while ((result = input.readLine()) != null) {
+					response.append(result);
+				}
+
+				//InputStream, BufferedReader 종료
+				input.close();
+
+				//HTTP Connection 종료
+				httpCon.disconnect();
+			} else {
+
+			}
+
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		//문자열로된 Response 결과 return
+		return response.toString();
+	}
+
+	/**
+	 * @author 최정우
+	 * @throws Exception
+	 * @since 2020.07.21
+	 *
+	 * 파라메터 데이터를 HTTP통신을 위한 문자열로 변환시켜주는 메서드
+	 * Map -> String
+	 */
+	public String createUrlQuery (Map<String, Object> parameter, String incoding) {
+		if (parameter.isEmpty() == true) {
+			return "";
+		} else {
+			StringBuilder query = new StringBuilder();
+			for(Map.Entry<String,Object> param : parameter.entrySet()) {
+				try {
+					if(query.length() > 0) {
+						query.append('&');
+					}
+
+					if (StringUtil.isEmpty(incoding) == true) {
+						query.append(param.getKey());
+						query.append('=');
+						query.append(param.getValue());
+					} else {
+						query.append(URLEncoder.encode(param.getKey(), incoding));
+						query.append('=');
+						query.append(URLEncoder.encode(String.valueOf(param.getValue()), incoding));
+					}
+
+				} catch (UnsupportedEncodingException e) {
+					e.printStackTrace();
+				}
+			}
+
+			return query.toString();
+		}
+	}
+
+	/**
+	 * @author 최정우
+	 * @throws Exception
+	 * @since 2020.07.21
+	 *
+	 * [GET] HTTP 통신
+	 */
+	public synchronized String HttpGetConnectionApi (String urlText,  List<ApiParam>  parameter) {
+		StringBuffer response = new StringBuffer();
+
+		URL url = null;
+		try {
+			if (parameter.isEmpty() == false) {
+				urlText += "?" + createUrlQueryApi(parameter, "UTF-8");
+			}
+			url = new URL(urlText);
+		} catch (MalformedURLException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		HttpURLConnection httpCon = null;
+		try {
+
+			/* Connection */
+			httpCon = (HttpURLConnection) url.openConnection();
+			httpCon.setRequestMethod("GET");
+			httpCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36");
+			httpCon.setConnectTimeout(1000 * 60);//http통신 최대 커넥션 시간(1분)
+			httpCon.setReadTimeout(1000 * 60);//http통신 커넥션 이후, 데이터를 받아오는데 걸리는 최대 시간(1분)
+			httpCon.setDoInput(true);//받아올 데이터가 있을 때, 사용
+
+			//HTTP Request 결과 코드
+			int responseCode = httpCon.getResponseCode();
+			if (responseCode == 200) {
+				//Response 결과 데이터 받기
+				BufferedReader input = new BufferedReader(new InputStreamReader(httpCon.getInputStream(), "UTF-8"));
+
+				//Response 결과 데이터를 문자열로 만들기
+				String result = null;
+				while ((result = input.readLine()) != null) {
+					response.append(result);
+				}
+
+				//InputStream, BufferedReader 종료
+				input.close();
+
+				//HTTP Connection 종료
+				httpCon.disconnect();
+
+			} else {
+
+			}
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		//문자열로된 Response 결과 return
+		return response.toString();
+	}
+
+	/**
+	 * @author 최정우
+	 * @throws Exception
+	 * @since 2020.07.21
+	 *
+	 * 파라메터 데이터를 HTTP통신을 위한 문자열로 변환시켜주는 메서드
+	 * Map -> String
+	 */
+	public String createUrlQueryApi (List<ApiParam> parameter, String incoding) {
+		if (parameter.isEmpty() == true) {
+			return "";
+		} else {
+
+
+			StringBuilder query = new StringBuilder();
+			for(ApiParam param : parameter) {
+				try {
+
+					// 날짜 변경 처리
+					if(param.isDateForm() == true) {
+						param.setValue(getTodayaddMonth(param.getValue().toString(), param.getAddMonth()));
+					}
+
+
+					if(query.length() > 0) {
+						query.append('&');
+					}
+
+					if (StringUtil.isEmpty(incoding) == true) {
+						query.append(param.getKey());
+						query.append('=');
+						query.append(param.getValue());
+					} else {
+						query.append(URLEncoder.encode(param.getKey(), incoding));
+						query.append('=');
+						if(param.isDisableDecode()) {
+							query.append(param.getValue());
+						}else {
+							query.append(URLEncoder.encode(String.valueOf(param.getValue()), incoding));
+						}
+
+					}
+
+
+				} catch (UnsupportedEncodingException e) {
+					e.printStackTrace();
+				}
+			}
+
+			return query.toString();
+		}
+	}
+	/**
+	 * @author 김성원
+	 * @since 2019.11.13
+	 *
+	 * 현재날짜(년,월,일)에 특정 개월수 + -
+	 */
+	public static String getTodayaddMonth(String pattern, int month) {
+		String defaultPattern = "yyyy-MM-dd";
+		// 수정된 코드
+		if (pattern == null || pattern.isEmpty()) {
+			pattern = defaultPattern;
+		}
+
+		SimpleDateFormat dateFormat = null;
+		try {
+			dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		} catch (Exception e) {
+			dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA);
+		}
+		Timestamp timestamp = new Timestamp(System.currentTimeMillis());
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.MONTH, month);
+
+		return dateFormat.format(cal.getTime());
+	}
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/PaginationSupport.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/PaginationSupport.java
@@ -0,0 +1,32 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+/**
+ * 페이징 지원 객체 입니다.
+ *
+ * @author 서영석
+ * @since 2023.10.24
+ */
+public class PaginationSupport {
+
+    //한 페이지당 보여질 데이터 개수 (Default)
+    private final static int PER_PAGE = 10;
+
+    /**
+     * @author 서영석
+     * @since 2023.10.24
+     * 내용 : PostgreSQL 데이터
+     */
+    public static int pagingRowIndexForPostgreSql (int currentPage) {
+        return pagingRowIndexForPostgreSql(currentPage, PER_PAGE);
+    }
+    /**
+     * @author 서영석
+     * @since 2023.10.24
+     * 내용 : PostgreSQL 데이터
+     */
+    public static int pagingRowIndexForPostgreSql (int currentPage, int perPage) {
+        int startIndex = 0;
+        startIndex = (currentPage - 1) * perPage;
+        return startIndex;
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/SesssionEventListener.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/SesssionEventListener.java
@@ -0,0 +1,281 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jakarta.servlet.annotation.WebListener;
+import jakarta.servlet.http.HttpSession;
+import jakarta.servlet.http.HttpSessionEvent;
+import jakarta.servlet.http.HttpSessionListener;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author 서영석
+ * @since 2023.05.31
+ *
+ * Custom session 저장소를 만들어 놓고
+ * Tomcat이 관리하는 session 생성 또는 소멸시, 발생하는 이벤트를 활용하여 (HttpSessionListener를 통해 이벤트를 받을 수 있음)
+ * Custom session 저장소에 추가, 삭제를 통해
+ * session을 적절히 controll 하기위한 목적을 가진 Class 입니다.
+ */
+@WebListener
+public class SesssionEventListener implements HttpSessionListener {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SesssionEventListener.class);
+
+    //싱글턴패턴 사용을 위한 클래스변수
+    public static SesssionEventListener sesssionEventListener = null;
+
+    //싱글턴패턴으로 객체 생성 후 리턴.
+    public static synchronized SesssionEventListener getInstance() {
+        if(sesssionEventListener == null) {
+            sesssionEventListener = new SesssionEventListener();
+        }
+        return sesssionEventListener;
+    }
+
+    /**
+     * Custom session 저장소 (tomcat이 관리하고있는 실제 session저장소는 아님) 목록
+     * ConcurrentHashMap을 사용하는 이유 :
+     * HashMap은 Thread Safe 하지 않기 때문에 싱글턴 패턴에서 해당 session 저장소를 사용하기 위해서는 Thread Safe 한 ConcurrentHashMap를 사용
+     * HashTable도 Thread Safe 하지만, 읽기 쓰기 둘다 한개의 Thread만 접근 가능함
+     * ConcurrentHashMap은 쓰기에서한 한개의 Tread만 접근 가능하도록 해놓음 (읽기는 여러개의 쓰레드에서 동시 접근 가능)
+     */
+    private static final Map<String, HttpSession> sessions = new ConcurrentHashMap<>();
+
+    /**
+     * @author 서영석
+     * @since 2023.05.31
+     *
+     * @param userId : 사용자(회원) ID
+     *
+     * userId와 동일한 로그인 session을 가진 session ID 목록 조회
+     */
+    public synchronized static List<String> duplicationLoginSessionIdSelectListByUserId (String userId) {
+        List<String> result = new ArrayList<>();
+        try {
+            //Custom session 저장소에서 session ID는 다르지만 userId가 같은게 존재하는지 확인
+            for (String key : sessions.keySet()) {
+                HttpSession session = sessions.get(key);
+                if (session == null || session.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) {
+                    //세션이 존재하고, 로그인 정보가 없으면 continue;
+                    continue;
+                } else {
+                    //로그인 정보가 있으면 -> 중복 확인
+                    HashMap<String, Object> loginUser = (HashMap<String, Object>) session.getAttribute(AuthUtil.LOGIN_USER_SESSION);
+                    String loginUserId = (String) loginUser.get("user_id");
+
+                    /** 사용자(회원) ID와 동일한 로그인 정보 일 시 -> add **/
+                    if (userId.equals(loginUserId) == true) {
+                        result.add(session.getId());
+                    } else {
+                        //동일한 로그인 정보가 아니면 -> continue;
+                        continue;
+                    }
+                }
+            }
+        } catch (NullPointerException e) {
+            LOGGER.error(e.toString());
+        }
+
+        return result;
+    }
+
+
+    /**
+     * @author 서영석
+     * @since 2023.05.31
+     *
+     * 현재 client의 정보와 중복된 로그인 session ID 목록 조회
+     *
+     * 현재 User의 세션과 Custom session 저장소에 저장된 session 중
+     * session ID는 다르지만 userId가 같은 session List return
+     */
+    public synchronized static List<String> duplicationLoginSessionIdSelectList () {
+        List<String> result = new ArrayList<>();
+
+        try {
+            //현재 사용자의 session
+            HttpSession currentUserSession = CommonUtil.getHttpSession(false);
+            //현재 사용자의 session이 존재하고, 로그인 정보가 있을 때
+            if (currentUserSession != null && currentUserSession.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) {
+                //현재 사용자의 로그인 정보
+                HashMap<String, Object> currentLoginUser = (HashMap<String, Object>) currentUserSession.getAttribute(AuthUtil.LOGIN_USER_SESSION);
+                String currentLoginUserId = (String) currentLoginUser.get("user_id");
+
+                //Custom session 저장소에서 session ID는 다르지만 userId가 같은게 존재하는지 확인
+                for (String key : sessions.keySet()) {
+                    HttpSession session = sessions.get(key);
+                    if (session == null || session.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) {
+                        //세션이 존재하고, 로그인 정보가 없으면 continue;
+                        continue;
+                    } else if (currentUserSession.getId().equals(session.getId()) == true) {
+                        //동일한 세션 ID이면 continue;
+                        continue;
+                    } else {
+                        //로그인 정보가 있으면 -> 중복 확인
+                        HashMap<String, Object> duplicationLoginUser = (HashMap<String, Object>) session.getAttribute(AuthUtil.LOGIN_USER_SESSION);
+                        String duplicationLoginUserId = (String) duplicationLoginUser.get("user_id");
+
+                        /** 동일한 로그인 정보 일 시 -> add **/
+                        if (currentLoginUserId.equals(duplicationLoginUserId) == true) {
+                            result.add(session.getId());
+                        } else {
+                            //동일한 로그인 정보가 아니면 -> continue;
+                            continue;
+                        }
+                    }
+                }
+            }
+        } catch (NullPointerException e) {
+            LOGGER.error(e.toString());
+        }
+
+        return result;
+    }
+
+    /**
+     * @author 서영석
+     * @since 2023.05.31
+     *
+     * @param userId : 사용자(회원) ID
+     *
+     * userId와 동일한 로그인 session을 가진 session ID 목록 삭제
+     */
+    public static int duplicationLoginSessionDeleteByUserId (String userId) {
+        int result = 0;
+        try {
+            List<String> sessionIds = duplicationLoginSessionIdSelectListByUserId(userId);
+            for (int i = 0; i < sessionIds.size(); i++) {
+                //Custom session 저장소에서 session 무효화 시키기
+                sessions.get(sessionIds.get(i)).invalidate();
+                //Custom session 저장소에서 session 삭제
+                sessions.remove(sessionIds.get(i));
+            }
+        } catch (NullPointerException e) {
+            LOGGER.error(e.toString());
+        }
+        return result;
+    }
+
+    /**
+     * @author 서영석
+     * @since 2023.05.31
+     *
+     * 현재 client의 정보와 중복된 로그인 session 전부 무효화 시키기 (완전 삭제는 못시킴)
+     */
+    public static int duplicationLoginSessionDeleteAll () {
+        int result = 0;
+        try {
+            List<String> sessionIds = duplicationLoginSessionIdSelectList();
+            for (int i = 0; i < sessionIds.size(); i++) {
+                //Custom session 저장소에서 session 무효화 시키기
+                sessions.get(sessionIds.get(i)).invalidate();
+                //Custom session 저장소에서 session 삭제
+                sessions.remove(sessionIds.get(i));
+            }
+        } catch (NullPointerException e) {
+            LOGGER.error(e.toString());
+        }
+        return result;
+    }
+
+    //난수생성
+    public static String generateRandomHex(int length) {
+        SecureRandom random = new SecureRandom();
+        byte[] randomBytes = new byte[length / 2]; // 16진수 문자열의 길이에 맞게 바이트 배열 크기를 조절
+
+        random.nextBytes(randomBytes);
+
+        // 바이트 배열을 16진수 문자열로 변환
+        StringBuilder hexStringBuilder = new StringBuilder();
+        for (byte b : randomBytes) {
+            hexStringBuilder.append(String.format("%02x", b));
+        }
+
+        return hexStringBuilder.toString();
+    }
+
+    /**
+     * HttpSessionListener Interface로 부터 상속 받은 메소드
+     *
+     * tomcat에서 session이 생성되었을 때(session timeout), 발생하는 이벤트
+     * @param target : session 이벤트(생성) 객체
+     *
+     * session 생성 이벤트가 발생하면 Custom session 저장소(sessions)에 해당 session ID 값을 Key로 잡고 저장
+     * (※ Default로 session에 현재 Client의 IP를 넣어줌)
+     */
+    @Override
+    public void sessionCreated(HttpSessionEvent target) {
+        int i = 1;
+        for (String key : sessions.keySet()) {
+            HttpSession hs = sessions.get(key);
+        }
+
+        // session에 key(salt) 값 넣기 시작
+        HashMap<String, Object> key = new HashMap<String, Object>();
+
+        // "SHA1PRNG"은 알고리즘 이름
+//        SecureRandom random = null;
+//        try {
+//            random = SecureRandom.getInstance("SHA1PRNG");
+//        } catch (NoSuchAlgorithmException e) {
+//            e.printStackTrace();
+//        }
+//        SecureRandom random = new SecureRandom();
+//
+//        byte[] saltBytes  = new byte[24];
+//        byte[] encKeyBytes = new byte[24];
+//        byte[] ivBytes = new byte[24];
+//        random.nextBytes(saltBytes);
+//        random.nextBytes(encKeyBytes);
+//        random.nextBytes(ivBytes);
+        //SALT 생성
+//        String salt = Base64.getEncoder().encodeToString(saltBytes);
+//        String ENC_KEY = Base64.getEncoder().encodeToString(encKeyBytes);
+//        String iv = Base64.getEncoder().encodeToString(ivBytes);
+        String salt = generateRandomHex(32);
+        String ENC_KEY = generateRandomHex(32);
+        String iv = generateRandomHex(32);
+        key.put("salt",salt);
+        key.put("ENC_KEY",ENC_KEY);
+        key.put("iv",iv);
+
+        target.getSession().setAttribute("key", key);
+
+        //종료
+
+
+        //현재 Client의 IP set
+        target.getSession().setAttribute("ip", CommonUtil.getClientIp());
+//        target.getSession().setAttribute("key",);
+
+        //세션 저장소에 set
+        sessions.put(target.getSession().getId(), target.getSession());
+    }
+
+    /**
+     * HttpSessionListener Interface로 부터 상속 받은 메소드
+     *
+     * tomcat에서 session이 소멸되었을 때, 발생하는 이벤트
+     * @param target : session 이벤트(소멸) 객체
+     *
+     * session 제거 이벤트가 발생하면 Custom session 저장소(sessions)에 해당 session ID 값을 가지고 있는 session 무효화 및 제거
+     */
+    @Override
+    public void sessionDestroyed(HttpSessionEvent target) {
+        //소멸된 세션 Custom session 저장소에서 가지고 오기
+        if (sessions.get(target.getSession().getId()) != null) {
+            //소멸된 세션 무효화 시키기 (가능한지 모르겠지만, 일단 작성해봄)
+            sessions.get(target.getSession().getId()).invalidate();
+            //Custom session 저장소에서 해당 session 삭제
+            sessions.remove(target.getSession().getId());
+        } else {
+            return;
+        }
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/util/SftpUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/SftpUtil.java
@@ -0,0 +1,1384 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jcraft.jsch.*;
+import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil;
+import com.takensoft.taken_bi_manager.common.file.vo.FileInfo;
+import com.takensoft.taken_bi_manager.common.vo.CheckMessage;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode;
+import com.takensoft.taken_bi_manager.data.vo.ColumnData;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.host.vo.ConnectionVO;
+import com.takensoft.taken_bi_manager.host.vo.FilesVO;
+import com.takensoft.taken_bi_manager.host.vo.SftpVO;
+import com.takensoft.taken_bi_manager.jobs.vo.JobItm;
+import org.apache.commons.io.FileUtils;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.takensoft.taken_bi_manager.data.util.DataTableConvert.fileToDataset;
+
+public class SftpUtil {
+
+    private Session session = null;
+    private Channel channel = null;
+    private ChannelSftp channelSftp = null;
+
+
+    /**
+     * sftp 연결
+     *
+     * @author 김성훈
+     * @since 2024.01.02
+     */
+    public CheckMessage sftpConnection(ConnectionVO.Host host) {
+        CheckMessage checkMessage = new CheckMessage();
+
+        JSch jSch = new JSch();
+
+        try {
+
+            session = jSch.getSession(host.getHost_id(), host.getHost_ip());
+            session.setPassword(host.getHost_pw());
+            java.util.Properties config = new java.util.Properties();
+
+            config.put("StrictHostKeyChecking", "no");
+            session.setConfig(config);
+            session.connect();
+
+            channel = session.openChannel("sftp");
+            channel.connect();
+
+            channelSftp = (ChannelSftp)channel;
+
+            checkMessage.setMessage(host.getHost_nm() + " 연결에 성공하였습니다.");
+            checkMessage.setStatus(HttpStatus.OK.value());
+
+        } catch (JSchException e) {
+
+            e.printStackTrace();
+            if("java.net.ConnectException: Connection timed out: connect".equals(e.getMessage())) {
+                checkMessage.setMessage(host.getHost_nm() + " 연결에 실패하였습니다.(연결 시간 초과)");
+
+            } else if("Auth fail".equals(e.getMessage())) {
+                checkMessage.setMessage(host.getHost_nm() + " 연결에 실패하였습니다.(계정 정보 불일치)");
+            }
+            checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+        }
+
+        return checkMessage;
+
+    }
+
+    /**
+     * sftp 해제
+     *
+     * @author 김성훈
+     * @since 2024.01.02
+     */
+    public void sftpDisconnection(SftpVO sftpVO) {
+        if(sftpVO.getSftpUtil().channelSftp != null) {
+            sftpVO.getSftpUtil().channelSftp.quit();
+        }
+        if(sftpVO.getSftpUtil().channel != null) {
+            sftpVO.getSftpUtil().channel.disconnect();
+        }
+        if(sftpVO.getSftpUtil().session != null) {
+            sftpVO.getSftpUtil().session.disconnect();
+        }
+    }
+
+    /**
+     * fileTree init
+     *
+     * @author 김성훈
+     * @since 2024.02.02
+     */
+    public CustomeResultMap fileTree(ConnectionVO.Connection connection) {
+
+        // 결과맵 생성
+        CustomeResultMap resultMap = new CustomeResultMap();
+
+        try {
+
+            // 루트 폴더 설정
+            String rootPath = this.rootPath(connection.getPath());
+
+            // 파일 리스트 및 FileDTO 생성
+            List<FilesVO> fileList = new ArrayList<>();
+            FilesVO filesVO = new FilesVO();
+
+            // 루트 폴더 추가
+            this.fileListAdd(null, rootPath, filesVO, "folder");
+            fileList.add(filesVO);
+
+            // 자식 폴더 추가
+            this.scanDir(filesVO.getPath(), filesVO.getChildren(), connection.getType(), connection.getDepth());
+
+            resultMap.getResultData().put("fileTree", fileList);
+
+            return resultMap;
+
+        } catch (Exception e) {
+
+            e.printStackTrace();
+            return null;
+
+        }
+    }
+
+    /**
+     * fileList
+     *
+     * @author 김성훈
+     * @since 2024.02.02
+     */
+    public CustomeResultMap fileList(ConnectionVO.Connection connection) {
+        // 결과맵 생성
+        CustomeResultMap resultMap = new CustomeResultMap();
+
+        try {
+
+            // 파일 리스트 및 FileDTO 생성
+            List<FilesVO> fileList = this.scanDir(connection.getPath(), new ArrayList<FilesVO>(), connection.getType(), connection.getDepth());
+
+            // 상위 폴더가기 구현
+            if( "all".equals(connection.getType()) || "file".equals(connection.getType())) {
+                connection.getPath();
+                if(!connection.getPath().equals("/home")) {
+                    FilesVO temp = new FilesVO();
+                    String parentPath = this.parentPath(connection.getPath());
+                    this.fileListAdd(null, parentPath, temp, "folder");
+                    temp.setText("상위폴더로 이동");
+                    temp.setExtension("");
+                    fileList.add(0,temp);
+
+                    resultMap.getResultData().put("totalRow", fileList.size() - 1);
+                } else {
+                    resultMap.getResultData().put("totalRow", fileList.size());
+                }
+            }
+
+            resultMap.getResultData().put("fileList", fileList);
+
+            return resultMap;
+
+        } catch (Exception e) {
+
+            e.printStackTrace();
+            return null;
+
+        }
+
+    }
+
+    /**
+     * FILE -> FileDTO로 변환
+     *
+     * @author 김성훈
+     * @since 2024.01.03
+     */
+    public void fileListAdd(ChannelSftp.LsEntry lsEntry, String path, FilesVO filesVO, String fileType) throws Exception {
+        // 루트 폴더가 아닐때
+        if(lsEntry != null) {
+
+            SftpATTRS attrs = lsEntry.getAttrs();
+            filesVO.setId(path);
+            filesVO.setText(lsEntry.getFilename());
+            filesVO.setPath(path);
+
+            // 시간변환
+            SimpleDateFormat inFormat = new SimpleDateFormat ("EEE MMM d HH:mm:ss Z yyyy", Locale.ENGLISH);
+            Date date = inFormat.parse(lsEntry.getAttrs().getMtimeString());
+            SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            String formatDate = outFormat.format(date);
+
+            filesVO.setLastUpdate(formatDate);
+            // 폴더인지 파일인지 확인
+            if("folder".equals(fileType)) {
+                filesVO.setSize(0);
+                filesVO.setFolder(true);
+                filesVO.setExtension("폴더");
+                filesVO.setSort(0);
+            } else {
+                filesVO.setSize(attrs.getSize());
+                filesVO.setFolder(false);
+                filesVO.setExtension(this.splitLastString(lsEntry.getFilename(), '.'));
+                filesVO.setSort(1);
+            }
+
+            // 루트 폴더 일때
+        } else {
+            filesVO.setId(path);
+            filesVO.setPath(path);
+            filesVO.setFolder(true);
+            filesVO.setSize(0);
+            filesVO.setExtension("폴더");
+            filesVO.setSort(0);
+            if(path != "/") {
+                filesVO.setText(this.splitLastString(path, '/'));
+            } else {
+                filesVO.setText("/");
+            }
+
+        }
+    }
+
+    /**
+     * 파일 경로를 이용하여 경로에 존재하는 폴더 및 파일 찾기
+     *
+     * @author 김성훈
+     * @since 2024.01.03
+     */
+    public List<FilesVO> scanDir(String path, List<FilesVO> children, String type, int depth) {
+
+        try {
+
+            List<ChannelSftp.LsEntry> files = null;
+
+            // 폴더 리스트
+            files = channelSftp.ls(path);
+
+            //파일 리스트 정렬(알파벳 오름차순)
+            files = files.stream().sorted(Comparator.comparing(ChannelSftp.LsEntry::getFilename, String.CASE_INSENSITIVE_ORDER)).collect(Collectors.toList());
+
+            // 자식 폴더가 있을때
+            if (files != null || !files.isEmpty()) {
+                // 파일리스트에 있는 파일한개 가져오기
+                for (ChannelSftp.LsEntry lsEntry : files) {
+
+                    // 파일명이 . and ..이 아닐때
+                    if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) {
+                        SftpATTRS attrs = lsEntry.getAttrs();
+
+                        String childrenPath;
+                        // 파일 패스 만들기
+                        if (path != "/") {
+                            childrenPath = path + "/" + lsEntry.getFilename();
+                        } else {
+                            childrenPath = path + lsEntry.getFilename();
+                        }
+
+                        // 폴더이거나 링크폴더일 경우
+                        if (attrs.isDir() || attrs.isLink()) {
+                            if ("all".equals(type) || "folder".equals(type)) {
+                                FilesVO temp = new FilesVO();
+
+                                // lsEntry -> 파일DTO로 변환
+                                this.fileListAdd(lsEntry, childrenPath, temp, "folder");
+                                temp.setParent(this.parentPath(childrenPath));
+                                // 부모 폴더 자식에 추가
+                                children.add(temp);
+                                //폴더 깊이가 0이면 다음 깊이(자식) 한번 더 검색
+                                if (depth < 1) {
+                                    scanDir(childrenPath, temp.getChildren(), type, depth + 1);
+                                }
+                            }
+                        } else {
+                            // 파일검색 일때
+                            if ("all".equals(type) || "file".equals(type)) {
+                                FilesVO temp = new FilesVO();
+                                // lsEntry -> 파일DTO로 변환
+                                this.fileListAdd(lsEntry, childrenPath, temp, "file");
+                                temp.setParent(this.parentPath(childrenPath));
+                                // 부모 폴더 자식에 추가
+                                children.add(temp);
+                            }
+                        }
+                    }
+                }
+            }
+            //파일 리스트 정렬(폴더가 위로 -> 파일이름)
+            children = children.stream().sorted(Comparator.comparingInt(FilesVO::getSort)).collect(Collectors.toList());
+            return children;
+
+        } catch (Exception e) {
+
+            e.printStackTrace();
+            return null;
+
+        }
+    }
+
+    /**
+     * 폴더 생성
+     *
+     * @author 김성훈
+     * @since 2024.02.08
+     */
+    public CheckMessage mkdir(ConnectionVO.Mkdir mkdir) {
+        CheckMessage checkMessage = new CheckMessage();
+        String dirPath = mkdir.getPath() + "/" + mkdir.getFolderName();
+        try {
+            if(!this.exists(dirPath)) {
+//                channelSftp.cd(mkdir.getPath());
+                channelSftp.mkdir(dirPath);
+                checkMessage.setMessage(mkdir.getFolderName() + " 폴더를 추가 하였습니다.");
+            } else {
+                checkMessage.setMessage(mkdir.getFolderName() + "은(는) 이미 존재하는 폴더명입니다.");
+            }
+            checkMessage.setStatus(HttpStatus.OK.value());
+        } catch (Exception e){
+            e.printStackTrace();
+            checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+        return checkMessage;
+    }
+
+    /**
+     * 파일 업로드
+     *
+     * @author 김성훈
+     * @since 2024.02.13
+     */
+    public CheckMessage fileUpload(ConnectionVO.FileUpload fileUpload) {
+        CheckMessage checkMessage = new CheckMessage();
+
+        String filePath = fileUpload.getPath() + "/" + fileUpload.getUploadFile().getOriginalFilename();
+
+        try (InputStream inputStream = fileUpload.getUploadFile().getInputStream()){
+
+            if(!fileUpload.isConfirm()) {
+                if(!this.exists(filePath)) {
+                    channelSftp.put(inputStream, filePath, new Monitor());
+                    checkMessage.setMessage(fileUpload.getUploadFile().getOriginalFilename() + " 파일을 업로드 하였습니다.");
+                    checkMessage.setStatus(HttpStatus.OK.value());
+                } else {
+                    checkMessage.setMessage(fileUpload.getUploadFile().getOriginalFilename() + "이(가) 이미 존재합니다. 덮어쓰시겠습니까?");
+                    checkMessage.setStatus(HttpStatus.CONTINUE.value());
+                }
+            } else {
+                channelSftp.put(inputStream, filePath, new Monitor());
+
+                checkMessage.setMessage("덮어쓰기를 완료 하였습니다.");
+                checkMessage.setStatus(HttpStatus.OK.value());
+            }
+
+        } catch (Exception e) {
+
+            e.printStackTrace();
+            checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+        }
+
+        return checkMessage;
+    }
+
+    /**
+     * 파일 다운로드
+     *
+     * @author 김성훈
+     * @since 2024.02.14
+     */
+    public CheckMessage fileDownload(ConnectionVO.FileDownload fileDownload, String host_nm) {
+        CheckMessage checkMessage = new CheckMessage();
+        String filePath = fileDownload.getPath() + "/" + fileDownload.getFileName();
+
+        FileOutputStream out = null;
+        try {
+
+            //로컬에 저장 폴더 있는지 확인
+            String absolutePath = SystemCode.FileUploadPath.SFTP_ABSOLUTE_PATH.getOSFileUploadPath() + "/" + host_nm;
+            File dir = new File(absolutePath);
+
+            if (dir.exists() == false) {
+                dir.mkdirs();
+            }
+
+            if(this.exists(filePath)) {
+                channelSftp.cd(fileDownload.getPath());
+
+                out = new FileOutputStream(new File(absolutePath + "/" + fileDownload.getFileName()));
+
+                channelSftp.get(fileDownload.getFileName(), out, new Monitor());
+
+                checkMessage.setMessage("파일 다운로드를 완료 하였습니다.");
+            } else {
+                checkMessage.setMessage("존재하지 않는 파일입니다.");
+            }
+
+            checkMessage.setStatus(HttpStatus.OK.value());
+
+            return checkMessage;
+
+        } catch (Exception e) {
+
+            e.printStackTrace();
+            checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+            return checkMessage;
+
+        } finally {
+
+            if(out != null) {
+                try {
+                    out.flush();
+                    out.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+
+                    checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요.");
+                    checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+                    return checkMessage;
+                }
+            }
+        }
+    }
+
+    /**
+     * 폴더, 파일 이름 변경
+     *
+     * @author 김성훈
+     * @since 2024.02.15
+     */
+    public CheckMessage fileReName(ConnectionVO.Rename rename) {
+        CheckMessage checkMessage = new CheckMessage();
+
+        try {
+
+            if(this.exists(rename.getCurrentPath())) {
+                channelSftp.rename(rename.getCurrentPath(), rename.getChangePath());
+                checkMessage.setMessage("이름 변경을 완료 하였습니다.");
+            } else {
+                checkMessage.setMessage("존재하지 않는 파일 입니다.");
+            }
+            checkMessage.setStatus(HttpStatus.OK.value());
+
+        } catch (Exception e){
+
+            e.printStackTrace();
+            checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+        }
+
+        return checkMessage;
+    }
+
+    /**
+     * 폴더, 파일 삭제
+     *
+     * @author 김성훈
+     * @since 2024.02.15
+     */
+    public CheckMessage fileRemove(List<ConnectionVO.Remove> removeList) {
+        CheckMessage checkMessage = new CheckMessage();
+
+        try {
+
+            for (ConnectionVO.Remove remove : removeList) {
+                if(this.exists(remove.getPath())) {
+                    if(remove.isFolder()) {
+//                        channelSftp.cd(remove.getPath());
+                        List<ChannelSftp.LsEntry> ls = channelSftp.ls(remove.getPath());
+
+                        if(ls.size() != 2) {
+                            this.rmdir(ls, remove.getPath());
+                        }
+                        channelSftp.rmdir(remove.getPath());
+
+                    } else {
+                        channelSftp.rm(remove.getPath());
+                    }
+                    checkMessage.setMessage("삭제를 완료 하였습니다.");
+                } else {
+                    checkMessage.setMessage("이미 삭제된 파일 입니다.");
+
+                }
+                checkMessage.setStatus(HttpStatus.OK.value());
+            }
+
+        } catch (Exception e){
+
+            e.printStackTrace();
+            checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+
+        }
+
+        return checkMessage;
+    }
+
+    /**
+     * @author 김성훈
+     * @since 2024.02.08
+     *
+     * 폴더 삭제 시 하위 폴더 안 파일 부터 삭제
+     */
+    public void rmdir(List<ChannelSftp.LsEntry> ls, String path) throws SftpException {
+
+        for (ChannelSftp.LsEntry lsEntry : ls) {
+            if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) {
+                String lsPath = path + "/" + lsEntry.getFilename();
+                if(this.exists(lsPath)) {
+                    SftpATTRS attrs = lsEntry.getAttrs();
+                    if (attrs.isDir() || attrs.isLink()) {
+//                        channelSftp.cd(lsPath);
+                        List<ChannelSftp.LsEntry> childrenLs = channelSftp.ls(lsPath);
+                        if(ls.size() != 2) {
+                            this.rmdir(childrenLs, lsPath);
+                        }
+                        channelSftp.rmdir(lsPath);
+                    } else {
+                        channelSftp.rm(lsPath);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 파일 이동
+     *
+     * @author 김성훈
+     * @since 2024.02.16
+     */
+    public CustomeResultMap fileMove(ConnectionVO.MoveList moveList) {
+        CustomeResultMap customeResultMap = new CustomeResultMap();
+        //폴더 리스트
+        List<ConnectionVO.Move> fileList = moveList.getFileList();
+        List<ConnectionVO.Remove> removeFolderList = moveList.getRemoveFolder();
+
+        try {
+            if("cancel".equals(moveList.getType())) {
+                fileList.remove(0);
+            }
+
+            for (int i = 0; i < fileList.size(); i++) {
+                ConnectionVO.Move move = fileList.get(i);
+
+                if(!moveList.isCheck()) {
+                    if (!move.isFolder()) {
+                        if (!this.exists(move.getMovePath() + "/" + move.getFileName())) {
+                            channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName());
+                        } else {
+                            if("move".equals(moveList.getType())) {
+                                channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName());
+                                moveList.setType("confirm");
+                            } else {
+                                customeResultMap.getCheckMessage().setMessage(move.getFileName() + "이(가) 이미 존재합니다. 동작을 선택하십시오.");
+                                customeResultMap.getCheckMessage().setStatus(HttpStatus.CONTINUE.value());
+                                customeResultMap.getResultData().put("removeFolderList", removeFolderList);
+                                customeResultMap.getResultData().put("fileList", fileList.subList(i, fileList.size()));
+                                return customeResultMap;
+                            }
+                        }
+                    } else {
+
+                        if(!this.exists(move.getMovePath() + "/" + move.getFileName())) {
+                            channelSftp.mkdir(move.getMovePath() + "/" + move.getFileName());
+                        }
+
+                        List<ChannelSftp.LsEntry> files = null;
+                        List<ConnectionVO.Move> filesSearchList = new ArrayList<>();
+
+                        // 폴더 리스트
+                        files = channelSftp.ls(move.getPath());
+
+                        // 자식이 있을때
+                        if(files != null && !files.isEmpty()) {
+                            // 파일리스트에 있는 파일한개 가져오기
+                            for (ChannelSftp.LsEntry lsEntry : files) {
+                                // 파일명이 . and ..이 아닐때
+                                if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) {
+                                    SftpATTRS attrs = lsEntry.getAttrs();
+
+                                    ConnectionVO.Move moveFile = new ConnectionVO.Move();
+
+                                    moveFile.setFileName(lsEntry.getFilename());
+                                    moveFile.setMovePath(move.getMovePath() + '/' + move.getFileName());
+                                    moveFile.setPath(move.getPath() + '/' + lsEntry.getFilename());
+                                    moveFile.setFolder(false);
+
+                                    if (attrs.isDir() || attrs.isLink()) {
+                                        moveFile.setFolder(true);
+                                    }
+                                    filesSearchList.add(moveFile);
+                                }
+                            }
+                        }
+                        fileList.addAll(filesSearchList);
+
+                        ConnectionVO.Remove remove = new ConnectionVO.Remove();
+                        remove.setPath(move.getPath());
+                        remove.setFolder(true);
+                        removeFolderList.add(remove);
+                    }
+                } else {
+                    if("move".equals(moveList.getType())) {
+                        channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName());
+                    } else {
+                        if (!this.exists(move.getMovePath() + "/" + move.getFileName())) {
+                            channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName());
+                        }
+                    }
+
+                }
+            }
+
+            customeResultMap.getResultData().put("removeFolderList", removeFolderList);
+            customeResultMap.getCheckMessage().setStatus(HttpStatus.OK.value());
+            customeResultMap.getCheckMessage().setMessage("파일이동을 완료 하였습니다.");
+
+        } catch (Exception e){
+            e.printStackTrace();
+            customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+        return customeResultMap;
+    }
+
+    /**
+     * 폴더, 파일 이동 후 비어있는 폴더 지우기
+     *
+     * @author 김성훈
+     * @since 2024.03.11
+     */
+    public CheckMessage removeFolder(List<ConnectionVO.Remove> folderList) {
+        CheckMessage checkMessage = new CheckMessage();
+
+        try {
+            for (int i = folderList.size(); i > 0; i--) {
+                ConnectionVO.Remove remove = folderList.get(i-1);
+
+                if(this.exists(remove.getPath())) {
+                    Vector ls = channelSftp.ls(remove.getPath());
+
+                    if(ls.size() == 2) {
+                        channelSftp.rmdir(remove.getPath());
+                    }
+                }
+            }
+
+        } catch(Exception e) {
+            e.printStackTrace();
+            checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+            checkMessage.setMessage("이동 완료 후 서버 오류로 인해 원본 폴더가 삭제되지 않았습니다. 삭제를 원하시면 원본 폴더를 삭제해주세요.");
+        }
+        return checkMessage;
+    }
+
+    /**
+     * 파일 복사
+     *
+     * @author 김성훈
+     * @since 2024.03.07
+     */
+    public CustomeResultMap fileCopy(ConnectionVO.CopyList copyList) {
+        CustomeResultMap customeResultMap = new CustomeResultMap();
+        //폴더 리스트
+        List<ConnectionVO.Move> fileList = copyList.getFileList();
+
+        try {
+
+            if("cancel".equals(copyList.getType())) {
+                fileList.remove(0);
+            }
+
+            for (int i = 0; i < fileList.size(); i++) {
+                ConnectionVO.Move move = fileList.get(i);
+
+                if(!copyList.isCheck()) {
+                    if (!move.isFolder()) { // 폴더가 아닐 때
+                        if (!this.exists(move.getMovePath() + "/" + move.getFileName())) { // 이동할 폴더에 동일한 이름의 파일이 없을 때
+//                            this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName()); // 파일 복사
+                            this.inputMoveCopy(move); // 파일 이동 복사
+                        } else { // 이동할 폴더에 동일한 이름의 파일이 있을 경우
+                            if("move".equals(copyList.getType())) {
+//                                this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName());
+                                this.inputMoveCopy(move); // 파일 이동 복사
+                                copyList.setType("confirm");
+                            } else {
+                                customeResultMap.getCheckMessage().setMessage(move.getFileName() + "이(가) 이미 존재합니다. 동작을 선택하십시오.");
+                                customeResultMap.getCheckMessage().setStatus(HttpStatus.CONTINUE.value());
+                                customeResultMap.getResultData().put("fileList", fileList.subList(i, fileList.size()));
+                                return customeResultMap;
+                            }
+                        }
+                    } else { // 폴더일 때
+
+                        if(!this.exists(move.getMovePath() + "/" + move.getFileName())) { // 이동할 폴더에 동일한 이름의 폴더가 없을 때
+                            channelSftp.mkdir(move.getMovePath() + "/" + move.getFileName()); // 폴더 생성
+                        }
+
+                        List<ChannelSftp.LsEntry> files = null;
+                        List<ConnectionVO.Move> filesSearchList = new ArrayList<>();
+
+                        // 폴더 리스트
+                        files = channelSftp.ls(move.getPath());
+
+                        // 자식이 있을때
+                        if(files != null && !files.isEmpty()) {
+                            // 파일리스트에 있는 파일한개 가져오기
+                            for (ChannelSftp.LsEntry lsEntry : files) {
+                                // 파일명이 . and ..이 아닐때
+                                if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) {
+                                    SftpATTRS attrs = lsEntry.getAttrs();
+
+                                    ConnectionVO.Move moveFile = new ConnectionVO.Move();
+
+                                    moveFile.setFileName(lsEntry.getFilename());
+                                    moveFile.setMovePath(move.getMovePath() + '/' + move.getFileName());
+                                    moveFile.setPath(move.getPath() + '/' + lsEntry.getFilename());
+                                    moveFile.setFolder(false);
+
+                                    if (attrs.isDir() || attrs.isLink()) {
+                                        moveFile.setFolder(true);
+                                    }
+                                    filesSearchList.add(moveFile);
+                                }
+                            }
+                        }
+                        fileList.addAll(filesSearchList);
+
+                    }
+                } else {
+                    if("move".equals(copyList.getType())) {
+//                        this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName());
+                        this.inputMoveCopy(move); // 파일 이동 복사
+                    } else {
+                        if (!this.exists(move.getMovePath() + "/" + move.getFileName())) {
+//                            this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName());
+                            this.inputMoveCopy(move); // 파일 이동 복사
+                        }
+                    }
+                }
+            }
+
+            customeResultMap.getCheckMessage().setStatus(HttpStatus.OK.value());
+            customeResultMap.getCheckMessage().setMessage("파일복사를 완료 하였습니다.");
+
+        } catch (Exception e){
+            e.printStackTrace();
+            customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+        return customeResultMap;
+    }
+
+    /**
+     * @author 김성훈
+     * @since 2024.03.13
+     *
+     * 파일 복사 시작
+     */
+    public void inputCopy(String path, String movePath) throws Exception {
+
+        Channel copyChannel = session.openChannel("sftp");
+        copyChannel.connect();
+        ChannelSftp copyChannelSftp = (ChannelSftp)copyChannel;
+
+        try(InputStream inputStream = channelSftp.get(path)) {
+            copyChannelSftp.put(inputStream, movePath, new Monitor());
+        } catch(Exception e) {
+            e.printStackTrace();
+            throw new IOException();
+        }
+    }
+
+    /**
+     * @author 김성훈
+     * @since 2024.03.13
+     *
+     * 파일 검색
+     */
+    public CustomeResultMap fileSearch(String path, List<FilesVO> fileList, String searchText) {
+        CustomeResultMap customeResultMap = new CustomeResultMap();
+
+        try {
+            List<ChannelSftp.LsEntry> files = null;
+
+            // 폴더 리스트
+            files = channelSftp.ls(path);
+
+            // 자식 폴더가 있을때
+            if (files != null || !files.isEmpty()) {
+
+                // 파일리스트에 있는 파일한개 가져오기
+                for (ChannelSftp.LsEntry lsEntry : files) {
+                    // 파일명이 . and ..이 아닐때
+                    if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) {
+                        SftpATTRS attrs = lsEntry.getAttrs();
+
+                        String childrenPath;
+                        // 파일 패스 만들기
+                        if (path != "/") {
+                            childrenPath = path + "/" + lsEntry.getFilename();
+                        } else {
+                            childrenPath = path + lsEntry.getFilename();
+                        }
+
+                        // 폴더이거나 링크폴더일 경우
+                        if (attrs.isDir() || attrs.isLink()) {
+                            this.fileSearch(childrenPath, fileList, searchText);
+                        } else {
+                            if(lsEntry.getFilename().contains(searchText)) {
+                                FilesVO temp = new FilesVO();
+                                // lsEntry -> 파일DTO로 변환
+                                this.fileListAdd(lsEntry, childrenPath, temp, "file");
+                                fileList.add(temp);
+                            }
+                        }
+                    }
+                }
+            }
+
+            customeResultMap.getResultData().put("fileList", fileList);
+            customeResultMap.getCheckMessage().setStatus(HttpStatus.OK.value());
+            customeResultMap.getCheckMessage().setMessage("파일 검색을 완료 하였습니다.");
+        } catch(Exception e) {
+            e.printStackTrace();
+            customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+            customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요.");
+
+        }
+        return customeResultMap;
+    }
+
+    /**
+     * @author 김성훈
+     * @since 2024.03.13
+     *
+     * 파일 -> DataTable 변환
+     */
+    public CustomeResultMap fileRead(FileInfo fileInfo) {
+        CustomeResultMap customeResultMap = new CustomeResultMap();
+        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        int limit = Integer.MAX_VALUE;
+
+        if(fileInfo.isViewMode() == true) {
+            limit = 100;
+        }
+
+        List<FileInfo> files = new ArrayList<>();
+        List<DataTable> dataTables = new ArrayList<>();
+
+        FileInfo backFileInfo = new FileInfo(fileInfo);
+
+        //임시 파일 초기화
+        List<File> tempFiles = new ArrayList<>();
+        //임시 파일 저장 경로
+        String tempPath = SystemCode.FileUploadPath.TEMP_ABSOLUTE_PATH.getOSFileUploadPath();
+
+        //임시파일 저장 폴더 없으면 생성
+        File tempDir = new File(tempPath);
+        if (tempDir.exists() == false) {
+            tempDir.mkdirs();
+        }
+
+        // 특정 파일 읽기
+        if("file".equals(fileInfo.getType())) {
+
+            try(InputStream inputStream = channelSftp.get(backFileInfo.getPath())) {
+                // 임시파일 생성
+                File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + backFileInfo.getExtension(), tempDir);
+
+                // 임시파일 쓰기
+                FileUtils.copyInputStreamToFile(inputStream, tempFile);
+
+                //FileInfo를 임시파일 정보로 변경
+                backFileInfo.fileToFileInfo(tempFile);
+
+                //임시파일 리스트 add
+                tempFiles.add(tempFile);
+                //파일읽기 리스트 add
+                files.add(backFileInfo);
+
+            } catch(Exception e) {
+                e.printStackTrace();
+            }
+        // 폴더에 있는 파일 목록 읽기
+        } else {
+
+            try {
+                // 폴더 리스트
+                List<ChannelSftp.LsEntry> allFiles = channelSftp.ls(fileInfo.getPath());
+
+                if (allFiles != null || !allFiles.isEmpty()) {
+                    List<ChannelSftp.LsEntry> lsFiles = new ArrayList<>();
+                    for (ChannelSftp.LsEntry lsEntry : allFiles) {
+                        if(!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename()) && !lsEntry.getAttrs().isDir() && !lsEntry.getAttrs().isLink()) {
+                            lsFiles.add(lsEntry);
+                        }
+                    }
+
+                    //파일 리스트 정렬(폴더가 위로 -> 파일이름)
+                    lsFiles = lsFiles.stream().sorted(Comparator.comparingInt(lsEntry -> lsEntry.getAttrs().getMTime())).collect(Collectors.toList());
+
+                    if(fileInfo.isLastData()) {
+                        ChannelSftp.LsEntry lsEntry = lsFiles.get(lsFiles.size() - 1);
+                        try(InputStream inputStream = channelSftp.get(fileInfo.getPath() + "/" + lsEntry.getFilename())) {
+                            // 임시파일 생성
+                            File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + this.splitLastString(lsEntry.getFilename(), '.'), tempDir);
+
+                            // 임시파일 쓰기
+                            FileUtils.copyInputStreamToFile(inputStream, tempFile);
+
+                            //FileInfo를 임시파일 정보로 변경
+                            fileInfo.fileToFileInfo(tempFile);
+
+                            //임시파일 리스트 add
+                            tempFiles.add(tempFile);
+                            //파일읽기 리스트 add
+                            files.add(fileInfo);
+
+                        } catch(Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+
+                    if(fileInfo.isDatasetAfter()) {
+                        List<ChannelSftp.LsEntry> datasetAfterFileList = new ArrayList<>();
+                        Date datasetDate = null;
+//                             기준 데이터셋 확인
+//                        if(!StringUtil.isEmpty(fileInfo.getDatasetId())) {
+//                            Dataset dataset = datasetDAO.selectDatasetByPostId(fileInfo.getDatasetId());
+//                            if(StringUtil.isEmpty(dataset.getUpdtDt().toString())) {
+//                                datasetDate = new Date(sf.parse(dataset.getCreatDt().toString()).getTime());
+//                            }else {
+//                                datasetDate = new Date(sf.parse(dataset.getUpdtDt().toString()).getTime());
+//                            }
+//                        }
+
+                        // 파일리스트에 있는 파일한개 가져오기
+                        for (int i = 0; i < lsFiles.size(); i++) {
+                            ChannelSftp.LsEntry lsEntry = lsFiles.get(i);
+
+                            SftpATTRS attrs = lsEntry.getAttrs();
+
+                            // 시간변환
+                            SimpleDateFormat inFormat = new SimpleDateFormat ("EEE MMM d HH:mm:ss Z yyyy", Locale.ENGLISH);
+                            Date date = inFormat.parse(attrs.getMtimeString());
+                            SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                            String formatDate = outFormat.format(date);
+                            Date resultDate = outFormat.parse(formatDate);
+
+                            if(datasetDate.compareTo(resultDate) < 0) {
+                                datasetAfterFileList = lsFiles.subList(i, lsFiles.size());
+                                break;
+                            }
+                        }
+
+                        if(!datasetAfterFileList.isEmpty()) {
+                            for (ChannelSftp.LsEntry lsEntry : datasetAfterFileList) {
+                                try(InputStream inputStream = channelSftp.get(fileInfo.getPath() + "/" + lsEntry.getFilename())) {
+                                    // 임시파일 생성
+                                    File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + this.splitLastString(lsEntry.getFilename(), '.'), tempDir);
+
+                                    // 임시파일 쓰기
+                                    FileUtils.copyInputStreamToFile(inputStream, tempFile);
+
+                                    //FileInfo를 임시파일 정보로 변경
+                                    fileInfo.fileToFileInfo(tempFile);
+
+                                    //임시파일 리스트 add
+                                    tempFiles.add(tempFile);
+                                    //파일읽기 리스트 add
+                                    files.add(fileInfo);
+
+                                } catch(Exception e) {
+                                    e.printStackTrace();
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    //자식파일이 없을때!! 구현해야함
+               }
+            } catch(Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        // 데이터셋 만들기 (파일 하나 밖에 처리 안 됨)
+        Map<String, DataTable> dataTableMap = new LinkedHashMap<>();
+        for(FileInfo file : files) {
+            try {
+                dataTableMap = fileToDataset(file, limit);
+                dataTables.add(dataTableMap.get(dataTableMap.keySet().toArray()[0]));
+            } catch(Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        // 데이터셋에 표출 컬럼명 추가
+        DataTable resultDataTable = new DataTable();
+
+        if(dataTables.size() > 0) resultDataTable = dataTables.get(0);
+
+        List<ColumnData> columnDatas = resultDataTable.getColumnDatas();
+
+        for (ColumnData columnData : columnDatas) {
+            columnData.setDisplyColumnNm(columnData.getOrginlColumnNm());
+        }
+
+        // 데이터셋 인덱스 처리?
+        /*if(fileInfo.getRowDataColumnIndex() > 0) {
+            resultDataTable.setRowDataColumnIndex(fileInfo.getRowDataColumnIndex());
+            resultDataTable.setStartRowIndex(fileInfo.getStartRowIndex());
+            resultDataTable.setStartCellIndex(fileInfo.getStartCellIndex());
+
+            for(int i = 0 ; i < columnDatas.size() ; i++ ) {
+                columnDatas.get(i).setDisplyColumnNm(resultDataTable.getColumnDatas().get(i).get(i).toString());
+                columnDatas.get(i).setOrginlColumnNm(resultDataTable.getRowData().get(0).get(i).toString());
+            }
+        }*/
+
+//        customeResultMap.getResultData().put("dataTableMap", dataTableMap);
+
+        try {
+            DataTypeUtil.convertDataTableColumMeta(resultDataTable); // 데이터 컬럼에 메타 정보 삽입
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        customeResultMap.getResultData().put("dataTableMap", resultDataTable);
+
+        if (!tempFiles.isEmpty()) { // 임시파일 목록이 비어있지 않다면
+            for (File tempFile : tempFiles) {
+                if(tempFile.exists()) { // 임시파일이 존재한다면
+                    this.deleteTempFile(tempFile); // 임시파일 삭제
+                }
+            }
+        }
+
+        return customeResultMap;
+    }
+
+
+    /**
+     * 루트 폴더 설정
+     *
+     * @author 김성훈
+     * @since 2024.01.04
+     */
+    public String rootPath(String path) {
+        if (path == null || path.trim().isEmpty()) {
+            path = "#";
+        }
+        if ("#".equals(path)) {
+            path = "/home";
+        }
+        return path;
+    }
+
+    /**
+     * 경로 및 확장자 추출
+     *
+     * @author 김성훈
+     * @since 2024.01.04
+     */
+    public String splitLastString(String text, char deliminator) {
+        int index = text.lastIndexOf(deliminator);
+        if(index > 0) {
+            return text.substring(index + 1);
+        }
+        return text;
+    }
+
+    /**
+     * 부모파일경로 찾기
+     *
+     * @author 김성훈
+     * @since 2024.01.04
+     */
+    public String parentPath(String path) {
+        int index = path.lastIndexOf("/");
+        return path.substring(0,index);
+    }
+
+    /**
+     * @author 김성훈
+     * @since 2024.02.08
+     *
+     * 디렉토리( or 파일) 존재 여부
+     */
+    public boolean exists(String path) {
+        Vector ls = null;
+        try {
+            ls = channelSftp.ls(path);
+        } catch (SftpException e) {
+            if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
+                return false;
+            }
+        }
+        return ls != null && !ls.isEmpty();
+    }
+
+
+    /**
+     * @author 김성훈
+     * @since 2024.02.16
+     *
+     * 파일 업로드, 다운로드 진행율(%) 표시
+     */
+    class Monitor implements SftpProgressMonitor {
+
+        private long max = 0;  //최대
+        private long count = 0;  //계산을 위해 담아두는 변수
+        private long percent = 0;  //퍼센트
+
+        @Override
+        public void init(int op, String src, String dest, long max) {  //설정
+
+            this.max = max;
+        }
+
+        @Override
+        public void end() {
+            //종료시 할 행동
+        }
+
+        @Override
+        public boolean count(long bytes) {
+            this.count += bytes;  //전송한 바이트를 더한다.
+            long percentNow = this.count*100/max;  //현재값에서 최대값을 뺀후
+            if(percentNow>this.percent){  //퍼센트보다 크면
+                this.percent = percentNow;
+            }
+            return true;//기본값은 false이며 false인 경우 count메소드를 호출하지 않는다.
+        }
+    }
+
+    /**
+     * @author 하석형
+     * @since 2024.04.25
+     *
+     * 파일 이동 복사 시작
+     */
+    public void inputMoveCopy(ConnectionVO.Move move) throws Exception {
+        /** 호스트서버 -> 로컬 임시파일 다운로드 */
+        //임시 파일 저장 경로
+        String tempPath = SystemCode.FileUploadPath.TEMP_ABSOLUTE_PATH.getOSFileUploadPath();
+
+        //임시파일 저장 폴더 없으면 생성
+        File tempDir = new File(tempPath);
+        if (tempDir.exists() == false) {
+            tempDir.mkdirs();
+        }
+
+        File newFile = null; // 최종 임시파일
+
+        try(InputStream inputStream = channelSftp.get(move.getPath())) {
+            // 임시파일 생성
+            File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + move.getExtension(), tempDir);
+            // 임시파일은 복사 후 삭제할거기 때문에 기존 파일명을 그대로 임시파일로 사용해도 문제없음
+//        File tempFile = File.createTempFile(move.getFileName(), "." + move.getExtension(), tempDir);
+
+            // 임시파일 쓰기
+            FileUtils.copyInputStreamToFile(inputStream, tempFile);
+
+            // 임시파일명을 기존 파일명으로 변경
+            newFile = new File(tempDir, move.getFileName());
+            boolean renamed = tempFile.renameTo(newFile);
+            if (!renamed) {
+                throw new IOException("임시 파일명 변경 실패");
+            }
+
+            /** 로컬 -> 호스트서버 파일 업로드 */
+            // 업로드할 경로
+            String filePath = move.getMovePath() + "/" + move.getFileName();
+
+            try(InputStream uploadInputStream = new FileInputStream(newFile.getAbsolutePath())) {
+                // 파일 업로드
+                channelSftp.put(uploadInputStream, filePath, new Monitor());
+            }
+
+        } catch(Exception e) {
+            e.printStackTrace();
+            throw new IOException();
+        } finally {
+            // 로컬 임시파일 삭제
+            this.deleteTempFile(newFile);
+        }
+    }
+
+    /**
+     * @author 하석형
+     * @since 2024.04.26
+     *
+     * 로컬 임시파일 삭제
+     */
+    public void deleteTempFile(File file) {
+        if (file != null && file.exists()) {
+            try {
+                Files.delete(file.toPath());
+            } catch (IOException e) {
+                System.err.println("임시 파일 삭제 실패: " + file.toPath());
+            }
+        }
+    }
+
+    /**
+     * @author 하석형
+     * @since 2024.04.26
+     *
+     * 파일 쓰기
+     */
+    public CustomeResultMap fileWrite(JobItm jobItm) {
+        CustomeResultMap customeResultMap = new CustomeResultMap();
+        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+
+        // 빈 파일 인스턴스 생성
+//        FileInfo fileInfo = new FileInfo();
+        ObjectMapper objectMapper = new ObjectMapper();
+        FileInfo fileInfo = objectMapper.convertValue(jobItm.getItm(), FileInfo.class);
+        // 빈 데이터테이블 인스턴스 생성
+        DataTable dataTable = new DataTable();
+
+//        fileInfo = (FileInfo) jobItm.getItm();
+        dataTable = jobItm.getDataTable();
+
+        String suffix = "";
+
+        // 데이터명 뒤에 날짜 Suffix 처리
+        if(fileInfo.isStreOptn()) {
+            suffix = StringUtil.getTodayaddMonth(fileInfo.getSuffix(), "month", fileInfo.getAddMonth());
+        }
+
+        String fileName = removeFileExtension(fileInfo.getFileName());
+
+        // 생성된 파일 PATH
+//        String path = fileInfo.getPath() + "/" + fileName + suffix + "." + fileInfo.getFileFom();
+        String path = fileInfo.getPath() + "/" + fileName + suffix + ".xlsx"; // 현재 xlsx만 지원
+
+//        String path = "C:\\Taken_BI_Manager" + File.separator + fileName + suffix + "." + fileInfo.getFileFom(); // 테스트 로컬 파일
+
+        // 임시 테이블명 처리
+        jobItm.getDataTable().setDatasetSj("upload");
+
+        // 엑셀파일로 파일 저장
+        XSSFWorkbook xlsWb = null;
+
+        FileOutputStream fileOut = null;
+
+        try {
+//            xlsWb = dataTableService.getDataTableExcelDownload(jobItm.getDataTable());
+            xlsWb = this.getDataTableExcelDownload(jobItm.getDataTable());
+            /*File file = new File(path);
+            FileOutputStream fileOut = new FileOutputStream(file);
+            xlsWb.write(fileOut);
+            fileOut.close();*/
+            try(InputStream inputStream = channelSftp.get(fileInfo.getPath())) {
+                // 임시파일 생성
+//                File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + fileInfo.getExtension());
+                File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), ".xlsx"); // 현재 xlsx만 지원
+                fileOut = new FileOutputStream(tempFile);
+                xlsWb.write(fileOut);
+                xlsWb.close();
+
+                try(InputStream uploadInputStream = new FileInputStream(tempFile.getAbsolutePath())) {
+                    // 파일 업로드
+                    channelSftp.put(uploadInputStream, path, new Monitor());
+                }
+            }
+
+//            channelSftp.put(fileOut.toString(), path, new Monitor());
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요.");
+            customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+        }
+
+        customeResultMap.getResultData().put("dataTableMap", null);
+
+        return customeResultMap;
+    }
+
+    /**
+     * @author 하석형
+     * @since 2024.04.26
+     *
+     * 파일명 확장자 제거
+     */
+    public static String removeFileExtension(String fileName) {
+        // 마지막 '.'의 위치를 찾음
+        int lastIndexOfDot = fileName.lastIndexOf(".");
+
+        // '.'이 없거나 파일명의 맨 마지막에 위치한다면 확장자가 없는 것으로 간주, 원본 문자열 반환
+        if (lastIndexOfDot == -1 || lastIndexOfDot == fileName.length() - 1) {
+            return fileName;
+        }
+
+        // '.' 이전까지의 문자열(확장자 제외)을 반환
+        return fileName.substring(0, lastIndexOfDot);
+    }
+
+    /**
+     * @author 하석형
+     * @since 2024.04.26
+     *
+     * 데이터테이블 엑셀화
+     */
+    public XSSFWorkbook getDataTableExcelDownload (DataTable dataTable) throws Exception {
+        XSSFWorkbook xlsWb = new XSSFWorkbook();
+
+        if(dataTable.getTableNmKr() == null) {
+            dataTable.setTableNmKr("데이터테이블");
+        }
+        Sheet sheet = xlsWb.createSheet(dataTable.getTableNmKr());
+
+        int rowIdx = 0;
+
+        //0행 0열
+        Row row = null;
+        Cell cell = null;
+
+        row = sheet.createRow(rowIdx++);
+        for (int i = 0; i < dataTable.getColumnDatas().size(); i++) {
+            cell = row.createCell(i);
+
+            String columnName = dataTable.getColumnDatas().get(i).getDisplyColumnNm();
+            if (StringUtil.isEmpty(columnName)) {
+                columnName = dataTable.getColumnDatas().get(i).getOrginlColumnNm();
+            }
+
+            cell.setCellValue(columnName);
+            cell.setCellStyle(getCellStyle(xlsWb, "head"));
+        }
+
+        for (int i = 0; i < dataTable.getRowData().size(); i++) {
+            row = sheet.createRow(rowIdx++);
+            for (int j = 0; j < dataTable.getRowData().get(i).size(); j++) {
+                cell = row.createCell(j);
+//                cell.setCellValue(dataTable.getRowData().get(i).get(j));
+                
+                Object value = dataTable.getRowData().get(i).get(j);
+                cell.setCellValue(value.toString());
+            }
+        }
+
+        return xlsWb;
+    }
+
+    public CellStyle getCellStyle(XSSFWorkbook xlsWb, String kind) {
+        CellStyle cellStyle = xlsWb.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.CENTER); //가운데 정렬
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //중앙 정렬
+
+        if(kind.equals("head")) {
+            cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); //노란색
+            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); //색상 패턴처리
+        }
+
+        return cellStyle;
+    }
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/StringUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/StringUtil.java
@@ -0,0 +1,713 @@
+package com.takensoft.taken_bi_manager.common.util;
+
+
+
+import java.io.UnsupportedEncodingException;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.Random;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.web.servlet.server.Encoding.Type;
+
+
+/**
+ * @author 최정우
+ * @since 2019.11.13
+ * 
+ * 문자열과 관련된 기능을 정의 해놓은 Util입니다.
+ */
+public class StringUtil {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(StringUtil.class);
+	
+	public static final String NULL_TEXT = "NULL";
+	
+	public static String toString(Object obj) {
+		if (obj == null) {
+			return null;
+		} else {
+			try {
+				return obj.toString();
+			} catch (Exception e) {
+				return null;
+			}
+		}
+	}
+	
+	public static String toStringNotNull(Object obj) {
+		if (obj == null) {
+			return "";
+		} else {
+			try {
+				return obj.toString();
+			} catch (Exception e) {
+				return "";
+			}
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.11.26
+     * 
+     * 객체를 문자열로 바꾼 후, 문자열 길이 반환
+     */
+	public static int stringLength(Object obj) {
+		if (obj == null) {
+			return 0;
+		} else {
+			try {
+				return obj.toString().length();
+			} catch (Exception e) {
+				return 0;
+			}
+		}
+	}
+	
+	/**
+     * @author 최정우
+     * @since 2020.11.26
+     * 
+     * 문자열이 Null or null or NULL인 경우 실제 null값 세팅 
+     */
+	public static boolean isNullText(String text) {
+		if (isEmpty(text) == false && text.toUpperCase().equals(NULL_TEXT)) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 빈 문자열 검사
+     */
+    public static boolean isEmpty(String text) {
+        return text == null || text.trim().length() == 0;
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * indexOf - 문자 검색 후, 해당 문자의 위치(index)반환
+     */
+    public static int indexOf(String text, String searchText) {
+        if (text == null || searchText == null) {
+            return -1;
+        }
+        return text.indexOf(searchText);
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * lastIndexOf - 문자 검색 후, 해당 문자의 위치(index)반환
+     */
+    public static int lastIndexOf(String text, String searchText) {
+    	if (text == null || searchText == null) {
+            return -1;
+        }
+        return text.lastIndexOf(searchText);
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * substringBetween - 특정 문자열 사이에 값을 뽑아내는 메서드
+     */
+    public static String substringBetween(String text, String startText, String endText) {
+		if (isEmpty(text) == true || isEmpty(startText) == true || isEmpty(endText) == true) {
+			return null;
+		}
+		text = text.toLowerCase();
+		startText = startText.toLowerCase();
+		endText = endText.toLowerCase();
+		
+		int start = text.indexOf(startText);
+		if (start != -1) {
+			int end = text.indexOf(endText, start + startText.length());
+			if (end != -1) {
+				return text.substring(start + startText.length(), end);
+			}
+		}
+		return null;
+	}
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 모든 공백 제거
+     */
+    public static String removeSpace(String text) {
+        if (isEmpty(text)) {
+            return text;
+        }
+        int length = text.length();
+        char[] newCharList = new char[length];
+        int count = 0;
+        for (int i = 0; i < length; i++) {
+            if (Character.isWhitespace(text.charAt(i)) == false) {
+            	newCharList[count++] = text.charAt(i);
+            }
+        }
+        if (count == length) {
+            return text;
+        }
+
+        return new String(newCharList, 0, count);
+    }
+    
+	 
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 소문자 변환
+     */
+    public static String lowerCase(String text) {
+        if (isEmpty(text) == true) {
+            return text;
+        } else {
+        	return text.toLowerCase();
+        }
+    }
+
+    /**
+     * 대문자 변환
+     */
+    public static String upperCase(String text) {
+    	if (isEmpty(text) == true) {
+            return text;
+        } else {
+        	return text.toUpperCase();
+        }
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 현재날짜(년,월,일)를 구하는 기능
+     */
+    public static String getToday() {
+		String pattern = "yyyy-MM-dd";
+		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		Timestamp timestamp = new Timestamp(System.currentTimeMillis());
+		return dateFormat.format(timestamp.getTime());
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 현재날짜(년,월,일)를 구하는 기능
+     */
+    public static String getToday(String pattern) {
+    	String defaultPattern = "yyyy-MM-dd";
+    	if (isEmpty(pattern) == true) {
+    		pattern = defaultPattern;
+    	}
+    	
+    	SimpleDateFormat dateFormat = null;
+		try {
+			dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		} catch (Exception e) {
+			dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA);
+		}
+		Timestamp timestamp = new Timestamp(System.currentTimeMillis());		
+		return dateFormat.format(timestamp.getTime());
+    }
+    
+    
+    /**
+     * @author 김성원
+     * @since 2019.11.13
+     * 
+     * 현재날짜(년,월,일)에 특정 날짜 + -
+     */
+    public static String getTodayaddMonth(String pattern, String type,  int date) {
+    	String defaultPattern = "yyyy-MM-dd";
+    	if (isEmpty(pattern) == true) {
+    		pattern = defaultPattern;
+    	}
+    	
+    	SimpleDateFormat dateFormat = null;
+		try {
+			dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		} catch (Exception e) {
+			dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA);
+		}
+		
+		Timestamp timestamp = new Timestamp(System.currentTimeMillis());		
+		Calendar cal = Calendar.getInstance();
+		if(type.equals("year")) {
+			cal.add(Calendar.YEAR, date);
+		}else if(type.equals("month")) {
+			cal.add(Calendar.MONTH, date);
+		}else if(type.equals("day")) {
+			cal.add(Calendar.DATE, date);
+		}		
+		
+		return dateFormat.format(cal.getTime());
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 현재날짜(년,월,일)를 구하는 기능
+     */
+    public static String getToday(String yearSuffix, String monthSuffix, String daySuffix) {
+    	String defaultPattern = "yyyy년MM월dd일";
+    	if (isEmpty(yearSuffix) == true) {
+    		yearSuffix = "";
+    	}
+    	if (isEmpty(monthSuffix) == true) {
+    		monthSuffix = "";
+    	}
+    	if (isEmpty(daySuffix) == true) {
+    		daySuffix = "";
+    	}
+    	
+    	String pattern = "yyyy" + yearSuffix + "MM" + monthSuffix + "dd" + daySuffix;
+    	
+    	SimpleDateFormat dateFormat = null;
+		try {
+			dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		} catch (Exception e) {
+			dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA);
+		}
+		Timestamp timestamp = new Timestamp(System.currentTimeMillis());
+		return dateFormat.format(timestamp.getTime());
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 17자리의 현재일시를 구하는 기능
+     */
+    public static String getDateTime() {
+		// 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초))
+		String pattern = "yyyyMMddHHmmssSSS";
+		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		Timestamp timestamp = new Timestamp(System.currentTimeMillis());
+		return dateFormat.format(timestamp.getTime());
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 원하는 패턴의 현재일시 구하는 기능
+     */
+    public static String getDateTime(String pattern) {
+    	// 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초))
+    	String defaultPattern = "yyyyMMddHHmmssSSS";
+    	if (isEmpty(pattern)) {
+    		pattern = defaultPattern;
+    	}
+		SimpleDateFormat dateFormat = null;
+		try {
+			dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		} catch (Exception e) {
+			dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA);
+		}
+		Timestamp timestamp = new Timestamp(System.currentTimeMillis());
+		return dateFormat.format(timestamp.getTime());
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 현재 일시 - addDay => 원하는 패턴의 일시를 구하는 기능 
+     */
+    public static String getDateTime(String pattern, int addDay) {
+    	// 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초))
+    	String defaultPattern = "yyyyMMddHHmmssSSS";	
+    	if (pattern == null) {
+    		pattern = defaultPattern;
+    	}
+		SimpleDateFormat dateFormat = null;
+		try {
+			dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		} catch (Exception e) {
+			dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA);
+		}
+		Calendar cal = new GregorianCalendar();
+		cal.add(Calendar.DATE, addDay);
+		Date date = cal.getTime();
+		return dateFormat.format(date.getTime());
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 현재 일시 - addDay => 원하는 패턴의 일시를 구하는 기능 
+     */
+    public static String getDateTime(String pattern, int addDay, int addHour, int addMin, int addSec) {
+    	// 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초))
+    	String defaultPattern = "yyyyMMddHHmmssSSS";	
+    	if (pattern == null) {
+    		pattern = defaultPattern;
+    	}
+		SimpleDateFormat dateFormat = null;
+		try {
+			dateFormat = new SimpleDateFormat(pattern, Locale.KOREA);
+		} catch (Exception e) {
+			dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA);
+		}
+		Calendar cal = new GregorianCalendar();
+		cal.add(Calendar.DATE, addDay);
+		cal.add(Calendar.HOUR, addHour);
+		cal.add(Calendar.MINUTE, addMin);
+		cal.add(Calendar.SECOND, addSec);
+		Date date = cal.getTime();
+		return dateFormat.format(date.getTime());
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 현재 일시(17자리)와, 랜덤숫자(4자리)를 이용하여 키값 생성
+     */
+    public static String getCreateKey (String prefix) {
+		int random = new Random().nextInt(9999);
+		String result = prefix + "_" + getDateTime() + "_" + numberToText(random, 4);
+		return result;
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열이 Date문자열(yyyy-MM-dd)로 포맷 가능한지
+     * text: 문자열
+     * pattern: 문자열의 날짜 패턴
+     */
+    public static boolean isDate(String text, String pattern) {
+    	try {
+    		Date date = new SimpleDateFormat(pattern).parse(text);
+    		text = new SimpleDateFormat("yyyy-MM-dd").format(date);
+        	return true;
+    	} catch (java.text.ParseException e) {
+			// TODO Auto-generated catch block
+			return false;
+		}
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열을 날짜형태로 Convert
+     * text: 문자열
+     * pattern: 문자열의 날짜 패턴
+     * newPattern: 해당 문자열을 Converting할 날짜 패턴 
+     */
+    public static String textToDateText (String text, String pattern, String newPattern) {
+		String defaultPattern = "yyyy-MM-dd";
+		if (isEmpty(newPattern) == true) {
+			newPattern = defaultPattern;
+    	}
+		
+		SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
+		Date date = new Date();
+		try {
+			date = dateFormat.parse(text);
+			dateFormat.applyPattern(newPattern);
+			return dateFormat.format(date);
+        } catch (Exception e) {
+            //e.printStackTrace();
+            return text;
+        }
+	}
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 숫자 -> 문자열 -> 문자열 길이가 length보다 작을 때, length길이 만큼될 수 있도록 앞에 '0'을 붙여줌
+     */
+    public static String numberToText (int number, int length) {
+    	String text = Integer.toString(number);
+    	if (text.length() < length) {
+            int emptyLength = length - text.length();
+            for (int i = 0; i < emptyLength; i++) {
+            	text = "0" + text;
+            }
+        }
+        return text;
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열이 지정한 길이를 초과했을때 해당 문자열을 삭제하는 메서드
+     * @param text 원본 문자열 배열
+     * @param maxLength 지정길이
+     * @return 지정길이로 자른 문자열
+     */
+    public static String cutString(String text, int maxLength) {
+        String result = null;
+        if (text != null) {
+            if (text.length() > maxLength) {
+                result = text.substring(0, maxLength);
+            } else
+                result = text;
+        }
+        return result;
+    }
+	
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열이 지정한 길이를 초과했을때 지정한길이에다가 해당 문자열을 붙여주는 메서드.
+     * @param text 원본 문자열 배열
+     * @param addText 더할문자열
+     * @param maxLength 지정길이
+     * @return 지정길이로 잘라서 더할분자열 합친 문자열
+     */
+    public static String cutString(String text, String addText, int maxLength) {
+        String result = null;
+        if (text != null) {
+            if (text.length() > maxLength) {
+            	result = text.substring(0, maxLength) + addText;
+            } else
+            	result = text;
+        }
+        return result;
+    }
+
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * <p>기준 문자열에 포함된 모든 대상 문자(char)를 제거한다.</p>
+     *
+     * <pre>
+     * StringUtil.remove(null, *)       = null
+     * StringUtil.remove("", *)         = ""
+     * StringUtil.remove("queued", 'u') = "qeed"
+     * StringUtil.remove("queued", 'z') = "queued"
+     * </pre>
+     *
+     * @param str  입력받는 기준 문자열
+     * @param remove  입력받는 문자열에서 제거할 대상 문자열
+     * @return 제거대상 문자열이 제거된 입력문자열. 입력문자열이 null인 경우 출력문자열은 null
+     */
+    public static String remove(String text, char remove) {
+        if (isEmpty(text) || text.indexOf(remove) == -1) {
+            return text;
+        }
+        char[] chars = text.toCharArray();
+        int pos = 0;
+        for (int i = 0; i < chars.length; i++) {
+            if (chars[i] != remove) {
+                chars[pos++] = chars[i];
+            }
+        }
+        
+        return new String(chars, 0, pos);
+    }
+
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 원본 문자열의 포함된 특정 문자열을 새로운 문자열로 변환하는 메서드
+     * @param source 원본 문자열
+     * @param subject 원본 문자열에 포함된 특정 문자열
+     * @param object 변환할 문자열
+     * @return sb.toString() 새로운 문자열로 변환된 문자열
+     */
+    public static String replace(String text, String subject, String object) {
+        StringBuffer rtnStr = new StringBuffer();
+        String preStr = "";
+        String nextStr = text;
+        String srcStr  = text;
+
+        while (srcStr.indexOf(subject) >= 0) {
+            preStr = srcStr.substring(0, srcStr.indexOf(subject));
+            nextStr = srcStr.substring(srcStr.indexOf(subject) + subject.length(), srcStr.length());
+            srcStr = nextStr;
+            rtnStr.append(preStr).append(object);
+        }
+        rtnStr.append(nextStr);
+        return rtnStr.toString();
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 원본 문자열의 포함된 특정 문자열 첫번째 한개만 새로운 문자열로 변환하는 메서드
+     * @param source 원본 문자열
+     * @param subject 원본 문자열에 포함된 특정 문자열
+     * @param object 변환할 문자열
+     * @return sb.toString() 새로운 문자열로 변환된 문자열 / source 특정문자열이 없는 경우 원본 문자열
+     */
+    public static String replaceOnce(String source, String subject, String object) {
+        StringBuffer rtnStr = new StringBuffer();
+        String preStr = "";
+        String nextStr = source;
+        if (source.indexOf(subject) >= 0) {
+            preStr = source.substring(0, source.indexOf(subject));
+            nextStr = source.substring(source.indexOf(subject) + subject.length(), source.length());
+            rtnStr.append(preStr).append(object).append(nextStr);
+            return rtnStr.toString();
+        } else {
+            return source;
+        }
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * <code>subject</code>에 포함된 각각의 문자를 object로 변환한다.
+     *
+     * @param source 원본 문자열
+     * @param subject 원본 문자열에 포함된 특정 문자열
+     * @param object 변환할 문자열
+     * @return sb.toString() 새로운 문자열로 변환된 문자열
+     */
+    public static String replaceChar(String source, String subject, String object) {
+        StringBuffer rtnStr = new StringBuffer();
+        String preStr = "";
+        String nextStr = source;
+        String srcStr  = source;
+
+        char chA;
+
+        for (int i = 0; i < subject.length(); i++) {
+            chA = subject.charAt(i);
+
+            if (srcStr.indexOf(chA) >= 0) {
+                preStr = srcStr.substring(0, srcStr.indexOf(chA));
+                nextStr = srcStr.substring(srcStr.indexOf(chA) + 1, srcStr.length());
+                srcStr = rtnStr.append(preStr).append(object).append(nextStr).toString();
+            }
+        }
+
+        return srcStr;
+    }
+
+    /**
+     * @author 최정우
+     * @since 2019.11.13
+     * 
+     * 문자열을 다양한 문자셋(EUC-KR[KSC5601],UTF-8..)을 사용하여 인코딩하는 기능 역으로 디코딩하여 원래의 문자열을
+     * 복원하는 기능을 제공함 String temp = new String(문자열.getBytes("바꾸기전 인코딩"),"바꿀 인코딩");
+     * String temp = new String(문자열.getBytes("8859_1"),"KSC5601"); => UTF-8 에서
+     * EUC-KR
+     *
+     * @param text - 문자열
+     * @param encoding - 원래의 인코딩된 값
+     * @param decoding - 디코딩할 문자값
+     * @return 인(디)코딩 문자열
+     * @exception MyException
+     * @see
+     */
+    public static String textDecoding(String text, String encoding, String decoding) {
+		if (text == null) {
+			return null;
+		}
+	
+		try {
+			text = new String(text.getBytes(encoding), decoding);
+		} catch (UnsupportedEncodingException e) {
+			text = null;
+		}
+	
+		return text;
+    }
+    
+    
+    /**
+     * @author 최정우
+     * @since 2020.11.26
+     * 
+     * 문자열 특정 포맷팅으로 변환 ##-####
+     */
+    public static String formatConvert(String data, String format) {
+		
+    	StringBuilder bf = new StringBuilder();
+		
+    	if(StringUtil.isEmpty(format) || StringUtil.isEmpty(data)) {
+    		bf.append(data);
+    	}else {
+    		int num =  data.length()-1;    		
+    		for(int i = format.length()-1 ; i >= 0 ; i--) {
+    			if(format.charAt(i) == '#') {
+    				bf.insert(0, data.charAt(num--));
+    			}else {
+    				bf.insert(0,format.charAt(i));
+    			}
+    		}
+    	}
+		
+		return bf.toString();
+	}
+    
+    /**
+     * @author 김성원
+     * @since 2022.07.06
+     * 
+     * 날짜형식 문자열  특정 포맷팅으로 변환 ##-####
+     */
+    public static String dateConvert(String date) {
+    	
+    	StringBuilder bf = new StringBuilder();
+    	
+    	boolean dateForm = true;
+    	
+    	if(!date.contains("-") && date.length() > 4) {
+    		dateForm = false;
+    	}
+    	
+    	if(!StringUtil.isEmpty(date)) {
+    	
+    		String dateStr =  date.replaceAll("[^0-9]", "");
+    		// 년도 처리 
+    		if(dateStr.length() < 5) {
+    			bf.append(date.substring(0,4));
+    		}else {
+    			if(dateForm == true) {
+    				bf.append(StringUtil.formatConvert(dateStr.substring(0,6),"####-##"));
+    			}else {
+    				bf.append(StringUtil.formatConvert(dateStr.substring(0,6),"####-##"));
+    				//bf.append(dateStr.substring(0,4));
+    				//bf.append("년 ");
+    			}
+    		}
+    	}    
+		
+		return bf.toString();
+	}
+    
+    
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/bean/ApplicationContextProvider.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/bean/ApplicationContextProvider.java
@@ -0,0 +1,45 @@
+package com.takensoft.taken_bi_manager.common.util.bean;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 최정우
+ * @since 2019.11.17
+ * 
+ * Spring 컨테이너(ApplicationContext)에 접근하기 위한 Class 입니다.
+ * ApplicationContextAware 구현체
+ */
+@Component
+public class ApplicationContextProvider implements ApplicationContextAware {
+    
+	/**
+	 * 해당 어플리케이션의 인스턴스(bean)들의 정보를 담은 객체 
+	 */
+    private static ApplicationContext applicationContext;
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.17
+     * 
+     * ApplicationContextAware를 구현하기 위한 메소드
+     * Spring 구동 시, 해당 Class가 스캔 당하면 applicationContext 객체가 생성됨
+     */
+    @Override
+    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+        applicationContext = ctx;
+    }
+    
+    /**
+     * @author 최정우
+     * @since 2019.11.17
+     * 
+     * applicationContext 객체 호출
+     */
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+ 
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/util/bean/BeanUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/bean/BeanUtil.java
@@ -0,0 +1,42 @@
+package com.takensoft.taken_bi_manager.common.util.bean;
+
+import org.springframework.beans.BeansException;
+
+/**
+ * @author 최정우
+ * @since 2020.11.25
+ * 
+ * ApplicationContextProvider에서 bean객체를 얻어 활용할 수 있도록 해주는 Util 입니다.
+ */
+public class BeanUtil {
+
+	/**
+     * @author 최정우
+     * @since 2019.11.17
+     * 
+     * 해당 어플리케이션에서 스프링 컨테이너가 관리하는 bean으로 등록된 객체를 이름으로 호출
+     */
+    public static Object getBean(String beanName) {
+    	try {
+    		return ApplicationContextProvider.getApplicationContext().getBean(beanName);
+    	} catch (BeansException e) {
+    		e.printStackTrace();
+    		return null;
+    	}
+    }
+	
+    /**
+     * @author 최정우
+     * @since 2019.11.17
+     * 
+     * 해당 어플리케이션에서 스프링 컨테이너가 관리하는 bean으로 등록된 객체를 객체의 타입으로 호출
+     */
+	public static Object getBean(Class<?> classType) {
+		try {
+    		return ApplicationContextProvider.getApplicationContext().getBean(classType);
+    	} catch (BeansException e) {
+    		e.printStackTrace();
+    		return null;
+    	}
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/util/reflection/ParentLastURLClassLoader.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/reflection/ParentLastURLClassLoader.java
@@ -0,0 +1,88 @@
+package com.takensoft.taken_bi_manager.common.util.reflection;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/*
+ * 커스텀 URLClassLoder
+ * 
+ * WAS(톰캣)에서 URLClassLoder로 작동시 외부 라이브러리에 있는 jar파일을 읽지 못함
+ * 외부 라이브러리 class들을 먼저 읽기 위함
+ */
+public class ParentLastURLClassLoader extends ClassLoader
+{
+    private ChildURLClassLoader childClassLoader;
+
+    /**
+     * This class allows me to call findClass on a classloader
+     */
+    private static class FindClassClassLoader extends ClassLoader
+    {
+        public FindClassClassLoader(ClassLoader parent)
+        {
+            super(parent);
+        }
+
+        @Override
+        public Class<?> findClass(String name) throws ClassNotFoundException
+        {
+            return super.findClass(name);
+        }
+    }
+
+    /**
+     * This class delegates (child then parent) for the findClass method for a URLClassLoader.
+     * We need this because findClass is protected in URLClassLoader
+     */
+    private static class ChildURLClassLoader extends URLClassLoader
+    {
+        private FindClassClassLoader realParent;
+
+        public ChildURLClassLoader(URL[] urls, FindClassClassLoader realParent )
+        {
+            super(urls, null);
+
+            this.realParent = realParent;
+        }
+
+        @Override
+        public Class<?> findClass(String name) throws ClassNotFoundException
+        {
+            try
+            {
+                // first try to use the URLClassLoader findClass
+                return super.findClass(name);
+            }
+            catch( ClassNotFoundException e )
+            {
+                // if that fails, we ask our real parent classloader to load the class (we give up)
+                return realParent.loadClass(name);
+            }
+        }
+    }
+
+    //List<URL> classpath
+    public ParentLastURLClassLoader(URL[] urls)
+    {
+        super(Thread.currentThread().getContextClassLoader());
+
+        //URL[] urls = classpath.toArray(new URL[classpath.size()]);
+
+        childClassLoader = new ChildURLClassLoader( urls, new FindClassClassLoader(this.getParent()) );
+    }
+
+    @Override
+    protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
+    {
+        try
+        {
+            // first we try to find a class inside the child classloader
+            return childClassLoader.findClass(name);
+        }
+        catch( ClassNotFoundException e )
+        {
+            // didn't find it, try the parent
+            return super.loadClass(name, resolve);
+        }
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/util/reflection/ReflectionUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/reflection/ReflectionUtil.java
@@ -0,0 +1,220 @@
+package com.takensoft.taken_bi_manager.common.util.reflection;
+
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+import com.takensoft.taken_bi_manager.common.util.bean.BeanUtil;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+
+/**
+ * @author 최정우
+ * @since 2020.11.25
+ * 
+ * Reflection - 클래스, 인터페이스, 메소드관련 인스턴스화(로드) 및 실행 관련 Util입니다.
+ */
+public class ReflectionUtil {
+	
+	/******************************************** Class 단 ********************************************/
+	/**
+     * @author 최정우
+	 * @since 2020.11.25 
+     *
+     * classLoad - 어플리케이션 내부(+Bean객체포함) OR 외부의 class 파일을 저장된 경로를 통해  class 파일 로드 후, 객체 생성
+     * 
+	 * classFullName과 classFilePath를 통해 실제 클래스를 인스턴스화함.
+	 * 1. Class.forName을 통해 어플리케이션 내부의 class path에 있는 class객체 생성
+	 * 2. 어플리케이션 내부에 class가 존재할 때
+	 * 		2-1. 어플리케이션의 Spring 컨테이너에 해당 클래스 타입으로 생성된 Bean이 있는지 확인
+	 * 			=> 존재할 때, Bean 객체 주입
+	 * 			=> 존재하지 않을 때, 객체 생성
+	 * 3. 어플리케이션 내부에 class가 존재하지 않을 때
+	 * 		3-1. class or jar file이 저장된 경로를 이용하여 클래스를 로드 
+	 * 
+	 * 4. 객체 생성 실패시, Log 기록 및 다음 작업 목록으로 넘어감
+	 */
+    public static Object classAndBeanLoad (String classFilePath, String classFullName) {
+    	Object clazz = null;
+    	try {
+    		//Class.forName을 통해 어플리케이션 내부의 class path에 있는 class객체 생성
+			Class<?> c = forName(classFullName);
+			if (c != null) {//어플리케이션 내부에 class가 존재할 때
+				//플리케이션의 Spring 컨테이너에 해당 클래스 타입으로 생성된 Bean이 있는지 확인 후, Bean 객체 주입
+				clazz = BeanUtil.getBean(c);
+				
+				if (clazz == null) {//Bean 객체 존재하지 않을 때
+					clazz = newInstance(c);
+				}
+			} else {//어플리케이션 내부에 class가 존재하지 않을 때
+				//class or jar file이 저장된 경로
+				//file 경로 값이 있을 때만 클래스를 로드함
+				if (StringUtil.isEmpty(classFilePath) == false) {
+					if (StringUtil.isEmpty(classFullName) == false) {
+						clazz = classLoad(classFilePath, classFullName);
+					} else {
+						clazz = classLoad(classFilePath);
+					}
+				}
+			}
+    	} catch (Exception e) {
+    		e.printStackTrace();
+    	}
+    	
+    	return clazz;
+    }
+	
+	/**
+     * @author 최정우
+	 * @since 2019.11.17
+     * 
+     * forName - 어플리케이션 내부의 class path에 있는 class객체 생성
+     * 
+     * classFullName = package명 + class명
+     */
+    public static Class<?> forName (String classFullName) {
+    	try {
+    		return Class.forName(classFullName);
+    	} catch (Exception e) {
+    		e.printStackTrace();
+    		return null;
+    	} 
+    }
+    
+    /**
+     * @author 최정우
+	 * @since 2019.11.17 
+     *
+     * classLoad - 어플리케이션 내부 OR 외부의 class 파일을 저장된 경로를 통해  class 파일 로드 후, 객체 생성
+     * 주로 외부 class파일을 로드할 때 쓰임
+     * 
+     * classFilePath - 클래스파일 절대경로
+     * classFullName = package명 + class명
+     */
+    public static Object classLoad (String classFilePath, String classFullName) {
+    	try {
+    		File file = new File(classFilePath);
+    		//실제 경로상에 있는 .class파일을 통해 class를 읽어옴
+    		ParentLastURLClassLoader classLoader = new ParentLastURLClassLoader(new URL[] { file.toURI().toURL() });
+    		//읽어온 .class파일을 이용해 해당되는  패키지 내에 있는 class를 로드해 옴
+    		Class<?> c = classLoader.loadClass(classFullName);
+    		//class를 new 객체 생성함
+    		return newInstance(c);
+    	} catch (Exception e) {
+    		e.printStackTrace();
+    		return null;
+    	}
+    }
+    
+    /**
+     * @author 최정우
+	 * @since 2019.11.17
+     * 
+     * classLoad - 어플리케이션 내부 OR 외부의 class 파일을 저장된 경로를 통해  class 파일 로드 후, 객체 생성
+     * 주로 외부 class파일을 로드할 때 쓰임
+     * class명을 모를 때 사용
+     * 
+     * classFilePath - 클래스파일 절대경로
+     */
+    public static Object classLoad (String classFilePath) {
+    	try {
+    		File file = new File(classFilePath);
+    		//실제 경로상에 있는 .class파일을 통해 class를 읽어옴
+    		ParentLastURLClassLoader classLoader = new ParentLastURLClassLoader(new URL[] { file.toURI().toURL() });
+    		//읽어온 .class파일을 이용해 해당되는  패키지 내에 있는 class를 로드해 옴
+    		Class<?> c = classLoader.getClass();
+    		//class를 new 객체 생성함
+    		return newInstance(c);
+    	} catch (Exception e) {
+    		e.printStackTrace();
+    		return null;
+    	}
+    }
+    
+    /**
+     * @author 최정우
+	 * @since 2019.11.17
+     * 
+     * newInstance - 객체 인스턴스화(로드)
+     */
+    public static Object newInstance(Class<?> c) {
+    	try {
+			return c.newInstance();
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+    }
+    
+    /******************************************** Class 단 ********************************************/
+    
+    
+    
+    /******************************************** Method 단 ********************************************/
+    /**
+     * @author 최정우
+	 * @since 2019.11.17
+     * 
+     * invokeByMethodName - 메소드 이름을 통한 메소드 호출
+     * 
+     * clazz - 인스턴스화(로드)된 객체
+     * methodName - 메소드명
+     * paramValues - 메소드의 파라메터 값
+     * paramTypes - 메소드의 파라메터 타입
+     * (주의 paramValues, paramTypes 순서가 같아야함)
+     */
+	public static Object invokeByMethodName (Object clazz, String methodName, Object[] paramValues, Class<?>[] paramTypes) throws Exception {
+		try {
+			Method method = null;
+			if (paramValues != null && paramTypes != null
+					&& paramValues.length > 0 && paramTypes.length > 0
+					&& paramValues.length == paramTypes.length) {
+
+
+				if (paramValues != null && paramValues.length > 0) {
+
+				}
+
+				//메소드 객체 가지고오기
+				method = clazz.getClass().getMethod(methodName, paramTypes);
+			} else {
+				//메소드 객체 가지고오기
+				method = clazz.getClass().getMethod(methodName);
+			}
+
+			//메소드 호출
+			return invoke(clazz, method, paramValues);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new Exception(e);
+		}
+
+	}
+
+	/**
+	 * @author 최정우
+	 * @since 2019.11.17
+	 *
+	 * invoke - 메소드 호출
+	 *
+	 * clazz - 인스턴스화(로드)된 객체
+	 * method - 메소드 객체
+	 * paramValues - 메소드의 파라메터 값
+	 */
+	public static Object invoke (Object clazz, Method method, Object[] paramValues) throws Exception {
+		try {
+			if (paramValues != null && paramValues.length > 0) {
+				//메소드 호출
+				return method.invoke(clazz, paramValues);
+			} else {
+				//메소드 호출
+				return method.invoke(clazz);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new Exception(e);
+		}
+
+	}
+    /******************************************** Method 단 ********************************************/
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/CheckMessage.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CheckMessage.java
@@ -0,0 +1,81 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.01.04
+ * 
+ * 데이터 체크, 유효성 검사 등과 같이 검사와 관련된 변수를 정의한 Class 입니다.
+ */
+@Getter
+@Setter
+public class CheckMessage {
+	
+	public CheckMessage() {}
+	
+	public CheckMessage(boolean isSuccess) {
+		this.isSuccess = isSuccess;
+	}
+	
+	public CheckMessage(String message) {
+		this.message = message;
+	}
+	
+	public CheckMessage(boolean isSuccess, String message) {
+		this.isSuccess = isSuccess;
+		this.message = message;
+	}
+	
+	public CheckMessage(boolean isSuccess, String message, int status) {
+		this.isSuccess = isSuccess;
+		this.message = message;
+		this.status = status;
+	}
+	
+	public CheckMessage(boolean isSuccess, String message, String error) {
+		this.isSuccess = isSuccess;
+		this.message = message;
+		this.error = error;
+	}
+	
+	/**
+	 * 체크 완료(사용가능 or 성공) 여부
+	 */
+	private boolean isSuccess;
+	
+	/**
+	 * 체크한 상태의 메세지값
+	 */
+	private String message;
+	
+	/**
+	 * 에러 메세지
+	 */
+	private String error;
+	
+	/**
+	 * 체크한 상태의 상태값 -> 상황마다 다름
+	 */
+	private int status;	
+	
+	
+	// 오류처리
+	public void setError(String message) {	
+		this.message = message;
+		this.error = message;
+		this.isSuccess = false;
+		this.status = 0;
+	}
+
+	// 오류처리(에러코드 추가)
+	public void setError(String message, int errorCode) {
+		this.message = message;
+		this.error = message;
+		this.isSuccess = false;
+		this.status = errorCode;
+	}
+
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/CommonVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CommonVO.java
@@ -0,0 +1,139 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+
+import lombok.Getter;
+import lombok.Setter;
+
+
+
+/**
+ * @author 김성원
+ * @since 2024.01.09
+ * 
+ * 공통 검색 VO 입니다.(상속받으세요)
+ */
+@Getter
+@Setter
+public class CommonVO {
+
+	/**************************** 공통 ****************************/
+	/**
+	 * 검색조건
+	 */
+	private String searchCondition = "";
+
+	/**
+	 * 검색Keyword
+	 */
+	private String searchKeyword = "";
+	
+	/**
+	 * 검색Keyword
+	 */
+	private List<String> searchKeywordList = new ArrayList<String>();
+
+	/** 
+	 * 검색사용여부
+	 */
+	private String searchUseYn = "";
+  
+	/** 
+	 * 검색 시작일
+	 */
+	private String startDate = "";
+  
+	/** 
+	 * 검색 종료일
+	 */
+	private String endDate = "";
+	
+	/** 
+	 * 정렬 기준 (컬럼명)
+	 */
+	private String order = "";
+	
+	/** 
+	 * 정렬 타입
+	 * true - ASC
+	 * false - DESC
+	 */
+	private boolean isOrderASC = true;
+
+	/** 
+	 * 현재페이지
+	 */
+	private int currentPage = 1;
+
+	/** 
+	 * 페이지갯수
+	 */
+	private int perPage = 10;
+	
+	/** 
+	 * 총 개시물 수
+	 */
+	private int totalRows;
+	
+	/** 
+	 * 페이징 사용 유무
+	 */
+	private boolean isUsePaging = true;
+	
+	/** firstIndex */
+	private int firstIndex = 1;
+
+	/** lastIndex */
+	private int lastIndex = 1;
+	
+	/** 페이지사이즈 */
+	private int pageSize = 10;
+	
+	/** recordCountPerPage */
+	private int recordCountPerPage = 10;	  
+	
+	
+	public boolean getIsUsePaging() {
+		return isUsePaging;
+	}
+
+	public void setIsUsePaging(boolean isUsePaging) {
+		this.isUsePaging = isUsePaging;
+	}
+	/**************************** 공통 ****************************/
+	
+	/**************************** 검색어 분할 ****************************/
+	
+
+	public void setSearchKeywordList(List<String> searchKeywordList) {
+		this.searchKeywordList = searchKeywordList;
+	}
+	/**************************** 검색어 분할 ****************************/
+	
+	/**************************** 데이터베이스 별 페이징 ****************************/
+
+	
+	private int startIndex;
+	
+	/** 
+	 * 마지막 게시물의 인덱스 번호 (변환과정없음, 0부터 시작)
+	 */
+	private long limit = 0;
+	
+
+	public void searchClear() {
+		searchCondition = "";
+		searchKeyword = "";
+		searchUseYn = "";
+		startDate = "";
+		endDate = "";
+		order = "";
+	}
+	
+	/**************************** 데이터베이스 별 페이징 ****************************/
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/CustomeResultMap.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CustomeResultMap.java
@@ -0,0 +1,28 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.HashMap;
+
+/**
+ * 컨트롤러의 데이터를 반환할 기본 Map클래스
+ *
+ * @author 김성원
+ * @since 2023.12.28
+ */
+@Getter
+@Setter
+public class CustomeResultMap {
+
+    // 결과메세지
+    private CheckMessage checkMessage;
+    
+    // 결과 데이터 
+    private HashMap<String,Object> resultData = new HashMap<String,Object>();
+
+    public CustomeResultMap(){
+        checkMessage = new CheckMessage(true, "성공" , 200);
+    }
+
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/EditVo.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/EditVo.java
@@ -0,0 +1,28 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2022.01.18
+ * 
+ * 에디트 관련 상속 테이블 입니다.
+ */
+
+@Getter
+@Setter
+public class EditVo {
+
+	// 현재 스탯  1 = 기본 2 = 에디트 3 = 삭제
+	private int status = 1;
+	
+	
+	// 에디트 가능여브
+	private boolean enableEdit = false;
+
+	// 변경데이터 
+	private Object orgData;
+
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/PopupManage.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/PopupManage.java
@@ -0,0 +1,18 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.03.22
+ *
+ * 팝업관리 VO 객체
+ */
+@Getter
+@Setter
+public class PopupManage {
+
+    // 팝업 오픈관리
+    private boolean opener;
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchObject.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchObject.java
@@ -0,0 +1,44 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author 김성원
+ * @since 2024.01.09
+ * 
+ * 공통 검색용 VO 입니다
+ */
+@Getter
+@Setter
+public class SearchObject {
+	
+	/**
+	 * 검색 key
+	 */
+	private String key;
+
+	/**
+	 * 검색 값
+	 */
+	private Object value;
+	
+	
+	/**
+	 * 검색 key
+	 */
+	private String key2;
+
+	/**
+	 * 검색 값
+	 */
+	private Object value2;
+	
+	
+	/** 
+	 * 데이터 타입(날짜 : date, 숫자 : int, 문자 : string, 체크 : bool, 날짜쌍 : dates)
+	 */
+	private String type;
+
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchVO.java
@@ -0,0 +1,73 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.*;
+
+/**
+ * @author 김성원
+ * @since 2024.01.09
+ * 
+ * 공통 검색 VO 입니다
+ */
+@Getter
+@Setter
+public class SearchVO {
+	/**
+	 * 검색Keyword
+	 */
+	private List<SearchObject> searchObjectList = new ArrayList<SearchObject>();
+
+	/** 
+	 * 정렬 기준 (컬럼명)
+	 */
+	private String order = "";
+
+	/** 
+	 * 정렬 타입
+	 * true - ASC
+	 * false - DESC
+	 */
+	private boolean orderASC = true;
+	
+	/** 
+	 * 현재페이지
+	 */
+	private int currentPage = 1;
+
+	/** 
+	 * 페이지갯수
+	 */
+	private int perPage = 10;
+
+	/**
+	 * 총 개시물 수
+	 */
+	private int totalRows;
+
+	/**
+	 * 검색 key
+	 */
+	private String searchText;
+
+	/**
+	 * 검색 값
+	 */
+	private Object value;
+
+	/**
+	 * 검색 key
+	 */
+	private String key2;
+
+	/**
+	 * 검색 값
+	 */
+	private Object value2;
+
+	/**
+	 * 데이터 타입(날짜 : date, 숫자 : int, 문자 : string, 체크 : bool, 날짜쌍 : dates)
+	 */
+	private String type;
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/common/vo/SystemCode.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SystemCode.java
@@ -0,0 +1,579 @@
+package com.takensoft.taken_bi_manager.common.vo;
+
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import com.sun.jna.platform.win32.Sspi.TimeStamp;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.util.CommonUtil;
+import com.takensoft.taken_bi_manager.common.util.StringUtil;
+
+
+
+
+public class SystemCode {
+
+	//191자 => mariaDB에서 indexing가능한 최대 크기 765Byte/한글 4Byte(utf8mb4) 
+	public final static int DEFAULT_VARCHAR_SIZE = 191;
+		
+	//mariaDB에서 indexing가능한 varchar 최대 크기 765Byte
+	public final static int MAX_VARCHAR_SIZE = 765;
+	
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.11.13
+	 * 
+	 * 데이터 타입을 정의한 상수 Class 입니다.
+	 * 상수명(java데이터타입, 초기값, mysql데이터타입, display데이터타입
+	 */
+	public enum DataType {
+		NULL(null, null)
+		, BYTE(Byte.class, 0)
+		, BOOL(Boolean.class, false)
+		, CHAR(Character.class, '\u0000')
+		, STRING(String.class, "")
+		, SHORT(Short.class, 0)
+		, INT(Integer.class, 0)
+		, DECIMAL(BigDecimal.class,0)
+		, LONG(Long.class, 0)
+		, FLOAT(Float.class, 0.0)
+		, DOUBLE(Double.class, 0.0)
+		, DATE(Date.class, "")
+		, DATETIME(Date.class, "")
+		, TIMESTAMP(Timestamp.class, "")
+		, ENTER(Character.class,'\n');
+
+		/**
+		 * enum(열거형데이터)의 생성자 
+		 * 1. 상수에 나열된 parameter와 형태가 똑같이 만들어줘야함.
+		 * 2. 접근제한자는 private로만 다른 접근제한자는 허용하지 않음
+		 */
+		private DataType (Class<?> javaType, Object iniValue) {
+	        this.javaType = javaType;
+	        this.initValue = iniValue;
+	    }
+		
+		/**
+		 * java데이터타입
+		 */
+		final private Class<?> javaType;
+		
+		/**
+		 * 초기값
+		 */
+		final private Object initValue;
+		
+	    public Class<?> getJavaType() {
+	        return javaType;
+	    }
+	    public Object getInitValue() {
+	        return initValue;
+	    }
+	    	 
+	    
+	    /**
+		 * 데이터 타입 검사, DataType 조회
+		 */
+	    public static Map<DataType, String> getDataTypeList () {
+	    	Map<DataType, String> info = new LinkedHashMap<DataType, String>();
+	    	info.put(STRING, "문자열");
+	    	info.put(LONG, "정수");
+	    	info.put(DOUBLE, "실수");
+	    	info.put(DATE, "날짜");
+	    	info.put(DATETIME,"날짜,시간");
+	    	return info;
+		}
+	    
+	    
+	    /**
+		 * 데이터 타입 검사, DataType 조회
+		 */
+	    public static List<DataType> getDataTypeArray () {
+	    	List<DataType> info = new ArrayList<DataType>();
+	    	info.add(STRING);
+	    	info.add(LONG);
+	    	info.add(DOUBLE);
+	    	info.add(DATE);
+	    	info.add(DATETIME);
+	    	info.add(BOOL);
+	    	return info;
+		}
+	    
+	    /**
+		 * 데이터 타입 검사, DataType 조회
+		 */
+	    public static DataType getDataType (String text) {
+	    	/*
+	    	 * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정
+	    	 * 
+	    	 * 
+	    	 * 전화번호 정규식*/
+	    	String regExp = "^\\d{2,3}-\\d{3,4}-\\d{4}$";
+	    	String regDateTime = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) (0[1-9]|1[0-9]|2[0-4]):(0[1-9]|[1-5][0-9]):(0[1-9]|[1-5][0-9])";
+	    	String regDate = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])";
+	    			
+			if(StringUtil.isEmpty(text)) {
+				return NULL;
+			} else if(CommonUtil.isLong(text)) {
+				/*
+				 * 숫자로 변환 가능 하지만 앞에 '0'이 붙어 있으면 문자열로 봄
+				 * ex) 0102 -> String, 1102 -> Long
+				 */
+				if (text.length() > 1 && text.indexOf("0") == 0) {
+					return STRING;
+				} else {
+					return LONG;
+				}
+			}else if(CommonUtil.isDouble(text)) {
+				
+				return DOUBLE;
+				
+			} else if (CommonUtil.isDate(text)) {
+				/*
+		    	 * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정
+		    	 * 
+		    	 * 
+		    	 * 전화번호 정규식*/
+		    	boolean expResult = Pattern.matches(regExp, text);
+		    	boolean dateTimeResult = Pattern.matches(regDateTime, text);
+		    	boolean dateResult = Pattern.matches(regDate, text);
+		    	
+				if(expResult) {
+					return STRING;
+				}else if(dateResult) {				
+					return DATE;
+				}else {
+					return DATETIME;
+				}
+				
+			} else {
+				return STRING;
+			}
+		}
+	    
+	    /**
+		 * 데이터 타입 검사, dbDataType 조회
+		 */
+	    public static String convertDbDataType (DataType datatype, Integer size) {
+	    	if (datatype == STRING) {
+	    		if (size == null || size <= MAX_VARCHAR_SIZE) {
+	    			return "varchar";
+	    		} else {
+	    			return "text";
+	    		}
+	    	} else if (datatype == DATE) {
+	    		return "date";
+	    	} else if (datatype == DATETIME){
+	    		return "datetime";
+	    	} else if (datatype == LONG) {
+	    		return "bigint";
+	    	} else if (datatype == DOUBLE) {
+	    		return "double";
+	    	} else {
+	    		return "varchar";
+	    	}
+	    }
+	    
+	    /**
+		 * 데이터 타입 검사, dbDataType -> javaType 조회
+		 */
+	    public static DataType convertDataTypeDbtoJava (DataType datatype, Integer size) {
+	    	
+	    	
+	    	return null;	    	
+	    }
+	    
+	    
+	    /**
+		 * 데이터 타입 형태로 값 변경
+		 */
+		public static Object parse(DataType dataType, Object value) {
+			if (CommonUtil.isNull(value) == true) {
+				return null;
+			}
+			
+			Class<?> javaType = dataType.getJavaType();
+			try {
+				if (javaType.getSimpleName().equals("Byte")) {
+					return Byte.parseByte(value.toString());
+				} else if (javaType.getSimpleName().equals("Boolean")) {
+					return Boolean.parseBoolean(value.toString());
+				} else if (javaType.getSimpleName().equals("Character")) {
+					return value.toString().toCharArray();
+				} else if (javaType.getSimpleName().equals("String")) {
+					return value.toString();
+				} else if (javaType.getSimpleName().equals("Short")) {
+					//Short.parseShort(value.toString().replaceAll("[^0-9]",""));
+					return Short.parseShort(value.toString());
+				} else if (javaType.getSimpleName().equals("Integer")) {
+					//Integer.parseInt(value.toString().replaceAll("[^0-9]",""));
+					return Integer.parseInt(value.toString());
+				} else if (javaType.getSimpleName().equals("Long")) {
+					//Long.parseLong(value.toString().replaceAll("[^0-9]",""));
+					return Long.parseLong(value.toString());
+				} else if (javaType.getSimpleName().equals("Float")) {
+					//Float.parseFloat(value.toString().replaceAll("[^0-9]",""));
+					return Float.parseFloat(value.toString());
+				} else if (javaType.getSimpleName().equals("Double")) {
+					//Double.parseDouble(value.toString().replaceAll("[^0-9]",""));
+					return Double.parseDouble(value.toString());
+				} else {
+					return value;
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+				return dataType.getInitValue();
+			}
+		}
+		
+		/**
+		 * 데이터 타입 형태로 값 변경
+		 */
+		public static boolean parseCheck (DataType dataType, Object value) {
+			if (CommonUtil.isNull(value) == true) {
+				return false;
+			}
+			
+			Class<?> javaType = dataType.getJavaType();
+			try {
+				if (javaType.getSimpleName().equals("Byte")) {
+					Byte.parseByte(value.toString());
+				} else if (javaType.getSimpleName().equals("Boolean")) {
+					Boolean.parseBoolean(value.toString());
+				} else if (javaType.getSimpleName().equals("Character")) {
+					value.toString().toCharArray();
+				} else if (javaType.getSimpleName().equals("String")) {
+					value.toString();
+				} else if (javaType.getSimpleName().equals("Short")) {
+					//Short.parseShort(value.toString().replaceAll("[^0-9]",""));
+					Short.parseShort(value.toString());
+				} else if (javaType.getSimpleName().equals("Integer")) {
+					//Integer.parseInt(value.toString().replaceAll("[^0-9]",""));
+					Integer.parseInt(value.toString());
+				} else if (javaType.getSimpleName().equals("Long")) {
+					//Long.parseLong(value.toString().replaceAll("[^0-9]",""));
+					Long.parseLong(value.toString());
+				} else if (javaType.getSimpleName().equals("Float")) {
+					//Float.parseFloat(value.toString().replaceAll("[^0-9]",""));
+					Float.parseFloat(value.toString());
+				} else if (javaType.getSimpleName().equals("Double")) {
+					//Double.parseDouble(value.toString().replaceAll("[^0-9]",""));
+					Double.parseDouble(value.toString());
+				}
+				
+				return true;
+			} catch (Exception e) {
+				//e.printStackTrace();
+				return false;
+			}
+		}
+	    
+	}
+
+	/**
+	 * @author 최정우
+	 * @since 2019.12.03
+	 *
+	 * 데이터 셋의 타입을 정의한 상수 Class 입니다.
+	 */
+	public enum DatasetType {
+		RAW("raw_")
+		, TRANSFORM("transform_");
+
+		DatasetType(String prefix) {
+			this.prefix = prefix;
+		}
+
+		/**
+		 * prefix
+		 */
+		final String prefix;
+
+		/**
+		 * prefix 조회
+		 */
+		public String getPrefix () {
+			return prefix;
+		}
+
+		/**
+		 * 데이터 셋의 타입 목록 조회
+		 */
+		public static Map<DatasetType, String> getDatasetTypeList () {
+			Map<DatasetType, String> info = new LinkedHashMap<DatasetType, String>();
+			DatasetType[] array = DatasetType.values();
+			for (int i = 0; i < array.length; i++) {
+				info.put(array[i], array[i].getPrefix());
+			}
+			return info;
+		}
+	}
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.11.20
+	 * 
+	 * 데이터 베이스 타입별 상수를 정의
+	 */
+	public enum DatabaseType {
+		MYSQL("MySql", "com.mysql.jdbc.Driver", "jdbc:mysql://", "3306", "allowMultiQueries=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC")
+		, MARIADB("MariaDB", "org.mariadb.jdbc.Driver", "jdbc:mariadb://", "3306", "")
+		, ORACLE("Oracle", "oracle.jdbc.OracleDriver", "jdbc:oracle:thin:@", "1521", "useUnicode=true&characterEncoding=UTF-8")
+		, MSSQL("MS-SQL", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://", "1433", "trustServerCertificate=true")
+		, TIBERO("Tibero", "com.tmax.tibero.jdbc.TbDriver", "jdbc:tibero:thin:@", "8629", "")
+		, POSTGRESQL("PostgreSql", "org.postgresql.Driver", "jdbc:postgresql://", "5432", "");
+		
+		private DatabaseType(String value, String driverClassName, String baseUrl, String defalutPort, String option) {
+			this.value = value;
+			this.driverClassName = driverClassName;
+			this.baseUrl = baseUrl;
+			this.defalutPort = defalutPort;
+			this.option = option;
+		}
+		
+		/**
+		 * 한글값
+		 */
+		final private String value;
+		
+		/**
+		 * 드라이버 클래스
+		 */
+		final private String driverClassName;
+		
+		/**
+		 * 접속 URL
+		 */
+		final private String baseUrl;
+		
+		/**
+		 * 기본 포트
+		 */
+		final private String defalutPort;
+		
+		/**
+		 * 접속 옵션
+		 */
+		final private String option;
+		
+		
+		/**
+		 * 한글값 조회
+		 */
+		public String getValue () {
+			return value;
+		}
+		
+		/**
+		 * 드라이버 클래스 조회
+		 */
+		public String getDriverClassName () {
+			return driverClassName;
+		}
+		
+		/**
+		 * 접속 URL 조회
+		 */
+		public String getBaseUrl () {
+			return baseUrl;
+		}
+		
+		/**
+		 * 기본 포트 조회
+		 */
+		public String getDefaultPort () {
+			return defalutPort;
+		}
+		
+		/**
+		 * 접속 옵션 조회
+		 */
+		public String getOption () {
+			return option;
+		}
+		
+		/**
+		 * 접속 URL 조회
+		 */
+		public String getUrl (ConnectionDB connectionDB) {
+			StringBuilder builder = new StringBuilder();		
+			if ((this == ORACLE || this == TIBERO ) && connectionDB.isGroupDatabase() == false) {
+				builder.append(this.baseUrl);
+				builder.append(connectionDB.getConectIp());
+				builder.append(":");
+				builder.append(connectionDB.getConectPort());
+				builder.append(":");
+				builder.append(connectionDB.getDatabaseNm());
+			} else {
+				builder.append(this.baseUrl);
+				builder.append(connectionDB.getConectIp());
+				builder.append(":");
+				builder.append(connectionDB.getConectPort());
+				if(this == MSSQL) {
+					builder.append(";databaseName=");
+				}else {
+					builder.append("/");
+				}				
+				builder.append(connectionDB.getDatabaseNm());				
+				if (this == MYSQL) {
+					builder.append("?");
+					builder.append(this.option.replaceAll("&amp;", "&"));
+				}else if(this == POSTGRESQL) {
+					builder.append("?");
+					builder.append("currentSchema="+connectionDB.getSchemaNm());					
+				} else if(this == MSSQL){
+					builder.append(";");
+					builder.append(this.option);
+				}
+			}
+			
+			return builder.toString();
+		}
+		
+		/**
+		 * 접속 URL 조회
+		 */
+		public String getUrl (String ip, String port, String databaseName, boolean isGroupDatabase, String option) {
+			StringBuilder builder = new StringBuilder();		
+			if ((this == ORACLE || this == TIBERO ) && isGroupDatabase == false) {
+				builder.append(this.baseUrl);
+				builder.append(ip);
+				builder.append(":");
+				builder.append(port);
+				builder.append(":");
+				builder.append(databaseName);
+			} else {
+				builder.append(this.baseUrl);
+				builder.append(ip);
+				builder.append(":");
+				builder.append(port);
+				builder.append("/");
+				builder.append(databaseName);
+			}
+			
+			if (StringUtil.isEmpty(option) == false) {
+				builder.append("?");
+				option.replaceAll("&amp;", "&");
+				builder.append(option);
+			}	
+		
+			
+			return builder.toString();
+		}
+		
+		/**
+		 * 데이터 베이스 타입별 상수 목록 조회
+		 */
+		public static Map<DatabaseType, String> getDatabaseTypeList () {
+	    	Map<DatabaseType, String> info = new LinkedHashMap<DatabaseType, String>();
+	    	DatabaseType[] array = DatabaseType.values();
+	    	for (int i = 0; i < array.length; i++) {
+	    		info.put(array[i], array[i].getValue());
+	    	}
+	    	return info;
+		}
+		
+		/**
+		 * 데이터 베이스 타입별 상수 목록 조회
+		 */
+		public static Map<DatabaseType, Map<String, String>> getDatabaseTypeInfoList () {
+			Map<DatabaseType, Map<String, String>> info = new LinkedHashMap<DatabaseType, Map<String, String>>();
+	    	DatabaseType[] array = DatabaseType.values();
+	    	for (int i = 0; i < array.length; i++) {
+	    		Map<String, String> detailInfo = new HashMap<String, String>();
+	    		detailInfo.put("key", array[i].toString());
+	    		detailInfo.put("value", array[i].getValue());
+	    		detailInfo.put("driverClassName", array[i].getDriverClassName());
+	    		detailInfo.put("baseUrl", array[i].getBaseUrl());
+	    		detailInfo.put("defalutPort", array[i].getDefaultPort());
+	    		detailInfo.put("option", array[i].getOption());
+	    		info.put(array[i], detailInfo);
+	    	}
+	    	return info;
+		}
+		
+	}
+	
+	
+	/**
+	 * @author 최정우
+	 * @since 2019.11.13
+	 * 
+	 * SPMiner에서 등록되는 파일 타입과, 해당 파일 타입의 등록가능한 확장자를 정의한 상수 Class 입니다.
+	 * 첨부파일, 이미지파일, 데이터 셋 파일 순서입니다.
+	 */
+	public enum FileType {
+		ALL_FILE(Arrays.asList("bmp","jpg","gif","png","jpeg","bmp","wma","avi","wav","mp3","mp4","mpeg","wmv","asf","pdf","ppt","pptx","docx","xls","xlsx","csv","hwp","txt","doc","zip", "json", "xml"))
+		, IMG_FILE(Arrays.asList("bmp","jpg","gif","png","jpeg"))
+		, DATASET_FILE(Arrays.asList("xls","xlsx","csv"));
+		
+		private FileType(List<String> extensions) {
+			this.extensions = extensions;
+		}
+		
+		/**
+		 * 확장자 목록
+		 */
+		final private List<String> extensions;
+		
+		/**
+		 * 확장자 목록 조회
+		 */
+		public List<String> getExtensions () {
+			return extensions;
+		}
+	}
+
+	/**
+	 * @author 김성훈
+	 * @since 2023.02.14
+	 *
+	 * 업로드 파일에 대한 저장 폴더 경로를 정의한 상수 Class
+	 * MAIN-메인 저장소, TEMP-임시 저장소
+	 */
+	public enum FileUploadPath {
+		/* 관리 시스템 파일 업로드 경로 */
+		//상대 경로 저장소(프로젝트 내부 -> Windows, Linux 구분 없음)
+		SFTP_RELATIVE_PATH("\\resources\\common\\file\\upload\\main", "/resources/common/file/upload/main")
+		//절대 경로 저장소(Windows, Linux)
+		, SFTP_ABSOLUTE_PATH("C:\\Taken_BI_Manager", "/home/Taken_BI_Manager")
+		, TEMP_ABSOLUTE_PATH("C:\\Taken_BI_Manager\\temp", "/home/Taken_BI_Manager/temp");
+
+		private FileUploadPath(String windowFileUploadPath, String linuxFileUploadPath) {
+			this.windowFileUploadPath = windowFileUploadPath;
+			this.linuxFileUploadPath = linuxFileUploadPath;
+		}
+
+		final private String windowFileUploadPath;
+
+		final private String linuxFileUploadPath;
+
+		public String getWindowFileUploadPath() {
+			return windowFileUploadPath;
+		}
+
+		public String getLinuxFileUploadPath() {
+			return linuxFileUploadPath;
+		}
+
+		/**
+		 * OS 타입별 파일 업로드 경로 return
+		 */
+		public String getOSFileUploadPath() {
+			if (System.getProperty("os.name").indexOf("Windows") > -1) {
+				return windowFileUploadPath;
+			} else {
+				return linuxFileUploadPath;
+			}
+		}
+	}
+}
 
src/main/java/com/takensoft/taken_bi_manager/controller/cmmn/CommonController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/cmmn/CommonController.java
@@ -0,0 +1,126 @@
+package com.takensoft.taken_bi_manager.controller.cmmn;
+
+import java.util.HashMap;
+
+import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi;
+import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.file.vo.FileInfo;
+import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule;
+import com.takensoft.taken_bi_manager.common.stylesheet.vo.Background_style;
+import com.takensoft.taken_bi_manager.common.stylesheet.vo.BorderStyle;
+import com.takensoft.taken_bi_manager.common.stylesheet.vo.FontStyle;
+import com.takensoft.taken_bi_manager.common.stylesheet.vo.StyleSheet;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode;
+import com.takensoft.taken_bi_manager.custom.vo.ComponentData;
+import com.takensoft.taken_bi_manager.custom.vo.CustomComponentVO;
+import com.takensoft.taken_bi_manager.custom.vo.CustomSplitterVO;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+import com.takensoft.taken_bi_manager.data.vo.DatasetPost;
+import com.takensoft.taken_bi_manager.diagram.vo.DiagramVO;
+import com.takensoft.taken_bi_manager.diagram.vo.NodeVO;
+import com.takensoft.taken_bi_manager.jobs.vo.JobGroup;
+import com.takensoft.taken_bi_manager.jobs.vo.JobItm;
+import com.takensoft.taken_bi_manager.jobs.vo.item.DataCheck;
+import com.takensoft.taken_bi_manager.jobs.vo.item.DataFilter;
+import com.takensoft.taken_bi_manager.jobs.vo.item.FilterItem;
+import com.takensoft.taken_bi_manager.jobs.vo.item.JobItemGroup;
+import com.takensoft.taken_bi_manager.meta.wrd.vo.StdWrd;
+import com.takensoft.taken_bi_manager.openAPI.vo.ApiExportVO;
+import com.takensoft.taken_bi_manager.openAPI.vo.OpenApiInfoVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.takensoft.taken_bi_manager.common.code.service.CmmnCodeService;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType;
+
+@RestController
+@RequestMapping("/common")
+public class CommonController {
+
+	@Autowired
+    private CmmnCodeService cmmnCodeService;
+	
+	
+	/*
+	 * 공통코드 리스트 요청
+	 */
+	@PostMapping(path = "/getCodeList.json")
+    public CustomeResultMap getCodeList(@RequestBody HashMap<String, Object> params) throws Exception {
+	  
+		CustomeResultMap map = new CustomeResultMap();
+
+		// 코드리스트  
+		map.getResultData().put("codeList",cmmnCodeService.getCodeListByGroupId(params.get("groupCode").toString()));		
+		
+	
+        return map;
+    }	
+	
+	
+	@PostMapping(path = "/getDataBaseTypeList.json")
+    public CustomeResultMap getDataBaseTypeList() throws Exception {
+	  
+		CustomeResultMap map = new CustomeResultMap();
+		// 코드리스트  
+		map.getResultData().put("DatabaseTypeList", DatabaseType.getDatabaseTypeInfoList());
+	
+        return map;
+    }
+
+	/*
+	 * 데이터 베이스 접속 체크
+	 */
+	@PostMapping(path = "/getDefaultObject.json")
+	public CustomeResultMap getDefaultObject() throws Exception {
+		CustomeResultMap map = new CustomeResultMap();
+
+		// 잡그룹 처리 아이템
+		map.getResultData().put("jobGroup", new JobGroup());
+		map.getResultData().put("jobItem", new JobItm());
+		map.getResultData().put("connectionDb", new ConnectionDB());
+		map.getResultData().put("fileRead", new FileInfo()); // 하석형 추가
+
+		// API 추가
+		map.getResultData().put("connectionApi", new ConnectionApi());
+		map.getResultData().put("dataTable", new DataTable());
+		map.getResultData().put("dataCheck", new DataCheck());
+		map.getResultData().put("schedule", new Schedule());
+		map.getResultData().put("dataset", new Dataset());
+		map.getResultData().put("datasetPost", new DatasetPost());
+		map.getResultData().put("filterItem", new FilterItem());
+		map.getResultData().put("dataFilter", new DataFilter());
+		map.getResultData().put("dataTypeList", SystemCode.DataType.getDataTypeArray());
+		map.getResultData().put("jobItemGroup", new JobItemGroup());
+		map.getResultData().put("connectionEhojo", new ConnectionEhojoVO());
+
+		// 메타데이터 표준단어
+		map.getResultData().put("stdWrm", new StdWrd());
+
+		// NODE 아이템
+		map.getResultData().put("diagram", new DiagramVO());
+		map.getResultData().put("node", new NodeVO());
+
+		// 레이아웃 처리 아이템
+		map.getResultData().put("customSplitter", new CustomSplitterVO());
+		map.getResultData().put("component", new CustomComponentVO());
+		map.getResultData().put("componentData", new ComponentData());
+
+		// openAPI
+		map.getResultData().put("openApiInfo", new OpenApiInfoVO());
+		map.getResultData().put("apiExport", new ApiExportVO());
+
+		// 스타일 시트
+		map.getResultData().put("styleSheet", new StyleSheet());
+		map.getResultData().put("borderStyle", new BorderStyle());
+		map.getResultData().put("fontStyle", new FontStyle());
+		map.getResultData().put("background_style", new Background_style());
+
+		return map;
+	}
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/controller/cmmn/ScheduleController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/cmmn/ScheduleController.java
@@ -0,0 +1,65 @@
+package com.takensoft.taken_bi_manager.controller.cmmn;
+
+import com.takensoft.taken_bi_manager.common.schedule.service.ScheduleService;
+import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SearchVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/schedule")
+public class ScheduleController {
+	@Autowired
+    private ScheduleService scheduleService;
+
+	/*
+	 * 스케줄 등록
+	 */
+	@PostMapping(path = "/conflictInsertSchedule.json")
+    public CustomeResultMap conflictInsertSchedule(@RequestBody Schedule schedule) throws Exception {
+		CustomeResultMap map = new CustomeResultMap();
+		scheduleService.conflictInsertSchedule(schedule);
+        return map;
+    }
+
+	/*
+	 * 스케줄 목록 조회
+	 */
+	@PostMapping(path = "/selectScheduleList.json")
+	public CustomeResultMap selectScheduleList(@RequestBody SearchVO searchVO) throws Exception {
+		return scheduleService.selectScheduleList(searchVO);
+	}
+
+	/*
+	 * 스케줄 상세 조회
+	 */
+	@PostMapping(path = "/selectSchedule.json")
+	public CustomeResultMap selectSchedule(@RequestBody Schedule schedule) throws Exception {
+		CustomeResultMap map = new CustomeResultMap();
+		map.getResultData().put("schedule", scheduleService.selectSchedule(schedule));
+		return map;
+	}
+
+	/**
+	 * @author 박정하
+	 * @since 2024.10.04
+	 *
+	 * 스케줄 정보 삭제
+	 */
+	@GetMapping(value="/deleteSchedule/{schdulId}")
+	public CustomeResultMap deleteSchedule(@PathVariable String schdulId) throws Exception {
+		return scheduleService.deleteSchedule(schdulId);
+	}
+
+	/**
+	 * @author 박정하
+	 * @since 2024.10.04
+	 *
+	 * 스케줄 상태 변경
+	 */
+	@GetMapping(value="/scheduleSttusChange/{schdulId}/{schdulSttus}")
+	public CustomeResultMap scheduleSttusChange(@PathVariable String schdulId, @PathVariable String schdulSttus) throws Exception {
+		return scheduleService.scheduleSttusChange(schdulId, schdulSttus);
+	}
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/controller/data/DataController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/data/DataController.java
@@ -0,0 +1,175 @@
+package com.takensoft.taken_bi_manager.controller.data;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+import com.takensoft.taken_bi_manager.jobs.service.JobService;
+import com.takensoft.taken_bi_manager.jobs.vo.JobGroup;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.code.service.CmmnCodeService;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SearchVO;
+import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType;
+import com.takensoft.taken_bi_manager.data.service.DataService;
+import com.takensoft.taken_bi_manager.user.member.servie.LoginService;
+import com.takensoft.taken_bi_manager.user.member.vo.Member;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/data")
+public class DataController {
+	
+	@Autowired
+    private CmmnCodeService cmmnCodeService;
+	
+	@Autowired
+    private DataService dataService;
+
+	@Autowired
+	private JobService jobService;
+
+	/*
+	 * 데이터 베이스 접속 체크 
+	 */
+	@PostMapping(path = "/dataBaseConnectionCheck.json")
+    public CustomeResultMap dataBaseConnectionCheck(@RequestBody ConnectionDB connectionDB) throws Exception {
+	  
+		CustomeResultMap map = new CustomeResultMap();
+		
+        return dataService.dbConnectionCheck(connectionDB);
+    }
+
+	/*
+	 * 데이터 베이스 접속 체크
+	 */
+	@PostMapping(path = "/checkTableName.json")
+	public CustomeResultMap checkTableName(@RequestBody Map<String,Object> jsonObject) throws Exception {
+
+		CustomeResultMap map = new CustomeResultMap();
+
+		ObjectMapper mapper = new ObjectMapper();
+
+		ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class);
+
+		return dataService.checkTableName(jsonObject.get("tableNm").toString(),connectionDB);
+	}
+
+	/*
+	 * 데이터 베이스 테이블 리스트 조회
+	 */
+	@PostMapping(path = "/selectTableList.json")
+	public CustomeResultMap selectTableList(@RequestBody ConnectionDB connectionDB) throws Exception {
+
+		CustomeResultMap map = new CustomeResultMap();
+
+		return dataService.selectTableList(connectionDB);
+	}
+	
+	/*
+	 * 디비 커넥션 정보 저장, 수정, 삭제
+	 */
+	@PostMapping(path = "/insertDbConnection.json")
+    public CustomeResultMap insertDbConnection(@RequestBody ConnectionDB connectionDB) throws Exception {	  
+				
+        return dataService.conflictInsertDbConnection(connectionDB);
+    }
+	
+	/*
+	 * 디비 커넥션 정보 저장, 수정, 삭제
+	 */
+	@PostMapping(path = "/selectDbConnectionList.json")
+    public CustomeResultMap selectDbConnectionList(@RequestBody SearchVO searchVO) throws Exception {	  
+		
+        return dataService.selectDbConnectionList(searchVO);
+    }/*
+	 * 디비 커넥션 정보 저장, 수정, 삭제
+	 */
+	@PostMapping(path = "/selectDbConnectionOne.json")
+	public CustomeResultMap selectDbConnectionOne(@RequestBody Map<String, Object> jsonObject) throws Exception {
+
+		CustomeResultMap map = new CustomeResultMap();
+
+		map.getResultData().put("dbConnection",dataService.selectDbConnectionOne(jsonObject.get("dbConectId").toString()));
+
+		return map;
+	}
+
+
+
+	/*
+	 * 테이블 내용 가져오기
+	 */
+	@PostMapping(path = "/getTableData.json")
+	public CustomeResultMap getTableData(@RequestBody Map<String, Object> jsonObject) throws Exception {
+
+		ObjectMapper mapper = new ObjectMapper();
+
+		Dataset dataset = mapper.convertValue(jsonObject.get("dataset"), Dataset.class);
+		ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class);
+		DataTable dataTable = new DataTable(dataset);
+
+		return dataService.getTableData(connectionDB,dataTable,false);
+	}
+
+	/*
+	 * 테이블 내용 가져오기
+	 */
+	@PostMapping(path = "/getTableDataByQuery.json")
+	public CustomeResultMap getTableDataByQuery(@RequestBody Map<String, Object> jsonObject) throws Exception {
+
+		ObjectMapper mapper = new ObjectMapper();
+
+		DataTable dataTable = mapper.convertValue(jsonObject.get("dataTable"), DataTable.class);
+		ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class);
+
+		return dataService.getTableData(connectionDB,dataTable,true);
+	}
+
+	/*
+	 * 테이블 내용 가져오기
+	 */
+	@PostMapping(path = "/changeDatasetRows.json")
+	public CustomeResultMap changeDatasetRows(@RequestBody Map<String, Object> jsonObject) throws Exception {
+
+		ObjectMapper mapper = new ObjectMapper();
+
+		List<List<Object>> changeData = mapper.convertValue(jsonObject.get("changeData"), new TypeReference<List<List<Object>>>(){});
+		List<List<Object>> deleteData = mapper.convertValue(jsonObject.get("deleteData"), new TypeReference<List<List<Object>>>(){});
+		List<List<Object>> insertData = mapper.convertValue(jsonObject.get("insertData"), new TypeReference<List<List<Object>>>(){});
+
+		JobGroup jobGroup = mapper.convertValue(jsonObject.get("jobGroup"), JobGroup.class);
+
+		CustomeResultMap map = dataService.datasetRowDataUpdate(jsonObject.get("datasetPost_id").toString(), changeData, deleteData, insertData, "user");
+		map.getResultData().put("dataTable", jobService.excuteJob(jobGroup).getDataTable());
+
+		return map;
+	}
+
+
+	/*
+	 * 디비 커넥션 정보, 삭제
+	 */
+	@PostMapping(path = "/deleteConnectionDb.json")
+	public CustomeResultMap deleteConnectionDb(@RequestBody Map<String, Object> jsonObject) throws Exception {
+
+		CustomeResultMap map = new CustomeResultMap();
+
+		map.getResultData().put("dbConnection",dataService.deleteConnectionDb(jsonObject.get("dbConectId").toString()));
+
+		return map;
+	}
+
+	
+	
+}
 
src/main/java/com/takensoft/taken_bi_manager/controller/data/DatasetController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/data/DatasetController.java
@@ -0,0 +1,102 @@
+package com.takensoft.taken_bi_manager.controller.data;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.common.vo.SearchVO;
+import com.takensoft.taken_bi_manager.data.service.DatasetService;
+import com.takensoft.taken_bi_manager.data.vo.Dataset;
+import com.takensoft.taken_bi_manager.data.vo.DatasetPost;
+import com.takensoft.taken_bi_manager.jobs.vo.JobItm;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping("/dataset")
+public class DatasetController {
+
+    @Autowired
+    private DatasetService datasetService;
+
+    /*
+     * 테이블 내용 가져오기
+     */
+    @PostMapping(path = "/insertDataPost.json")
+    public CustomeResultMap insertDataPost(@RequestBody Map<String, Object> jsonObject) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        DatasetPost datasetPost = mapper.convertValue(jsonObject.get("datasetPost"), DatasetPost.class);
+        Dataset dataset = mapper.convertValue(jsonObject.get("dataset"), Dataset.class);
+        ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class);
+        JobItm jobItm = mapper.convertValue(jsonObject.get("JobItm"), JobItm.class);
+        String hostCode = mapper.convertValue(jsonObject.get("hostCode"), String.class);
+        return datasetService.insertDataPost(datasetPost, dataset, connectionDB, jobItm, hostCode);
+    }
+
+    /*
+     * 테이블 내용 가져오기
+     */
+    @PostMapping(path = "/updateDataPost.json")
+    public CustomeResultMap updateDataPost(@RequestBody Map<String, Object> jsonObject) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        DatasetPost datasetPost = mapper.convertValue(jsonObject.get("datasetPost"), DatasetPost.class);
+        Dataset dataset = mapper.convertValue(jsonObject.get("dataset"), Dataset.class);
+        return datasetService.updateDataPost(datasetPost,dataset);
+    }
+
+    /*
+     * 데이타셋 포스트 리스트 호출
+     */
+    @PostMapping(path = "/selectDataPostList.json")
+    public CustomeResultMap selectDataPostList(@RequestBody SearchVO searchVO) throws Exception {
+        return datasetService.selectDatasetPostList(searchVO);
+    }
+
+    /*
+     * 데이터셋 상세 내용 호출
+     */
+    @PostMapping(path = "/selectDataPost.json")
+    public CustomeResultMap selectDataPost(@RequestBody Map<String, Object> jsonObject) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        SearchVO searchVO = mapper.convertValue(jsonObject.get("search"), SearchVO.class);
+        return datasetService.selectDatasetPost((String) jsonObject.get("datapost_id"), searchVO);
+    }
+
+    /*
+     * 데이터셋 상세 내용 호출
+     */
+    @PostMapping(path = "/getDataTableInfo.json")
+    public CustomeResultMap getDataTableInfo(@RequestBody Map<String, Object> jsonObject) throws Exception {
+        return datasetService.getDataTableInfo(jsonObject.get("datapost_id").toString());
+    }
+
+    /*
+     * 컴럼 정보 변경
+     */
+    @RequestMapping(value = "/changeColumnInfo.json")
+    public CustomeResultMap changeColumnInfo (@RequestBody Map<String, Object> jsonObject) throws Exception {
+        CustomeResultMap map = new CustomeResultMap();
+        try {
+            map = datasetService.changeColumnInfo(jsonObject);
+        }catch (Exception e){
+            map.getCheckMessage().setError(e.getMessage());
+        }
+     //   mav.addObject("columnDatas",datasetService.getColumnDatas(jsonObject.get("datasetId")));
+        return map;
+    }
+
+    /*
+     * 데이터셋 데이터 포스트 삭제
+     */
+    @RequestMapping(value = "/deleteDataPost.json")
+    public CustomeResultMap deleteDataPost (@RequestBody Map<String, Object> jsonObject) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        DatasetPost datasetPost = mapper.convertValue(jsonObject.get("datasetPost"), DatasetPost.class);
+        return datasetService.deleteDataPost(datasetPost);
+    }
+}(파일 끝에 줄바꿈 문자 없음)
 
src/main/java/com/takensoft/taken_bi_manager/controller/jobs/JobController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/jobs/JobController.java
@@ -0,0 +1,97 @@
+package com.takensoft.taken_bi_manager.controller.jobs;
+
+
+import com.takensoft.taken_bi_manager.common.file.vo.FileInfo;
+import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule;
+import com.takensoft.taken_bi_manager.common.vo.SearchVO;
+import com.takensoft.taken_bi_manager.data.service.DataService;
+import com.takensoft.taken_bi_manager.data.vo.DataTable;
+import com.takensoft.taken_bi_manager.jobs.service.JobService;
+import com.takensoft.taken_bi_manager.jobs.vo.item.DataCheck;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB;
+import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap;
+import com.takensoft.taken_bi_manager.jobs.vo.JobGroup;
+import com.takensoft.taken_bi_manager.jobs.vo.JobItm;
+
+import java.util.HashMap;
+
+
+@RestController
+@RequestMapping("/job")
+public class JobController {
+
+
+	@Autowired
+	private JobService jobService;
+
+
+	/*
+	 * 데이터 베이스 접속 체크 
+	 */
+	@PostMapping(path = "/getDefaultJobGroup.json")
+    public CustomeResultMap getDefaultJobGroup() throws Exception {
+		CustomeResultMap map = new CustomeResultMap();	
+		map.getResultData().put("jobGroup", new JobGroup());
+		map.getResultData().put("jobItem", new JobItm());
+		map.getResultData().put("connectionDb", new ConnectionDB());
+		map.getResultData().put("fileRead", new FileInfo()); // 하석형 추가
+		map.getResultData().put("dataTable", new DataTable());
+		map.getResultData().put("dataCheck", new DataCheck());
+		map.getResultData().put("schedule", new Schedule());
+
+        return map;
+    }
+
+	/*
+	 * 데이터 베이스 접속 체크
+	 */
+	@PostMapping(path = "/executeJob.json")
+	public CustomeResultMap executeJob(@RequestBody JobGroup jobGroup) throws Exception {
+
+		CustomeResultMap map = new CustomeResultMap();
+		map.getResultData().put("dataTable",jobService.excuteJob(jobGroup).getDataTable());
+		return map;
+	}
+
+	/*
+	 * 내부 DB 잡그룹 생성
+	 */
+	@PostMapping(path = "/createJobGroup.json")
+	public CustomeResultMap createJobGroup(@RequestBody JobGroup jobGroup) throws Exception {
+
+		CustomeResultMap map = new CustomeResultMap();
+
+		map.getResultData().put("jobGroup",jobService.excuteJob(jobGroup));
+		return map;
+	}
+
+	/*
+	 * 데이터 베이스 접속 체크
+	 */
+	@PostMapping(path = "/insertJobGroup.json")
+	public CustomeResultMap insertJobGroup(@RequestBody JobGroup jobGroup) throws Exception {
+
+		return jobService.insertJobGroup(jobGroup);
+	}
+
+	/*
+	 * 데이터 베이스 접속 체크
+	 */
+	@PostMapping(path = "/selectJobGroup.json")
+	public CustomeResultMap selectJobGroup(@RequestBody HashMap<String, Object> params) throws Exception {
+
+		CustomeResultMap map = new CustomeResultMap();
+		map.getResultData().put("jobGroup",jobService.selectJobGroup(params.get("group_id").toString()));
+
+		return map;
+	}
+
+
+		
+}
 
src/main/java/com/takensoft/taken_bi_manager/controller/login/LoginController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/login/LoginController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/controller/meta/management/MetaManageController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/meta/management/MetaManageController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/controller/meta/wrd/WrdController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/controller/meta/wrd/WrdController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/dao/CustomDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/dao/CustomDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/service/CustomService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/service/CustomService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/service/impl/CustomServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/service/impl/CustomServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentColumn.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentColumn.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentData.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentData.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentJobGroupVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentJobGroupVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentTitleVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentTitleVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomComponentVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomComponentVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomPageVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomPageVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterColumnOptionVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterColumnOptionVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterOptionVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterOptionVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/ErrorRes.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ErrorRes.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/vo/JobFlowVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/JobFlowVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/web/CustomController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/web/CustomController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/web/CustomException.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/web/CustomException.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/custom/web/GlobalExceptionHandler.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/custom/web/GlobalExceptionHandler.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/dao/DataDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/dao/DataDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/dao/DatasetDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/dao/DatasetDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/service/DataService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/DataService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/service/DataTableService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/DataTableService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/service/DatasetService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/DatasetService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DataServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DataServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DataTableServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DataTableServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DatasetServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DatasetServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/util/DataTableConvert.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/util/DataTableConvert.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/util/DataUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/util/DataUtil.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/vo/Column.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/Column.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnData.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnData.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnValue.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnValue.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/vo/DataTable.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/DataTable.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/vo/Dataset.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/Dataset.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/vo/DatasetPost.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/DatasetPost.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/data/vo/DatasetPostLog.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/DatasetPostLog.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/dao/DepartmentDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/dao/DepartmentDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/dao/DeptHostDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/dao/DeptHostDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/service/DepartmentService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/DepartmentService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/service/DeptHostService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/DeptHostService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/service/Impl/DepartmentServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/Impl/DepartmentServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/service/Impl/DeptHostServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/Impl/DeptHostServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/vo/DepartmentVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/DepartmentVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/vo/DeptHostVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/DeptHostVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/vo/OrgnztAuthorVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/OrgnztAuthorVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/vo/OrgnztMemberVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/OrgnztMemberVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/web/DepartmentController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/web/DepartmentController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/department/web/DeptHostController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/department/web/DeptHostController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/dao/DiagramDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/dao/DiagramDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/dto/DiagramDetailDTO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/dto/DiagramDetailDTO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/dto/DiagramListDTO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/dto/DiagramListDTO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/service/Diagramservice.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/Diagramservice.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/service/FilterService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/FilterService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/service/impl/DiagramServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/impl/DiagramServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/service/impl/FilterServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/impl/FilterServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/vo/DiagramVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/DiagramVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/vo/EdgeVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/EdgeVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/vo/LogDetailVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/LogDetailVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/vo/LogVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/LogVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/vo/NodePosition.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/NodePosition.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/vo/NodeVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/NodeVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/web/DiagramController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/web/DiagramController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/web/FilterController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/web/FilterController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/diagram/web/ScheduleOperator.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/web/ScheduleOperator.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/dao/HostDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/dao/HostDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/dao/SftpDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/dao/SftpDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/service/HostService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/service/HostService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/service/SftpService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/service/SftpService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/service/impl/SftpServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/service/impl/SftpServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/vo/ConnectionVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/ConnectionVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/vo/FilesVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/FilesVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/vo/HostVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/HostVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/vo/SftpVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/SftpVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/web/HostController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/web/HostController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/host/web/SftpController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/host/web/SftpController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/dao/JobDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/dao/JobDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/service/JobService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/service/JobService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/service/impl/JobServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/service/impl/JobServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/util/DataFilterUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/util/DataFilterUtil.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/util/JobUtil.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/util/JobUtil.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/JobGroup.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/JobGroup.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/JobItm.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/JobItm.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataCheck.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataCheck.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataCheckItem.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataCheckItem.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataFilter.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataFilter.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DatasetWriteItem.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DatasetWriteItem.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/FileInfoItem.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/FileInfoItem.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/FilterItem.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/FilterItem.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/JobItemGroup.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/JobItemGroup.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/JobReadConItm.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/JobReadConItm.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/management/dao/MetaManageDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/management/dao/MetaManageDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/management/service/MetaManageService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/management/service/MetaManageService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/management/service/impl/MetaManageServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/management/service/impl/MetaManageServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/wrd/dao/StdWrdDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/dao/StdWrdDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/wrd/service/StdWrdService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/service/StdWrdService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/wrd/service/impl/StdWrdServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/service/impl/StdWrdServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/wrd/vo/StdWrd.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/vo/StdWrd.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/meta/wrd/vo/StdWrdSearch.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/vo/StdWrdSearch.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/dao/OpenApiDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/dao/OpenApiDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/service/OpenApiService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/service/OpenApiService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/service/impl/OpenApiServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/service/impl/OpenApiServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiConnectVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiConnectVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiExportVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiExportVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiParamVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiParamVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/GisInfoVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/GisInfoVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/OpenApiInfoVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/OpenApiInfoVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/OpenApiKeyVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/OpenApiKeyVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/openAPI/web/OpenApiController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/web/OpenApiController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/dao/PushDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/dao/PushDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/dao/WebPushDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/dao/WebPushDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/service/WebPushService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/service/WebPushService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/service/impl/WebPushServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/service/impl/WebPushServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/vo/PushResultVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushResultVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/vo/PushTokenLogVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushTokenLogVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/vo/PushTokenVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushTokenVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/vo/PushUserVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushUserVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/vo/PushVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/vo/_PushResultVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/_PushResultVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/vo/_PushVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/_PushVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/push/web/WebPushController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/push/web/WebPushController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/dao/LoginDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/LoginDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/dao/MemberDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/MemberDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/dao/MyPageDAO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/MyPageDAO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/servie/LoginService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/LoginService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/servie/MemberService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/MemberService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/servie/MyPageService.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/MyPageService.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/LoginServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/LoginServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/MemberServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/MemberServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/MyPageServiceImpl.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/MyPageServiceImpl.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/vo/AuthorVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/AuthorVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/vo/Member.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/Member.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/vo/MemberHistory.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/MemberHistory.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/vo/UserAuthorVO.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/UserAuthorVO.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/web/MemberController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/web/MemberController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/member/web/MyPageController.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/web/MyPageController.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/org/vo/Organization.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/org/vo/Organization.java
This diff is skipped because there are too many other diffs.
 
src/main/java/com/takensoft/taken_bi_manager/user/org/vo/OrganizationHistory.java (added)
+++ src/main/java/com/takensoft/taken_bi_manager/user/org/vo/OrganizationHistory.java
This diff is skipped because there are too many other diffs.
 
src/main/resources/application.properties (added)
+++ src/main/resources/application.properties
This diff is skipped because there are too many other diffs.
 
src/main/resources/log4j2.xml (added)
+++ src/main/resources/log4j2.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/log4jdbc.log4j2.properties (added)
+++ src/main/resources/log4jdbc.log4j2.properties
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/api/connect-ehojo-plus-SQL.xml (added)
+++ src/main/resources/spring/mapper/api/connect-ehojo-plus-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/api/connection-api-SQL.xml (added)
+++ src/main/resources/spring/mapper/api/connection-api-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/common/commonCode-SQL.xml (added)
+++ src/main/resources/spring/mapper/common/commonCode-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/common/file-SQL.xml (added)
+++ src/main/resources/spring/mapper/common/file-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/common/schedule-SQL.xml (added)
+++ src/main/resources/spring/mapper/common/schedule-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/custom/custom-SQL.xml (added)
+++ src/main/resources/spring/mapper/custom/custom-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/data/data-SQL.xml (added)
+++ src/main/resources/spring/mapper/data/data-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/data/dataset-SQL.xml (added)
+++ src/main/resources/spring/mapper/data/dataset-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/department/department-SQL.xml (added)
+++ src/main/resources/spring/mapper/department/department-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/department/deptHost-SQL.xml (added)
+++ src/main/resources/spring/mapper/department/deptHost-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/host/host-SQL.xml (added)
+++ src/main/resources/spring/mapper/host/host-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/host/sftp-SQL.xml (added)
+++ src/main/resources/spring/mapper/host/sftp-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/job/job-SQL.xml (added)
+++ src/main/resources/spring/mapper/job/job-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/meta/stdwrd-SQL.xml (added)
+++ src/main/resources/spring/mapper/meta/stdwrd-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/mybatis-config.xml (added)
+++ src/main/resources/spring/mapper/mybatis-config.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/openAPI/openApi-SQL.xml (added)
+++ src/main/resources/spring/mapper/openAPI/openApi-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/postgres/diagram-SQL.xml (added)
+++ src/main/resources/spring/mapper/postgres/diagram-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/push/push-SQL.xml (added)
+++ src/main/resources/spring/mapper/push/push-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/sql/mariadb-SQL.xml (added)
+++ src/main/resources/spring/mapper/sql/mariadb-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/sql/mssql-SQL.xml (added)
+++ src/main/resources/spring/mapper/sql/mssql-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/sql/mysql-SQL.xml (added)
+++ src/main/resources/spring/mapper/sql/mysql-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/sql/oracle-SQL.xml (added)
+++ src/main/resources/spring/mapper/sql/oracle-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/sql/postgre-SQL.xml (added)
+++ src/main/resources/spring/mapper/sql/postgre-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/sql/tibero-SQL.xml (added)
+++ src/main/resources/spring/mapper/sql/tibero-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/user/login-SQL.xml (added)
+++ src/main/resources/spring/mapper/user/login-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/user/member-SQL.xml (added)
+++ src/main/resources/spring/mapper/user/member-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/spring/mapper/user/mypage-SQL.xml (added)
+++ src/main/resources/spring/mapper/user/mypage-SQL.xml
This diff is skipped because there are too many other diffs.
 
src/main/resources/static/index.html (added)
+++ src/main/resources/static/index.html
This diff is skipped because there are too many other diffs.
 
src/main/webapp/META-INF/MANIFEST.MF (added)
+++ src/main/webapp/META-INF/MANIFEST.MF
This diff is skipped because there are too many other diffs.
Add a comment
List