

240117 김성훈 back-end 최초커밋
@ce5aa8853bda0e7b6a39356b173f3fed909259fa
+++ .gitignore
... | ... | @@ -0,0 +1,37 @@ |
1 | +HELP.md | |
2 | +.gradle | |
3 | +build/ | |
4 | +!gradle/wrapper/gradle-wrapper.jar | |
5 | +!**/src/main/**/build/ | |
6 | +!**/src/test/**/build/ | |
7 | + | |
8 | +### STS ### | |
9 | +.apt_generated | |
10 | +.classpath | |
11 | +.factorypath | |
12 | +.project | |
13 | +.settings | |
14 | +.springBeans | |
15 | +.sts4-cache | |
16 | +bin/ | |
17 | +!**/src/main/**/bin/ | |
18 | +!**/src/test/**/bin/ | |
19 | + | |
20 | +### IntelliJ IDEA ### | |
21 | +.idea | |
22 | +*.iws | |
23 | +*.iml | |
24 | +*.ipr | |
25 | +out/ | |
26 | +!**/src/main/**/out/ | |
27 | +!**/src/test/**/out/ | |
28 | + | |
29 | +### NetBeans ### | |
30 | +/nbproject/private/ | |
31 | +/nbbuild/ | |
32 | +/dist/ | |
33 | +/nbdist/ | |
34 | +/.nb-gradle/ | |
35 | + | |
36 | +### VS Code ### | |
37 | +.vscode/ |
+++ build.gradle
... | ... | @@ -0,0 +1,56 @@ |
1 | +plugins { | |
2 | + id 'java' | |
3 | + id 'org.springframework.boot' version '3.2.1' | |
4 | + id 'io.spring.dependency-management' version '1.1.4' | |
5 | +} | |
6 | + | |
7 | +group = 'com.takensoft' | |
8 | +version = '0.0.1-SNAPSHOT' | |
9 | + | |
10 | +java { | |
11 | + sourceCompatibility = '17' | |
12 | +} | |
13 | + | |
14 | +repositories { | |
15 | + mavenCentral() | |
16 | +} | |
17 | + | |
18 | +dependencies { | |
19 | + // postgresql jdbc | |
20 | + implementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0' | |
21 | + // 오라클 jdbc | |
22 | + implementation group: 'com.oracle.database.jdbc', name: 'ojdbc11', version: '21.8.0.0' | |
23 | + // 마리아 jdbc | |
24 | + implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '3.3.2' | |
25 | + // mysql jdbc | |
26 | + implementation group: 'com.mysql', name: 'mysql-connector-j', version: '8.0.33' | |
27 | + // mssql jdbc | |
28 | + implementation group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version: '12.4.2.jre11' | |
29 | + | |
30 | + // mybatis | |
31 | + implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3' | |
32 | + | |
33 | + //lombok 라이브러리 | |
34 | + compileOnly 'org.projectlombok:lombok' | |
35 | + annotationProcessor 'org.projectlombok:lombok' | |
36 | + testCompileOnly 'org.projectlombok:lombok' | |
37 | + testAnnotationProcessor 'org.projectlombok:lombok' | |
38 | + | |
39 | + // https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple | |
40 | + implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' | |
41 | + // https://mvnrepository.com/artifact/org.json/json | |
42 | + implementation group: 'org.json', name: 'json', version: '20231013' | |
43 | + // https://mvnrepository.com/artifact/org.springframework.security/spring-security-crypto | |
44 | + implementation group: 'org.springframework.security', name: 'spring-security-crypto', version: '6.2.1' | |
45 | + // https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api | |
46 | + //compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1' | |
47 | + | |
48 | + // 기본 | |
49 | + implementation 'org.springframework.boot:spring-boot-starter-web' | |
50 | + testImplementation 'org.springframework.boot:spring-boot-starter-test' | |
51 | + | |
52 | +} | |
53 | + | |
54 | +tasks.named('test') { | |
55 | + useJUnitPlatform() | |
56 | +} |
+++ gradle/wrapper/gradle-wrapper.jar
Binary file is not shown |
+++ gradle/wrapper/gradle-wrapper.properties
... | ... | @@ -0,0 +1,6 @@ |
1 | +#Wed Dec 27 17:54:29 KST 2023 | |
2 | +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip | |
3 | +distributionBase=GRADLE_USER_HOME | |
4 | +distributionPath=wrapper/dists | |
5 | +zipStorePath=wrapper/dists | |
6 | +zipStoreBase=GRADLE_USER_HOME |
+++ gradlew
... | ... | @@ -0,0 +1,249 @@ |
1 | +#!/bin/sh | |
2 | + | |
3 | +# | |
4 | +# Copyright © 2015-2021 the original authors. | |
5 | +# | |
6 | +# Licensed under the Apache License, Version 2.0 (the "License"); | |
7 | +# you may not use this file except in compliance with the License. | |
8 | +# You may obtain a copy of the License at | |
9 | +# | |
10 | +# https://www.apache.org/licenses/LICENSE-2.0 | |
11 | +# | |
12 | +# Unless required by applicable law or agreed to in writing, software | |
13 | +# distributed under the License is distributed on an "AS IS" BASIS, | |
14 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 | +# See the License for the specific language governing permissions and | |
16 | +# limitations under the License. | |
17 | +# | |
18 | + | |
19 | +############################################################################## | |
20 | +# | |
21 | +# Gradle start up script for POSIX generated by Gradle. | |
22 | +# | |
23 | +# Important for running: | |
24 | +# | |
25 | +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is | |
26 | +# noncompliant, but you have some other compliant shell such as ksh or | |
27 | +# bash, then to run this script, type that shell name before the whole | |
28 | +# command line, like: | |
29 | +# | |
30 | +# ksh Gradle | |
31 | +# | |
32 | +# Busybox and similar reduced shells will NOT work, because this script | |
33 | +# requires all of these POSIX shell features: | |
34 | +# * functions; | |
35 | +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», | |
36 | +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; | |
37 | +# * compound commands having a testable exit status, especially «case»; | |
38 | +# * various built-in commands including «command», «set», and «ulimit». | |
39 | +# | |
40 | +# Important for patching: | |
41 | +# | |
42 | +# (2) This script targets any POSIX shell, so it avoids extensions provided | |
43 | +# by Bash, Ksh, etc; in particular arrays are avoided. | |
44 | +# | |
45 | +# The "traditional" practice of packing multiple parameters into a | |
46 | +# space-separated string is a well documented source of bugs and security | |
47 | +# problems, so this is (mostly) avoided, by progressively accumulating | |
48 | +# options in "$@", and eventually passing that to Java. | |
49 | +# | |
50 | +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, | |
51 | +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; | |
52 | +# see the in-line comments for details. | |
53 | +# | |
54 | +# There are tweaks for specific operating systems such as AIX, CygWin, | |
55 | +# Darwin, MinGW, and NonStop. | |
56 | +# | |
57 | +# (3) This script is generated from the Groovy template | |
58 | +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | |
59 | +# within the Gradle project. | |
60 | +# | |
61 | +# You can find Gradle at https://github.com/gradle/gradle/. | |
62 | +# | |
63 | +############################################################################## | |
64 | + | |
65 | +# Attempt to set APP_HOME | |
66 | + | |
67 | +# Resolve links: $0 may be a link | |
68 | +app_path=$0 | |
69 | + | |
70 | +# Need this for daisy-chained symlinks. | |
71 | +while | |
72 | + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path | |
73 | + [ -h "$app_path" ] | |
74 | +do | |
75 | + ls=$( ls -ld "$app_path" ) | |
76 | + link=${ls#*' -> '} | |
77 | + case $link in #( | |
78 | + /*) app_path=$link ;; #( | |
79 | + *) app_path=$APP_HOME$link ;; | |
80 | + esac | |
81 | +done | |
82 | + | |
83 | +# This is normally unused | |
84 | +# shellcheck disable=SC2034 | |
85 | +APP_BASE_NAME=${0##*/} | |
86 | +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | |
87 | +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | |
88 | + | |
89 | +# Use the maximum available, or set MAX_FD != -1 to use that value. | |
90 | +MAX_FD=maximum | |
91 | + | |
92 | +warn () { | |
93 | + echo "$*" | |
94 | +} >&2 | |
95 | + | |
96 | +die () { | |
97 | + echo | |
98 | + echo "$*" | |
99 | + echo | |
100 | + exit 1 | |
101 | +} >&2 | |
102 | + | |
103 | +# OS specific support (must be 'true' or 'false'). | |
104 | +cygwin=false | |
105 | +msys=false | |
106 | +darwin=false | |
107 | +nonstop=false | |
108 | +case "$( uname )" in #( | |
109 | + CYGWIN* ) cygwin=true ;; #( | |
110 | + Darwin* ) darwin=true ;; #( | |
111 | + MSYS* | MINGW* ) msys=true ;; #( | |
112 | + NONSTOP* ) nonstop=true ;; | |
113 | +esac | |
114 | + | |
115 | +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | |
116 | + | |
117 | + | |
118 | +# Determine the Java command to use to start the JVM. | |
119 | +if [ -n "$JAVA_HOME" ] ; then | |
120 | + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |
121 | + # IBM's JDK on AIX uses strange locations for the executables | |
122 | + JAVACMD=$JAVA_HOME/jre/sh/java | |
123 | + else | |
124 | + JAVACMD=$JAVA_HOME/bin/java | |
125 | + fi | |
126 | + if [ ! -x "$JAVACMD" ] ; then | |
127 | + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | |
128 | + | |
129 | +Please set the JAVA_HOME variable in your environment to match the | |
130 | +location of your Java installation." | |
131 | + fi | |
132 | +else | |
133 | + JAVACMD=java | |
134 | + if ! command -v java >/dev/null 2>&1 | |
135 | + then | |
136 | + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
137 | + | |
138 | +Please set the JAVA_HOME variable in your environment to match the | |
139 | +location of your Java installation." | |
140 | + fi | |
141 | +fi | |
142 | + | |
143 | +# Increase the maximum file descriptors if we can. | |
144 | +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | |
145 | + case $MAX_FD in #( | |
146 | + max*) | |
147 | + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. | |
148 | + # shellcheck disable=SC2039,SC3045 | |
149 | + MAX_FD=$( ulimit -H -n ) || | |
150 | + warn "Could not query maximum file descriptor limit" | |
151 | + esac | |
152 | + case $MAX_FD in #( | |
153 | + '' | soft) :;; #( | |
154 | + *) | |
155 | + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. | |
156 | + # shellcheck disable=SC2039,SC3045 | |
157 | + ulimit -n "$MAX_FD" || | |
158 | + warn "Could not set maximum file descriptor limit to $MAX_FD" | |
159 | + esac | |
160 | +fi | |
161 | + | |
162 | +# Collect all arguments for the java command, stacking in reverse order: | |
163 | +# * args from the command line | |
164 | +# * the main class name | |
165 | +# * -classpath | |
166 | +# * -D...appname settings | |
167 | +# * --module-path (only if needed) | |
168 | +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. | |
169 | + | |
170 | +# For Cygwin or MSYS, switch paths to Windows format before running java | |
171 | +if "$cygwin" || "$msys" ; then | |
172 | + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) | |
173 | + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) | |
174 | + | |
175 | + JAVACMD=$( cygpath --unix "$JAVACMD" ) | |
176 | + | |
177 | + # Now convert the arguments - kludge to limit ourselves to /bin/sh | |
178 | + for arg do | |
179 | + if | |
180 | + case $arg in #( | |
181 | + -*) false ;; # don't mess with options #( | |
182 | + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath | |
183 | + [ -e "$t" ] ;; #( | |
184 | + *) false ;; | |
185 | + esac | |
186 | + then | |
187 | + arg=$( cygpath --path --ignore --mixed "$arg" ) | |
188 | + fi | |
189 | + # Roll the args list around exactly as many times as the number of | |
190 | + # args, so each arg winds up back in the position where it started, but | |
191 | + # possibly modified. | |
192 | + # | |
193 | + # NB: a `for` loop captures its iteration list before it begins, so | |
194 | + # changing the positional parameters here affects neither the number of | |
195 | + # iterations, nor the values presented in `arg`. | |
196 | + shift # remove old arg | |
197 | + set -- "$@" "$arg" # push replacement arg | |
198 | + done | |
199 | +fi | |
200 | + | |
201 | + | |
202 | +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
203 | +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | |
204 | + | |
205 | +# Collect all arguments for the java command: | |
206 | +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, | |
207 | +# and any embedded shellness will be escaped. | |
208 | +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be | |
209 | +# treated as '${Hostname}' itself on the command line. | |
210 | + | |
211 | +set -- \ | |
212 | + "-Dorg.gradle.appname=$APP_BASE_NAME" \ | |
213 | + -classpath "$CLASSPATH" \ | |
214 | + org.gradle.wrapper.GradleWrapperMain \ | |
215 | + "$@" | |
216 | + | |
217 | +# Stop when "xargs" is not available. | |
218 | +if ! command -v xargs >/dev/null 2>&1 | |
219 | +then | |
220 | + die "xargs is not available" | |
221 | +fi | |
222 | + | |
223 | +# Use "xargs" to parse quoted args. | |
224 | +# | |
225 | +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. | |
226 | +# | |
227 | +# In Bash we could simply go: | |
228 | +# | |
229 | +# readarray ARGS < <( xargs -n1 <<<"$var" ) && | |
230 | +# set -- "${ARGS[@]}" "$@" | |
231 | +# | |
232 | +# but POSIX shell has neither arrays nor command substitution, so instead we | |
233 | +# post-process each arg (as a line of input to sed) to backslash-escape any | |
234 | +# character that might be a shell metacharacter, then use eval to reverse | |
235 | +# that process (while maintaining the separation between arguments), and wrap | |
236 | +# the whole thing up as a single "set" statement. | |
237 | +# | |
238 | +# This will of course break if any of these variables contains a newline or | |
239 | +# an unmatched quote. | |
240 | +# | |
241 | + | |
242 | +eval "set -- $( | |
243 | + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | | |
244 | + xargs -n1 | | |
245 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | | |
246 | + tr '\n' ' ' | |
247 | + )" '"$@"' | |
248 | + | |
249 | +exec "$JAVACMD" "$@" |
+++ gradlew.bat
... | ... | @@ -0,0 +1,92 @@ |
1 | +@rem | |
2 | +@rem Copyright 2015 the original author or authors. | |
3 | +@rem | |
4 | +@rem Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | +@rem you may not use this file except in compliance with the License. | |
6 | +@rem You may obtain a copy of the License at | |
7 | +@rem | |
8 | +@rem https://www.apache.org/licenses/LICENSE-2.0 | |
9 | +@rem | |
10 | +@rem Unless required by applicable law or agreed to in writing, software | |
11 | +@rem distributed under the License is distributed on an "AS IS" BASIS, | |
12 | +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | +@rem See the License for the specific language governing permissions and | |
14 | +@rem limitations under the License. | |
15 | +@rem | |
16 | + | |
17 | +@if "%DEBUG%"=="" @echo off | |
18 | +@rem ########################################################################## | |
19 | +@rem | |
20 | +@rem Gradle startup script for Windows | |
21 | +@rem | |
22 | +@rem ########################################################################## | |
23 | + | |
24 | +@rem Set local scope for the variables with windows NT shell | |
25 | +if "%OS%"=="Windows_NT" setlocal | |
26 | + | |
27 | +set DIRNAME=%~dp0 | |
28 | +if "%DIRNAME%"=="" set DIRNAME=. | |
29 | +@rem This is normally unused | |
30 | +set APP_BASE_NAME=%~n0 | |
31 | +set APP_HOME=%DIRNAME% | |
32 | + | |
33 | +@rem Resolve any "." and ".." in APP_HOME to make it shorter. | |
34 | +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | |
35 | + | |
36 | +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
37 | +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | |
38 | + | |
39 | +@rem Find java.exe | |
40 | +if defined JAVA_HOME goto findJavaFromJavaHome | |
41 | + | |
42 | +set JAVA_EXE=java.exe | |
43 | +%JAVA_EXE% -version >NUL 2>&1 | |
44 | +if %ERRORLEVEL% equ 0 goto execute | |
45 | + | |
46 | +echo. | |
47 | +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
48 | +echo. | |
49 | +echo Please set the JAVA_HOME variable in your environment to match the | |
50 | +echo location of your Java installation. | |
51 | + | |
52 | +goto fail | |
53 | + | |
54 | +:findJavaFromJavaHome | |
55 | +set JAVA_HOME=%JAVA_HOME:"=% | |
56 | +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |
57 | + | |
58 | +if exist "%JAVA_EXE%" goto execute | |
59 | + | |
60 | +echo. | |
61 | +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | |
62 | +echo. | |
63 | +echo Please set the JAVA_HOME variable in your environment to match the | |
64 | +echo location of your Java installation. | |
65 | + | |
66 | +goto fail | |
67 | + | |
68 | +:execute | |
69 | +@rem Setup the command line | |
70 | + | |
71 | +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | |
72 | + | |
73 | + | |
74 | +@rem Execute Gradle | |
75 | +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* | |
76 | + | |
77 | +:end | |
78 | +@rem End local scope for the variables with windows NT shell | |
79 | +if %ERRORLEVEL% equ 0 goto mainEnd | |
80 | + | |
81 | +:fail | |
82 | +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | |
83 | +rem the _cmd.exe /c_ return code! | |
84 | +set EXIT_CODE=%ERRORLEVEL% | |
85 | +if %EXIT_CODE% equ 0 set EXIT_CODE=1 | |
86 | +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% | |
87 | +exit /b %EXIT_CODE% | |
88 | + | |
89 | +:mainEnd | |
90 | +if "%OS%"=="Windows_NT" endlocal | |
91 | + | |
92 | +:omega |
+++ settings.gradle
... | ... | @@ -0,0 +1,1 @@ |
1 | +rootProject.name = 'taken_bi_manager' |
+++ src/main/java/com/takensoft/taken_bi_manager/DBConnectTest.java
... | ... | @@ -0,0 +1,76 @@ |
1 | +package com.takensoft.taken_bi_manager; | |
2 | + | |
3 | +import java.util.LinkedHashMap; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionUtil; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil; | |
8 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
9 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
10 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
12 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
13 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
14 | + | |
15 | +public class DBConnectTest { | |
16 | + public static void main(String[] args) throws Exception { | |
17 | + | |
18 | + | |
19 | + DBConnectionUtil dbc = new DBConnectionUtil(); | |
20 | + ConnectionDB cdb = new ConnectionDB(); | |
21 | + | |
22 | + cdb.setDatabaseNm("crosswalks"); | |
23 | + cdb.setDatabaseType(DatabaseType.POSTGRESQL); | |
24 | + cdb.setConectIp("210.180.118.83"); | |
25 | + cdb.setConectPort("5432"); | |
26 | + cdb.setConectNm("테스트 DB"); | |
27 | + cdb.setUserId("takensoft"); | |
28 | + cdb.setSchemaNm("crosswalk"); | |
29 | + // cdb.setUserPassword("Ts2020kr!@#"); | |
30 | + cdb.setUserPassword("tts64103165!@"); | |
31 | + | |
32 | + | |
33 | + dbc.createDatabaseDAO(cdb); | |
34 | + CheckMessage checkMessage = dbc.dbConnectionCheck(cdb); | |
35 | + List<Dataset> datasets = dbc.getDBConnectionTableList(cdb); | |
36 | + | |
37 | + | |
38 | + for(Dataset temp : datasets) { | |
39 | + System.out.println(temp.getTableNm()); | |
40 | + System.out.println("---------------------------------------------------"); | |
41 | + DataTable dt = new DataTable(temp); | |
42 | + dbc.setDataTableByDBConnectionTable(cdb, dt); | |
43 | + for(List<Object> item : dt.getRowData()) { | |
44 | + for(Object data : item) { | |
45 | + System.out.println(data); | |
46 | + } | |
47 | + } | |
48 | + | |
49 | + | |
50 | + /* | |
51 | + | |
52 | + cd = DataTypeUtil.convertDataTypeDbtoJavaList(cd, cdb.getDatabaseType()); | |
53 | + for(ColumnData it: cd) { | |
54 | + System.out.println("컬럼명 : " + it.getColumnNm()); | |
55 | + System.out.println("타입 : " +it.getDbDataType() + ": " + it.getDataTy()); | |
56 | + System.out.println("길이 : " +it.getDataSize()); | |
57 | + | |
58 | + if(it.getColumnNm().equals("cmmn_code_group")) { | |
59 | + | |
60 | + } | |
61 | + } | |
62 | + System.out.println("---------------------------------------------------"); | |
63 | + */ | |
64 | + } | |
65 | + | |
66 | + | |
67 | + | |
68 | + | |
69 | + | |
70 | + | |
71 | + System.out.println(checkMessage.getMessage()); | |
72 | + | |
73 | + | |
74 | + | |
75 | + } | |
76 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/MemberSelectTest.java
... | ... | @@ -0,0 +1,60 @@ |
1 | +package com.takensoft.taken_bi_manager; | |
2 | + | |
3 | + | |
4 | +import java.text.SimpleDateFormat; | |
5 | +import java.util.Date; | |
6 | +import java.util.List; | |
7 | +import java.util.Map; | |
8 | +import java.util.UUID; | |
9 | + | |
10 | +import com.takensoft.taken_bi_manager.common.connection.api.util.ApiUtil; | |
11 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam; | |
12 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
13 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
14 | +import com.takensoft.taken_bi_manager.data.util.DataTableConvert; | |
15 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
16 | + | |
17 | + | |
18 | +public class MemberSelectTest { | |
19 | + | |
20 | + public static void main(String[] args) throws Exception { | |
21 | + | |
22 | + DataTable dt = new DataTable(); | |
23 | + | |
24 | + ConnectionApi ca = new ConnectionApi(); | |
25 | + ca.setUrl("http://61.82.138.90:10971/aiSafetyCrossing/requestLogInfo.json"); | |
26 | + ca.setType(1); | |
27 | + ca.setRequestType(1); | |
28 | + ca.setDepth("resultData>"); | |
29 | + ApiParam apiParam1 = new ApiParam(); | |
30 | + apiParam1.setKey("st_dt"); | |
31 | + apiParam1.setValue("yyyy-MM-dd 10:22:00"); | |
32 | + apiParam1.setDateForm(true); | |
33 | + apiParam1.setDateType("month"); | |
34 | + apiParam1.setAddDate(0); | |
35 | + ca.getParams().add(apiParam1); | |
36 | + ApiParam apiParam2 = new ApiParam(); | |
37 | + apiParam2.setKey("ed_dt"); | |
38 | + apiParam2.setValue("yyyy-MM-dd 10:24:00"); | |
39 | + apiParam2.setDateForm(true); | |
40 | + apiParam2.setDateType("month"); | |
41 | + apiParam2.setAddDate(0); | |
42 | + ca.getParams().add(apiParam2); | |
43 | + ApiParam apiParam3 = new ApiParam(); | |
44 | + apiParam3.setKey("apiKey"); | |
45 | + apiParam3.setValue("f66b623060d0f20fee9663b8c0e445dc882cbf4ec4543630abd16c7960be7012"); | |
46 | + ca.getParams().add(apiParam3); | |
47 | + | |
48 | + List<Map<String,Object>> data = ApiUtil.getApiDataList(ApiUtil.apiRequest(ca)); | |
49 | + | |
50 | + dt = DataTableConvert.listMaptoDataset(data); | |
51 | + | |
52 | + int co = 0; | |
53 | + for(List<Object> temp: dt.getRowData()) { | |
54 | + System.out.println(dt.getColumnDatas().get(co).getOrginlColumnNm() + " : " + temp.get(co++)); | |
55 | + if(co == 9 ) co = 0; | |
56 | + } | |
57 | + | |
58 | + System.out.print(dt); | |
59 | + } | |
60 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/TakenBiManagerApplication.java
... | ... | @@ -0,0 +1,13 @@ |
1 | +package com.takensoft.taken_bi_manager; | |
2 | + | |
3 | +import org.springframework.boot.SpringApplication; | |
4 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | |
5 | + | |
6 | +@SpringBootApplication | |
7 | +class TakenBiManagerApplication { | |
8 | + | |
9 | + public static void main(String[] args) { | |
10 | + SpringApplication.run(TakenBiManagerApplication.class, args); | |
11 | + } | |
12 | + | |
13 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnCode.java
... | ... | @@ -0,0 +1,51 @@ |
1 | +package com.takensoft.taken_bi_manager.common.code.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2023-12-28 | |
11 | + * | |
12 | + * 공통코드 객체 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CmmnCode { | |
17 | + | |
18 | + // 콩통코드 | |
19 | + private String cmmnCode; | |
20 | + | |
21 | + // 그룹코드 | |
22 | + private String groupCode; | |
23 | + | |
24 | + // 코드명 | |
25 | + private String codeNm; | |
26 | + | |
27 | + // 코드 설명 | |
28 | + private String codeDc; | |
29 | + | |
30 | + // 상위코드 (없으면 생략) | |
31 | + private String upperCode; | |
32 | + | |
33 | + // 코드 정렬순서 | |
34 | + private String codeOrdr; | |
35 | + | |
36 | + // 코드 사용여부 | |
37 | + private boolean useAt; | |
38 | + | |
39 | + // 생성일 | |
40 | + private Timestamp creatDt; | |
41 | + | |
42 | + // 생성자ID | |
43 | + private String creatId; | |
44 | + | |
45 | + // 수정일 | |
46 | + private Timestamp updtDt; | |
47 | + | |
48 | + // 수정자 ID | |
49 | + private String updtId; | |
50 | + | |
51 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnGroup.java
... | ... | @@ -0,0 +1,42 @@ |
1 | +package com.takensoft.taken_bi_manager.common.code.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2023-12-28 | |
11 | + * | |
12 | + * 공통코드 그룹 객체 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CmmnGroup { | |
17 | + | |
18 | + // 공통코드 그룹 코드 | |
19 | + private String groupCode; | |
20 | + | |
21 | + // 공통코드 그룹 코드 명 | |
22 | + private String groupCodeNm; | |
23 | + | |
24 | + // 공통코드 그룹 설명 | |
25 | + private String groupCodeDc; | |
26 | + | |
27 | + // 공통코드 그룹 사용여부 | |
28 | + private boolean useAt; | |
29 | + | |
30 | + // 생성일 | |
31 | + private Timestamp creatDt; | |
32 | + | |
33 | + // 생성자ID | |
34 | + private String creatId; | |
35 | + | |
36 | + // 수정일 | |
37 | + private Timestamp updtDt; | |
38 | + | |
39 | + // 수정자 ID | |
40 | + private String updtId; | |
41 | + | |
42 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/FilterConfig.java
... | ... | @@ -0,0 +1,21 @@ |
1 | +package com.takensoft.taken_bi_manager.common.config; | |
2 | + | |
3 | +import org.springframework.boot.web.servlet.FilterRegistrationBean; | |
4 | +import org.springframework.context.annotation.Bean; | |
5 | +import org.springframework.context.annotation.Configuration; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.config.filter.SessionCheck; | |
8 | + | |
9 | +@Configuration | |
10 | +public class FilterConfig { | |
11 | + | |
12 | + @Bean | |
13 | + public FilterRegistrationBean<SessionCheck> sessionCheck() { | |
14 | + FilterRegistrationBean<SessionCheck> registrationBean = new FilterRegistrationBean<>(); | |
15 | + registrationBean.setFilter(new SessionCheck()); | |
16 | + registrationBean.addUrlPatterns("/*"); | |
17 | + registrationBean.setOrder(1); | |
18 | + registrationBean.setName("sessionCheck"); | |
19 | + return registrationBean; | |
20 | + } | |
21 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/MybatisConfig.java
... | ... | @@ -0,0 +1,7 @@ |
1 | +package com.takensoft.taken_bi_manager.common.config; | |
2 | + | |
3 | +public class MybatisConfig { | |
4 | + | |
5 | + | |
6 | + | |
7 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/filter/SessionCheck.java
... | ... | @@ -0,0 +1,53 @@ |
1 | +package com.takensoft.taken_bi_manager.common.config.filter; | |
2 | + | |
3 | +import java.io.IOException; | |
4 | +import java.util.HashMap; | |
5 | + | |
6 | +import org.springframework.web.filter.GenericFilterBean; | |
7 | +import org.springframework.web.util.ContentCachingResponseWrapper; | |
8 | + | |
9 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
10 | +import com.takensoft.taken_bi_manager.common.util.AuthUtil; | |
11 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
12 | + | |
13 | +import jakarta.servlet.FilterChain; | |
14 | +import jakarta.servlet.ServletException; | |
15 | +import jakarta.servlet.ServletRequest; | |
16 | +import jakarta.servlet.ServletResponse; | |
17 | +import jakarta.servlet.http.HttpServletRequest; | |
18 | +import jakarta.servlet.http.HttpServletResponse; | |
19 | + | |
20 | +public class SessionCheck extends GenericFilterBean { | |
21 | + | |
22 | + @Override | |
23 | + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | |
24 | + throws IOException, ServletException { | |
25 | + | |
26 | + HttpServletRequest httpServletRequest = (HttpServletRequest)request; | |
27 | + String uri =httpServletRequest.getRequestURI().toString(); | |
28 | + | |
29 | + // 로그인 세션 처리 (없으면 세션 없음 메세지 전달) | |
30 | + if(!uri.trim().contains("/login")) { | |
31 | + HashMap<String, Object> LoginUserInfo = (HashMap<String, Object>)httpServletRequest.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
32 | + if(LoginUserInfo == null) { | |
33 | + ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response); | |
34 | + chain.doFilter(request, responseWrapper); | |
35 | + CustomeResultMap map = new CustomeResultMap(); | |
36 | + map.getCheckMessage().setError("로그인 정보가 없습니다."); | |
37 | + map.getCheckMessage().setStatus(100); | |
38 | + map.getCheckMessage().setSuccess(false); | |
39 | + | |
40 | + String newResponse = new ObjectMapper().writeValueAsString(map); | |
41 | + response.setContentType("application/json"); | |
42 | + response.setContentLength(newResponse.length()); | |
43 | + response.getOutputStream().write(newResponse.getBytes()); | |
44 | + }else { | |
45 | + System.out.println("세션있음"); | |
46 | + System.out.println(LoginUserInfo.get("user_id")); | |
47 | + chain.doFilter(request, response); | |
48 | + } | |
49 | + } | |
50 | + | |
51 | + } | |
52 | + | |
53 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/ApiUtil.java
... | ... | @@ -0,0 +1,126 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.util; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.HashMap; | |
5 | +import java.util.List; | |
6 | +import java.util.Map; | |
7 | + | |
8 | +import org.json.simple.JSONArray; | |
9 | +import org.json.simple.JSONObject; | |
10 | +import org.json.simple.parser.JSONParser; | |
11 | + | |
12 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
13 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
14 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
15 | +import com.takensoft.taken_bi_manager.common.util.HTTPUtil; | |
16 | + | |
17 | +/** | |
18 | + * @author 김성원 | |
19 | + * @since 2024.01.12 | |
20 | + * | |
21 | + * API 연계 관련 기능 리스트 입니다. | |
22 | + */ | |
23 | +public class ApiUtil { | |
24 | + | |
25 | + | |
26 | + /** | |
27 | + * @author 김성원 | |
28 | + * @since 2024.01.12 | |
29 | + * | |
30 | + * OpenApi 데이터 수집 기능 | |
31 | + */ | |
32 | + public static ConnectionApi apiRequest(ConnectionApi connApi) throws Exception { | |
33 | + ObjectMapper mapper = new ObjectMapper(); | |
34 | + | |
35 | + HTTPUtil httpcon = new HTTPUtil(); | |
36 | + connApi.setResult(httpcon.HttpConnectionApi(connApi.getUrl(),connApi.getRequestType(), connApi.getParams())); | |
37 | + | |
38 | + return connApi; | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * @author 김성원 | |
43 | + * @since 2024.01.12 | |
44 | + * | |
45 | + * OpenApi 데이터 수집 기능 | |
46 | + */ | |
47 | + public static List<Map<String,Object>> getApiDataList (ConnectionApi connApi) throws Exception{ | |
48 | + ObjectMapper mapper = new ObjectMapper(); | |
49 | + | |
50 | + // depth 리스트 | |
51 | + String [] depthList = connApi.getDepth().split(">"); | |
52 | + CommonUtil commonUtil = new CommonUtil(); | |
53 | + | |
54 | + // Return Type : 1=JSON, 2=XML | |
55 | + if(connApi.getType() ==2) { | |
56 | + // XML String to JSON String | |
57 | + String jsonStr = commonUtil.xmlStrToJsonStr(connApi.getResult()); | |
58 | + connApi.setResult(jsonStr); | |
59 | + } | |
60 | + | |
61 | + JSONParser parser = new JSONParser(); | |
62 | + | |
63 | + JSONObject jsonObject = null; | |
64 | + JSONArray jsonArray = null; | |
65 | + | |
66 | + if(connApi.getResult().substring(0,1).equals("[")) { | |
67 | + jsonArray = (JSONArray) parser.parse(connApi.getResult()); | |
68 | + }else { | |
69 | + jsonObject = (JSONObject) parser.parse(connApi.getResult()); | |
70 | + } | |
71 | + | |
72 | + List<Map<String, Object>> apiDataList = new ArrayList<Map<String, Object>>(); | |
73 | + | |
74 | + if(jsonArray == null) { | |
75 | + // jsonObject to Map | |
76 | + Map<String, Object> resultMap = new HashMap<String, Object>(); | |
77 | + resultMap = commonUtil.jsonObjectToMap(jsonObject); | |
78 | + | |
79 | + int deptCount = 0; | |
80 | + for(String depth : depthList) { | |
81 | + deptCount++; | |
82 | + depth = depth.trim(); | |
83 | + Object temp = (Object)resultMap.get(depth); | |
84 | + | |
85 | + // 리스트 판별 | |
86 | + if(temp instanceof List) { | |
87 | + if(deptCount < depthList.length) { | |
88 | + List<Map<String, Object>> tempList = (List<Map<String, Object>>) temp; | |
89 | + resultMap = tempList.get(0); | |
90 | + }else { | |
91 | + apiDataList = (List<Map<String, Object>>) temp; | |
92 | + } | |
93 | + }else { | |
94 | + resultMap = (Map<String, Object>) temp; | |
95 | + } | |
96 | + } | |
97 | + }else { | |
98 | + apiDataList = (List<Map<String, Object>>)jsonArray; | |
99 | + } | |
100 | + | |
101 | + int max = 0; | |
102 | + int indx = 0; | |
103 | + | |
104 | + // 최대 길이의 키값을 가진 객체 구하기 | |
105 | + for(int i = 0 ; i < apiDataList.size() ; i++){ | |
106 | + if(apiDataList.get(i).keySet().size() > max) { | |
107 | + max = apiDataList.get(i).keySet().size(); | |
108 | + indx = i; | |
109 | + } | |
110 | + } | |
111 | + | |
112 | + // 빈정보 공백으로 채우기 | |
113 | + for(Map<String, Object> item : apiDataList ) { | |
114 | + if(max != item.size()) { | |
115 | + for (Map.Entry<String, Object> entry : apiDataList.get(indx).entrySet()) | |
116 | + { | |
117 | + if(item.get(entry.getKey()) == null) { | |
118 | + item.put(entry.getKey(),""); | |
119 | + } | |
120 | + } | |
121 | + } | |
122 | + } | |
123 | + | |
124 | + return apiDataList; | |
125 | + } | |
126 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ApiParam.java
... | ... | @@ -0,0 +1,71 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.vo; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.Serializable; | |
6 | + | |
7 | +import lombok.Getter; | |
8 | +import lombok.Setter; | |
9 | + | |
10 | +/** | |
11 | + * @author 김성원 | |
12 | + * @since 2021.11.02 | |
13 | + * | |
14 | + * Api 커넥션의 파라미터 정보를 담습니다. | |
15 | + */ | |
16 | +@Getter | |
17 | +@Setter | |
18 | +public class ApiParam implements Serializable { | |
19 | + | |
20 | + /** | |
21 | + * 시리얼 버전 | |
22 | + */ | |
23 | + private static final long serialVersionUID = 1L; | |
24 | + | |
25 | + /** | |
26 | + * 파라미터 DB저장 Key값 | |
27 | + */ | |
28 | + private String paramId; | |
29 | + | |
30 | + /** | |
31 | + * 파라미터 순서 | |
32 | + */ | |
33 | + private int index; | |
34 | + | |
35 | + /** | |
36 | + * 파라미터 Key값 | |
37 | + */ | |
38 | + private String key; | |
39 | + | |
40 | + /** | |
41 | + * 파라미터 value값 | |
42 | + */ | |
43 | + private Object value; | |
44 | + | |
45 | + /** | |
46 | + * encode 제외 변수 | |
47 | + */ | |
48 | + private boolean disableDecode; | |
49 | + | |
50 | + /** | |
51 | + * 날짜계산 변수 | |
52 | + */ | |
53 | + private boolean dateForm = false; | |
54 | + | |
55 | + | |
56 | + /** | |
57 | + * 날자 제어 타입(year, month, day) | |
58 | + */ | |
59 | + private String dateType; | |
60 | + | |
61 | + /** | |
62 | + * 날자 제어변수 | |
63 | + */ | |
64 | + private int addDate = 0; | |
65 | + | |
66 | + | |
67 | + public static long getSerialversionuid() { | |
68 | + return serialVersionUID; | |
69 | + } | |
70 | + | |
71 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ConnectionApi.java
... | ... | @@ -0,0 +1,92 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.vo; | |
2 | + | |
3 | + | |
4 | +import java.io.Serializable; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.HashMap; | |
7 | +import java.util.List; | |
8 | +import java.util.Map; | |
9 | + | |
10 | + | |
11 | +import lombok.Getter; | |
12 | +import lombok.Setter; | |
13 | + | |
14 | +/** | |
15 | + * @author 김성원 | |
16 | + * @since 2021.11.02 | |
17 | + * | |
18 | + * Api 커넥션 정보를 담는 Class | |
19 | + */ | |
20 | +@Getter | |
21 | +@Setter | |
22 | +public class ConnectionApi implements Serializable { | |
23 | + | |
24 | + | |
25 | + /** | |
26 | + * 연계 PAI 제목 | |
27 | + */ | |
28 | + private String title; | |
29 | + | |
30 | + /** | |
31 | + * 연계 url | |
32 | + */ | |
33 | + private String url; | |
34 | + | |
35 | + /** | |
36 | + * 연계 타입 1 = json, 2=xml | |
37 | + */ | |
38 | + private int type; | |
39 | + | |
40 | + /** | |
41 | + * 연계 타입 1 = post, 2 = get | |
42 | + */ | |
43 | + private int requestType; | |
44 | + | |
45 | + /** | |
46 | + * 연계 결과 | |
47 | + */ | |
48 | + private String result; | |
49 | + | |
50 | + /** | |
51 | + * 뎁스설정 구분자 > | |
52 | + */ | |
53 | + private String depth; | |
54 | + | |
55 | + /** | |
56 | + * 파라미터 리스트 | |
57 | + */ | |
58 | + private List<ApiParam> params = new ArrayList<ApiParam>(); | |
59 | + | |
60 | + /** | |
61 | + * 데이터(행,열)의 컬럼인 Row의 Index | |
62 | + */ | |
63 | + private int rowDataColumnIndex; | |
64 | + | |
65 | + /** | |
66 | + * 데이터(행,열)의 Row 시작 Index | |
67 | + */ | |
68 | + private int startRowIndex; | |
69 | + | |
70 | + /** | |
71 | + * 데이터(행,열)의 Cell 시작 Index | |
72 | + */ | |
73 | + private int startCellIndex; | |
74 | + | |
75 | + public ConnectionApi() { | |
76 | + this.params = new ArrayList<ApiParam>(); | |
77 | + this.type = 1; | |
78 | + } | |
79 | + | |
80 | + | |
81 | + public Map<String, Object> paramstoMap(){ | |
82 | + Map<String, Object> result = new HashMap<String,Object>(); | |
83 | + | |
84 | + // this.params -> map | |
85 | + for(int i=0; i< this.params.size(); i++ ) { | |
86 | + result.put(this.params.get(i).getKey(), this.params.get(i).getValue()); | |
87 | + } | |
88 | + | |
89 | + return result; | |
90 | + } | |
91 | + | |
92 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/DatabaseDAO.java
... | ... | @@ -0,0 +1,239 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.util.LinkedHashMap; | |
6 | +import java.util.List; | |
7 | +import java.util.Map; | |
8 | + | |
9 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
10 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
12 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
13 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
14 | + | |
15 | + | |
16 | +/** | |
17 | + * @author 김성원 | |
18 | + * @since 2024.01.09 | |
19 | + * | |
20 | + * 데이터베이스 접속 모듈에 관련된 SQL문에 접근하는 DAO 추상 Class입니다. | |
21 | + */ | |
22 | +public abstract class DatabaseDAO { | |
23 | + | |
24 | + /** | |
25 | + * @author 김성원 | |
26 | + * @since 2024.01.09 | |
27 | + * | |
28 | + * SqlSessionTemplate 생성 메서드 입니다. | |
29 | + */ | |
30 | + public abstract void createConnector (ConnectionDB db) throws Exception; | |
31 | + | |
32 | + /** | |
33 | + * @author 김성원 | |
34 | + * @since 2024.01.09 | |
35 | + * | |
36 | + * 접속한 데이터베이스의 테이블 목록 조회 SQL에 접근하는 메소드 입니다. | |
37 | + */ | |
38 | + public abstract List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception; | |
39 | + | |
40 | + /** | |
41 | + * @author 김성원 | |
42 | + * @since 2024.01.09 | |
43 | + * | |
44 | + * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
45 | + */ | |
46 | + public abstract List<ColumnData> getDBConnectionTableColumnList (Dataset dataset) throws Exception; | |
47 | + | |
48 | + /** | |
49 | + * @author 김성원 | |
50 | + * @since 2024.01.09 | |
51 | + * | |
52 | + * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다. | |
53 | + */ | |
54 | + public abstract List<LinkedHashMap<String, Object>> getDBConnectionTableDataList (DataTable datatable) throws Exception; | |
55 | + | |
56 | + /** | |
57 | + * @author 김성원 | |
58 | + * @since 2024.01.09 | |
59 | + * | |
60 | + * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다. | |
61 | + */ | |
62 | + public abstract int getDBConnectionTableDataTotalRows (DataTable datatable) throws Exception; | |
63 | + | |
64 | + | |
65 | + /** | |
66 | + * @author 김성원 | |
67 | + * @since 2024.01.09 | |
68 | + * | |
69 | + * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다. | |
70 | + */ | |
71 | + public abstract List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList (DataTable datatable) throws Exception; | |
72 | + | |
73 | + | |
74 | + /** | |
75 | + * @author 김성원 | |
76 | + * @since 2024.01.09 | |
77 | + * | |
78 | + * 조회 없는 실행형 쿼리 | |
79 | + */ | |
80 | + public abstract int executeCustomQuery (DataTable datatable) throws Exception; | |
81 | + | |
82 | + | |
83 | + /** | |
84 | + * @author 김성원 | |
85 | + * @since 2024.01.097 | |
86 | + * | |
87 | + * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다. | |
88 | + */ | |
89 | + public abstract int getDBConnectionCustomQueryDataTotalRows (DataTable datatable) throws Exception; | |
90 | + | |
91 | + /** | |
92 | + * @author 김성원 | |
93 | + * @since 2024.01.09 | |
94 | + * | |
95 | + * DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴) | |
96 | + */ | |
97 | + public abstract List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList (DataTable datatable) throws Exception; | |
98 | + | |
99 | + /** | |
100 | + * @author 김성원 | |
101 | + * @since 2024.01.09 | |
102 | + * | |
103 | + * DB연계 데이터 목록 총 갯수 조회 | |
104 | + */ | |
105 | + public abstract int getDBCollectionQueryDataTotalRows (DataTable datatable) throws Exception; | |
106 | + | |
107 | + | |
108 | + /** | |
109 | + * @author 김성원 | |
110 | + * @since 2024.01.09 | |
111 | + * | |
112 | + * 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) | |
113 | + */ | |
114 | + public abstract int getCustomQueryPrimaryOverlapCount (DataTable datatable) throws Exception; | |
115 | + | |
116 | + /** | |
117 | + * @author 김성원 | |
118 | + * @since 2024.01.09 | |
119 | + * | |
120 | + * DataSource Close | |
121 | + */ | |
122 | + public abstract void dbConnectionClose() throws Exception; | |
123 | + | |
124 | + /** | |
125 | + * @author 김성원 | |
126 | + * @since 2024.01.09 | |
127 | + * | |
128 | + * 쿼리 실행후, 실행한 쿼리문 조회 | |
129 | + */ | |
130 | + public abstract String getQuery (String id, Object parameter) throws Exception; | |
131 | + | |
132 | + /** | |
133 | + * @author 김성원 | |
134 | + * @since 2024.01.09 | |
135 | + * | |
136 | + * 커넥션된 데이터베이스의 실제 테이블 생성(pk 존재유) | |
137 | + */ | |
138 | + public abstract int datasetTableCreate(DataTable datatable) throws Exception; | |
139 | + | |
140 | + /** | |
141 | + * @author 김성원 | |
142 | + * @since 2024.01.09 | |
143 | + * | |
144 | + * 커넥션된 데이터베이스의 실제 테이블 생성(pk 존재무) | |
145 | + */ | |
146 | + public abstract int datasetDefaultTableCreate(DataTable datatable) throws Exception; | |
147 | + | |
148 | + /** | |
149 | + * @author 김성원 | |
150 | + * @since 2022.01.17 | |
151 | + * | |
152 | + * 커넥션된 데이터 베이스 데이터 업데이트(pk 존재무) | |
153 | + */ | |
154 | + public abstract void datasetDataUpdate(DataTable datatable) throws Exception; | |
155 | + | |
156 | + /** | |
157 | + * @author 김성원 | |
158 | + * @since 2022.01.17 | |
159 | + * | |
160 | + * 데이터 셋의 ROW 삭제 | |
161 | + */ | |
162 | + public abstract void datasetDataDelete(DataTable datatable) throws Exception; | |
163 | + | |
164 | + | |
165 | + /** | |
166 | + * @author 김성원 | |
167 | + * @since 2022.01.17 | |
168 | + * | |
169 | + * 커넥션된 데이터 베이스 중복체크 (pk 존재무) | |
170 | + */ | |
171 | + public abstract int duplicateCheckTableName(Map info) throws Exception; | |
172 | + | |
173 | + | |
174 | + /** | |
175 | + * @author 김성원 | |
176 | + * @since 2022.01.17 | |
177 | + * | |
178 | + * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징) | |
179 | + */ | |
180 | + public abstract List<LinkedHashMap<String, Object>> getRowData (DataTable dataTable) throws Exception; | |
181 | + | |
182 | + /** | |
183 | + * @author 김성원 | |
184 | + * @since 2022.01.17 | |
185 | + * | |
186 | + * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(x) | |
187 | + */ | |
188 | + public abstract List<LinkedHashMap<String, Object>> getRowDataAll (DataTable dataTable) throws Exception; | |
189 | + | |
190 | + /** | |
191 | + * @author 최정우 | |
192 | + * @since 2019.12.09 | |
193 | + * | |
194 | + * 데이터 셋의 컬럼 정보 목록 총 갯수 조회 메소드 입니다. | |
195 | + */ | |
196 | + public abstract int getRowDataTotalRows (DataTable dataTable) throws Exception; | |
197 | + | |
198 | + /** | |
199 | + * @author 김성원 | |
200 | + * @since 2022.1.12 | |
201 | + * | |
202 | + * 데이터 셋의 비우기 (데이터 셋 내용삭제) | |
203 | + */ | |
204 | + public abstract int emptyDataset (DataTable dataTable) throws Exception; | |
205 | + | |
206 | + /** | |
207 | + * @author 김성원 | |
208 | + * @since 2022.1.20 | |
209 | + * | |
210 | + * 실제 생성된 컬럼 변경 | |
211 | + */ | |
212 | + public abstract int tableColumnChange (TableBasicInfo tableBasicInfo) throws Exception; | |
213 | + | |
214 | + /** | |
215 | + * @author 김성원 | |
216 | + * @since 2022.1.20 | |
217 | + * | |
218 | + * 실제 생성된 테이블 PK처리 | |
219 | + */ | |
220 | + public abstract int changePrimaryKey (TableBasicInfo tableBasicInfo) throws Exception; | |
221 | + | |
222 | + /** | |
223 | + * @author 김성원 | |
224 | + * @since 2022.1.20 | |
225 | + * | |
226 | + * AI PK 생성 | |
227 | + */ | |
228 | + public abstract int createAutoIncrement (TableBasicInfo tableBasicInfo) throws Exception; | |
229 | + | |
230 | + | |
231 | + /** | |
232 | + * @author 김성원 | |
233 | + * @since 2022.09.30 | |
234 | + * | |
235 | + * 테이블 명 변경 | |
236 | + * | |
237 | + */ | |
238 | + public abstract void updateTableMetaInfo(DataTable dataTable) throws Exception; | |
239 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MariadbDAO.java
... | ... | @@ -0,0 +1,294 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.HashMap; | |
7 | +import java.util.LinkedHashMap; | |
8 | +import java.util.List; | |
9 | +import java.util.Map; | |
10 | + | |
11 | +import org.apache.ibatis.mapping.ParameterMapping; | |
12 | +import org.mybatis.spring.SqlSessionTemplate; | |
13 | +import org.springframework.stereotype.Repository; | |
14 | + | |
15 | +import com.fasterxml.jackson.core.type.TypeReference; | |
16 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
17 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
18 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
19 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
20 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
21 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
22 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
23 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
24 | + | |
25 | + | |
26 | +/** | |
27 | + * @author 김성원 | |
28 | + * @since 2024.01.09 | |
29 | + * | |
30 | + * Mariadb 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다. | |
31 | + */ | |
32 | +@Repository | |
33 | +public class MariadbDAO extends DatabaseDAO { | |
34 | + | |
35 | + public MariadbDAO () {} | |
36 | + | |
37 | + public MariadbDAO (ConnectionDB db) throws Exception { | |
38 | + this.createConnector(db); | |
39 | + } | |
40 | + | |
41 | + private DBConnectionConfig dbUtil = null; | |
42 | + | |
43 | + public DBConnectionConfig getDbUtil() { | |
44 | + return dbUtil; | |
45 | + } | |
46 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
47 | + this.dbUtil = dbUtil; | |
48 | + } | |
49 | + | |
50 | + /** | |
51 | + * @author 김성원 | |
52 | + * @since 2024.01.09 | |
53 | + * | |
54 | + * SqlSessionTemplate 생성 메서드 입니다. | |
55 | + */ | |
56 | + @Override | |
57 | + public void createConnector (ConnectionDB db) throws Exception { | |
58 | + dbUtil = new DBConnectionConfig(); | |
59 | + dbUtil.mybatisSqlTemplateCreate(db); | |
60 | + } | |
61 | + | |
62 | + /** | |
63 | + * @author 김성원 | |
64 | + * @since 2024.01.09 | |
65 | + * | |
66 | + * 접속한 데이터베이스의 테이블 목록 조회 SQL에 접근하는 메소드 입니다. | |
67 | + */ | |
68 | + @Override | |
69 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
70 | + try { | |
71 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableList", db); | |
72 | + } catch (Exception e) { | |
73 | + return new ArrayList<Dataset>(); | |
74 | + } | |
75 | + } | |
76 | + | |
77 | + /** | |
78 | + * @author 김성원 | |
79 | + * @since 2024.01.09 | |
80 | + * | |
81 | + * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
82 | + */ | |
83 | + @Override | |
84 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
85 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableColumnList", dataset); | |
86 | + } | |
87 | + | |
88 | + /** | |
89 | + * @author 김성원 | |
90 | + * @since 2024.01.09 | |
91 | + * | |
92 | + * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다. | |
93 | + */ | |
94 | + @Override | |
95 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList (DataTable datatable) throws Exception { | |
96 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableDataList", datatable); | |
97 | + } | |
98 | + | |
99 | + /** | |
100 | + * @author 김성원 | |
101 | + * @since 2024.01.09 | |
102 | + * | |
103 | + * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다. | |
104 | + */ | |
105 | + @Override | |
106 | + public int getDBConnectionTableDataTotalRows (DataTable datatable) throws Exception { | |
107 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getDBConnectionTableDataTotalRows", datatable); | |
108 | + } | |
109 | + | |
110 | + /** | |
111 | + * @author 김성원 | |
112 | + * @since 2024.01.09 | |
113 | + * | |
114 | + * 커스텀 테이블 데이터 조회 (페이징사용 유무에 따라 페이징 처리) SQL에 접근하는 메소드 입니다. | |
115 | + */ | |
116 | + @Override | |
117 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList (DataTable datatable) throws Exception { | |
118 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionCustomQueryDataList", datatable); | |
119 | + } | |
120 | + | |
121 | + /** | |
122 | + * @author 김성원 | |
123 | + * @since 2024.01.09 | |
124 | + * | |
125 | + * 커스텀 테이블 데이터 목록 총 갯수 조회 SQL에 접근하는 메소드 입니다. | |
126 | + */ | |
127 | + @Override | |
128 | + public int getDBConnectionCustomQueryDataTotalRows (DataTable datatable) throws Exception { | |
129 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
130 | + } | |
131 | + | |
132 | + /** | |
133 | + * @author 김성원 | |
134 | + * @since 2024.01.09 | |
135 | + * | |
136 | + * DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴) | |
137 | + */ | |
138 | + @Override | |
139 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList (DataTable datatable) throws Exception { | |
140 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBCollectionQueryDataList", datatable); | |
141 | + } | |
142 | + | |
143 | + /** | |
144 | + * @author 김성원 | |
145 | + * @since 2024.01.09 | |
146 | + * | |
147 | + * DB연계 데이터 목록 총 갯수 조회 | |
148 | + */ | |
149 | + @Override | |
150 | + public int getDBCollectionQueryDataTotalRows (DataTable datatable) throws Exception { | |
151 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getDBCollectionQueryDataTotalRows", datatable); | |
152 | + } | |
153 | + | |
154 | + /** | |
155 | + * @author 김성원 | |
156 | + * @since 2024.01.09 | |
157 | + * | |
158 | + * 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) | |
159 | + */ | |
160 | + @Override | |
161 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
162 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getCustomQueryPrimaryOverlapCount", datatable); | |
163 | + } | |
164 | + | |
165 | + /** | |
166 | + * @author 김성원 | |
167 | + * @since 2024.01.09 | |
168 | + * | |
169 | + * SqlSessionTemplate Close | |
170 | + */ | |
171 | + @Override | |
172 | + public void dbConnectionClose() throws Exception { | |
173 | + dbUtil.close(); | |
174 | + } | |
175 | + | |
176 | + /** | |
177 | + * @author 김성원 | |
178 | + * @since 2024.01.09 | |
179 | + * | |
180 | + * 쿼리 실행후, 실행한 쿼리문 조회 | |
181 | + */ | |
182 | + @Override | |
183 | + public String getQuery (String id, Object parameter) throws Exception { | |
184 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
185 | + | |
186 | + id = "OracleDAO." + id; | |
187 | + | |
188 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
189 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
190 | + | |
191 | + ObjectMapper mapper = new ObjectMapper(); | |
192 | + String json = mapper.writeValueAsString(parameter); | |
193 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
194 | + for (ParameterMapping par : paramMap) { | |
195 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
196 | + if(parameter == null) | |
197 | + sql = sql.replaceFirst("\\?", "NULL"); | |
198 | + else | |
199 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
200 | + } | |
201 | + System.out.println(""); | |
202 | + System.out.println("---------------------- OracleDAO sql --------------------"); | |
203 | + System.out.println(sql); | |
204 | + System.out.println(""); | |
205 | + return sql; | |
206 | + } | |
207 | + | |
208 | + @Override | |
209 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
210 | + // TODO Auto-generated method stub | |
211 | + return dbUtil.getTemplate().update("MariadbDAO.datasetTableCreate", datatable); | |
212 | + } | |
213 | + | |
214 | + @Override | |
215 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
216 | + // TODO Auto-generated method stub | |
217 | + return dbUtil.getTemplate().update("MariadbDAO.datasetDefaultTableCreate", datatable); | |
218 | + } | |
219 | + | |
220 | + @Override | |
221 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
222 | + // TODO Auto-generated method stub | |
223 | + dbUtil.getTemplate().update("MariadbDAO.datasetDataUpdate", datatable); | |
224 | + } | |
225 | + | |
226 | + @Override | |
227 | + public int duplicateCheckTableName(Map info) throws Exception { | |
228 | + // TODO Auto-generated method stub | |
229 | + return dbUtil.getTemplate().selectOne("MariadbDAO.duplicateCheckTableName", info); | |
230 | + } | |
231 | + | |
232 | + @Override | |
233 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
234 | + // TODO Auto-generated method stub | |
235 | + return dbUtil.getTemplate().selectList("MariadbDAO.getRowData", dataTable); | |
236 | + } | |
237 | + | |
238 | + @Override | |
239 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
240 | + return dbUtil.getTemplate().selectList("MariadbDAO.getRowDataAll", dataTable); | |
241 | + } | |
242 | + | |
243 | + @Override | |
244 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
245 | + // TODO Auto-generated method stub | |
246 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getRowDataTotalRows", dataTable); | |
247 | + } | |
248 | + | |
249 | + @Override | |
250 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
251 | + // TODO Auto-generated method stub | |
252 | + return dbUtil.getTemplate().delete("MariadbDAO.emptyDataset", dataTable); | |
253 | + } | |
254 | + | |
255 | + @Override | |
256 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
257 | + // TODO Auto-generated method stub | |
258 | + return dbUtil.getTemplate().update("MariadbDAO.tableColumnChange", tableBasicInfo); | |
259 | + } | |
260 | + | |
261 | + | |
262 | + @Override | |
263 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
264 | + // TODO Auto-generated method stub | |
265 | + return dbUtil.getTemplate().update("MariadbDAO.changePromaryKey", tableBasicInfo); | |
266 | + } | |
267 | + | |
268 | + | |
269 | + @Override | |
270 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
271 | + // TODO Auto-generated method stub | |
272 | + dbUtil.getTemplate().delete("MariadbDAO.datasetDataDelete", datatable); | |
273 | + } | |
274 | + | |
275 | + @Override | |
276 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
277 | + | |
278 | + return dbUtil.getTemplate().update("MariadbDAO.createAutoIncrement", tableBasicInfo); | |
279 | + | |
280 | + } | |
281 | + | |
282 | + @Override | |
283 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
284 | + | |
285 | + return dbUtil.getTemplate().update("MariadbDAO.executeCustomQuery", datatable); | |
286 | + } | |
287 | + | |
288 | + | |
289 | + @Override | |
290 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
291 | + // TODO Auto-generated method stub | |
292 | + | |
293 | + } | |
294 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/PostgresqlDAO.java
... | ... | @@ -0,0 +1,231 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | + | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.HashMap; | |
6 | +import java.util.LinkedHashMap; | |
7 | +import java.util.List; | |
8 | +import java.util.Map; | |
9 | + | |
10 | +import org.apache.ibatis.mapping.ParameterMapping; | |
11 | +import org.mybatis.spring.SqlSessionTemplate; | |
12 | + | |
13 | +import com.fasterxml.jackson.core.type.TypeReference; | |
14 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
15 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
16 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
17 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
18 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
19 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
20 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
21 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
22 | + | |
23 | + | |
24 | + | |
25 | +public class PostgresqlDAO extends DatabaseDAO { | |
26 | + | |
27 | + public PostgresqlDAO () {} | |
28 | + | |
29 | + public PostgresqlDAO (ConnectionDB db) throws Exception { | |
30 | + this.createConnector(db); | |
31 | + } | |
32 | + | |
33 | + private DBConnectionConfig dbUtil = null; | |
34 | + | |
35 | + public DBConnectionConfig getDbUtil() { | |
36 | + return dbUtil; | |
37 | + } | |
38 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
39 | + this.dbUtil = dbUtil; | |
40 | + } | |
41 | + | |
42 | + | |
43 | + @Override | |
44 | + public void createConnector(ConnectionDB db) throws Exception { | |
45 | + // TODO Auto-generated method stub | |
46 | + dbUtil = new DBConnectionConfig(); | |
47 | + dbUtil.mybatisSqlTemplateCreate(db); | |
48 | + } | |
49 | + | |
50 | + @Override | |
51 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
52 | + // TODO Auto-generated method stub | |
53 | + try { | |
54 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableList", db); | |
55 | + } catch (Exception e) { | |
56 | + return new ArrayList<Dataset>(); | |
57 | + } | |
58 | + } | |
59 | + | |
60 | + @Override | |
61 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
62 | + // TODO Auto-generated method stub | |
63 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableColumnList", dataset); | |
64 | + } | |
65 | + | |
66 | + @Override | |
67 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception { | |
68 | + // TODO Auto-generated method stub | |
69 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableDataList", datatable); | |
70 | + } | |
71 | + | |
72 | + @Override | |
73 | + public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception { | |
74 | + // TODO Auto-generated method stub | |
75 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBConnectionTableDataTotalRows", datatable); | |
76 | + } | |
77 | + | |
78 | + @Override | |
79 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) | |
80 | + throws Exception { | |
81 | + // TODO Auto-generated method stub | |
82 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionCustomQueryDataList", datatable); | |
83 | + } | |
84 | + | |
85 | + @Override | |
86 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
87 | + // TODO Auto-generated method stub | |
88 | + return dbUtil.getTemplate().update("PostgresqlDAO.executeCustomQueryDataList", datatable); | |
89 | + } | |
90 | + | |
91 | + @Override | |
92 | + public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception { | |
93 | + // TODO Auto-generated method stub | |
94 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
95 | + } | |
96 | + | |
97 | + @Override | |
98 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception { | |
99 | + // TODO Auto-generated method stub | |
100 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBCollectionQueryDataList", datatable); | |
101 | + } | |
102 | + | |
103 | + @Override | |
104 | + public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception { | |
105 | + // TODO Auto-generated method stub | |
106 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBCollectionQueryDataTotalRows", datatable); | |
107 | + } | |
108 | + | |
109 | + @Override | |
110 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
111 | + // TODO Auto-generated method stub | |
112 | + return dbUtil.getTemplate().selectOne("getCustomQueryPrimaryOverlapCount.getCustomQueryPrimaryOverlapCount", datatable); | |
113 | + } | |
114 | + | |
115 | + @Override | |
116 | + public void dbConnectionClose() throws Exception { | |
117 | + dbUtil.close(); | |
118 | + } | |
119 | + | |
120 | + @Override | |
121 | + public String getQuery(String id, Object parameter) throws Exception { | |
122 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
123 | + | |
124 | + id = "PostgresqlDAO." + id; | |
125 | + | |
126 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
127 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
128 | + | |
129 | + ObjectMapper mapper = new ObjectMapper(); | |
130 | + String json = mapper.writeValueAsString(parameter); | |
131 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
132 | + for (ParameterMapping par : paramMap) { | |
133 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
134 | + if(parameter == null) | |
135 | + sql = sql.replaceFirst("\\?", "NULL"); | |
136 | + else | |
137 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
138 | + } | |
139 | + System.out.println(""); | |
140 | + System.out.println("---------------------- PostGresqlDAO sql --------------------"); | |
141 | + System.out.println(sql); | |
142 | + System.out.println(""); | |
143 | + return sql; | |
144 | + } | |
145 | + | |
146 | + @Override | |
147 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
148 | + // TODO Auto-generated method stub | |
149 | + return dbUtil.getTemplate().update("PostgresqlDAO.datasetTableCreate", datatable); | |
150 | + } | |
151 | + | |
152 | + @Override | |
153 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
154 | + // TODO Auto-generated method stub | |
155 | + return dbUtil.getTemplate().update("PostgresqlDAO.datasetDefaultTableCreate", datatable); | |
156 | + } | |
157 | + | |
158 | + @Override | |
159 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
160 | + // TODO Auto-generated method stub | |
161 | + dbUtil.getTemplate().update("PostgresqlDAO.datasetDataUpdate", datatable); | |
162 | + } | |
163 | + | |
164 | + @Override | |
165 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
166 | + // TODO Auto-generated method stub | |
167 | + dbUtil.getTemplate().update("PostgresqlDAO.datasetDataUpdate", datatable); | |
168 | + } | |
169 | + | |
170 | + @Override | |
171 | + public int duplicateCheckTableName(Map info) throws Exception { | |
172 | + // TODO Auto-generated method stub | |
173 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.duplicateCheckTableName", info); | |
174 | + } | |
175 | + | |
176 | + @Override | |
177 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
178 | + // TODO Auto-generated method stub | |
179 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getRowData", dataTable); | |
180 | + } | |
181 | + | |
182 | + @Override | |
183 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
184 | + // TODO Auto-generated method stub | |
185 | + | |
186 | + ObjectMapper mapper = new ObjectMapper(); | |
187 | + System.out.println("dataTable :::: " + mapper.writeValueAsString(dataTable)); | |
188 | + | |
189 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getRowDataAll", dataTable); | |
190 | + } | |
191 | + | |
192 | + @Override | |
193 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
194 | + // TODO Auto-generated method stub | |
195 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getRowDataTotalRows", dataTable); | |
196 | + } | |
197 | + | |
198 | + @Override | |
199 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
200 | + // TODO Auto-generated method stub | |
201 | + return dbUtil.getTemplate().delete("PostgresqlDAO.emptyDataset", dataTable); | |
202 | + } | |
203 | + | |
204 | + @Override | |
205 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
206 | + // TODO Auto-generated method stub | |
207 | + ObjectMapper mapper = new ObjectMapper(); | |
208 | + | |
209 | + System.out.println("tableColumnChange" + mapper.writeValueAsString(tableBasicInfo)); | |
210 | + return dbUtil.getTemplate().update("PostgresqlDAO.tableColumnChange", tableBasicInfo); | |
211 | + } | |
212 | + | |
213 | + @Override | |
214 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
215 | + // TODO Auto-generated method stub | |
216 | + return dbUtil.getTemplate().update("PostgresqlDAO.changePromaryKey", tableBasicInfo); | |
217 | + } | |
218 | + | |
219 | + @Override | |
220 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
221 | + // TODO Auto-generated method stub | |
222 | + return dbUtil.getTemplate().update("PostgresqlDAO.createAutoIncrement", tableBasicInfo); | |
223 | + } | |
224 | + | |
225 | + | |
226 | + @Override | |
227 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
228 | + dbUtil.getTemplate().update("PostgresqlDAO.updateTableMetaInfo", dataTable); | |
229 | + | |
230 | + } | |
231 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/mybatis/config/config.xml
... | ... | @@ -0,0 +1,46 @@ |
1 | +<?xml version="1.0" encoding="UTF-8" ?> | |
2 | +<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> | |
3 | + | |
4 | +<configuration> | |
5 | + <settings> | |
6 | + <setting name="cacheEnabled" value="true"/> <!-- mapper 캐시 전역 사용여부 --> | |
7 | + <setting name="lazyLoadingEnabled" value="false"/> <!-- mybatis 지연 로딩 사용여부 --> | |
8 | + <setting name="multipleResultSetsEnabled" value="true"/> <!-- 한개의 구문에서 여러개의 ResultSet 허용 여부 --> | |
9 | + <setting name="useColumnLabel" value="true"/> <!-- 컬럼명 대신 컬럼라벨 사용 여부 --> | |
10 | + <setting name="useGeneratedKeys" value="false"/> <!-- 키자동생성 --> | |
11 | + <setting name="defaultExecutorType" value="SIMPLE"/> | |
12 | + <setting name="defaultStatementTimeout" value="25000"/> | |
13 | + <setting name="callSettersOnNulls" value="true"/><!-- 조회 조회시, null값 무조건 허용 --> | |
14 | + </settings> | |
15 | + | |
16 | + <typeAliases> | |
17 | + | |
18 | + <typeAlias type="com.takensoft.taken_bi_manager.data.vo.Dataset" alias="Dataset"/> | |
19 | + <typeAlias type="com.takensoft.taken_bi_manager.data.vo.ColumnData" alias="ColumnData"/> | |
20 | + <typeAlias type="com.takensoft.taken_bi_manager.data.vo.DataTable" alias="DataTable"/> | |
21 | + <typeAlias type="com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo" alias="TableBasicInfo"/> | |
22 | + <typeAlias type="com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB" alias="ConnectionDB"/> | |
23 | + | |
24 | + | |
25 | + <!-- etl --> | |
26 | + | |
27 | + <!-- | |
28 | + <typeAlias type="kr.co.sppartners.etl.common.collection.util.db.vo.TableBasicInfo" alias="TableBasicInfo"/> | |
29 | + <typeAlias type="kr.co.sppartners.etl.common.data.vo.DataTable" alias="DataTable"/> | |
30 | + | |
31 | + <typeAlias type="kr.co.sppartners.etl.data.dataset.vo.DatasetPost" alias="DatasetPost"/> | |
32 | + | |
33 | + <typeAlias type="kr.co.sppartners.etl.data.dataset.vo.DBCollection" alias="DBCollection"/> | |
34 | + <typeAlias type="kr.co.sppartners.etl.data.dataset.vo.CollectionTable" alias="CollectionTable"/> | |
35 | + | |
36 | + --> | |
37 | + | |
38 | + | |
39 | + </typeAliases> | |
40 | + | |
41 | + <!-- 사용안함 | |
42 | + <typeHandlers> | |
43 | + <typeHandler handler="kr.co.sppartners.etl.config.MybatisStringTypeHandler"/> | |
44 | + </typeHandlers> | |
45 | + --> | |
46 | +</configuration> |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/mybatis/sql/mariadb-SQL.xml
... | ... | @@ -0,0 +1,571 @@ |
1 | +<?xml version="1.0" encoding="UTF-8" ?> | |
2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
3 | + | |
4 | +<!-- | |
5 | + 작성자 : 최정우 | |
6 | + 작성일 : 2019.11.17 | |
7 | + 내용 : Mariadb 접속 모듈에 관련된 SQL입니다. | |
8 | + --> | |
9 | +<mapper namespace="MariadbDAO"> | |
10 | + | |
11 | + <!-- | |
12 | + 작성자 : 최정우 | |
13 | + 작성일 : 2020.01.27 | |
14 | + 내용 : 커넥션된 데이터베이스의 테이블 목록 조회 SQL입니다. | |
15 | + --> | |
16 | + <select id="getDBConnectionTableList" parameterType="ConnectionDB" resultType="Dataset"> | |
17 | + SELECT | |
18 | + TABLE_SCHEMA AS databaseNm | |
19 | + , TABLE_NAME AS tableNm | |
20 | + FROM | |
21 | + INFORMATION_SCHEMA.TABLES | |
22 | + WHERE | |
23 | + TABLE_SCHEMA = #{databaseNm} | |
24 | + ORDER BY | |
25 | + tableNm ASC | |
26 | + </select> | |
27 | + | |
28 | + <!-- | |
29 | + 작성자 : 최정우 | |
30 | + 작성일 : 2020.01.27 | |
31 | + 내용 : 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
32 | + --> | |
33 | + <select id="getDBConnectionTableColumnList" parameterType="Dataset" resultType="ColumnData"> | |
34 | + SELECT | |
35 | + TABLE_SCHEMA AS databaseNm | |
36 | + , TABLE_NAME AS tableNm | |
37 | + , COLUMN_NAME AS columnNm | |
38 | + , COLUMN_NAME AS displyColumnNm | |
39 | + , COLUMN_NAME AS orginlColumnNm | |
40 | + , DATA_TYPE AS dbDataType | |
41 | + , CHARACTER_MAXIMUM_LENGTH AS dataSize | |
42 | + , ORDINAL_POSITION AS ordr | |
43 | + , CASE WHEN COLUMN_KEY = 'PRI' then true else false end as "pkAt" | |
44 | + , CASE WHEN COLUMN_KEY = 'UNI' then true else false end as "uniqeAt" | |
45 | + FROM | |
46 | + INFORMATION_SCHEMA.COLUMNS | |
47 | + WHERE | |
48 | + TABLE_SCHEMA = #{databaseNm} | |
49 | + AND | |
50 | + TABLE_NAME = #{tableNm} | |
51 | + | |
52 | + </select> | |
53 | + | |
54 | + <!-- | |
55 | + 작성자: 최정우 | |
56 | + 작성일: 2020.01.27 | |
57 | + 내용: 커넥션된 데이터베이스의 테이블의 데이터 목록 조회 SQL입니다.(페이징) | |
58 | + --> | |
59 | + <select id="getDBConnectionTableDataList" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
60 | + SELECT | |
61 | + * | |
62 | + FROM | |
63 | + `${databaseNm}`.`${tableNm}` | |
64 | + WHERE 1 = 1 | |
65 | + | |
66 | + <!-- 검색 --> | |
67 | + <choose> | |
68 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
69 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
70 | + AND | |
71 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
72 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
73 | + `${item.columnName}` LIKE CONCAT('%', #{keyword}, '%') | |
74 | + </foreach> | |
75 | + </foreach> | |
76 | + </when> | |
77 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
78 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
79 | + <otherwise> | |
80 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
81 | + AND | |
82 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
83 | + `${searchCondition}` LIKE CONCAT('%', #{keyword}, '%') | |
84 | + </foreach> | |
85 | + </if> | |
86 | + </otherwise> | |
87 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
88 | + </choose> | |
89 | + <!-- //검색 --> | |
90 | + | |
91 | + <!-- 정렬 --> | |
92 | + <if test="order != null and order != ''"> | |
93 | + ORDER BY `${order}` | |
94 | + <choose> | |
95 | + <!-- 오름차순일 때 --> | |
96 | + <when test="isOrderASC == true"> | |
97 | + ASC | |
98 | + </when> | |
99 | + <!-- //오름차순일 때 --> | |
100 | + <!-- 내림차순일 때 --> | |
101 | + <otherwise> | |
102 | + DESC | |
103 | + </otherwise> | |
104 | + <!-- 내림차순일 때 --> | |
105 | + </choose> | |
106 | + ) AS NUM | |
107 | + </if> | |
108 | + <!-- //정렬 --> | |
109 | + | |
110 | + <if test="isUsePaging == true"> | |
111 | + LIMIT #{perPage} OFFSET #{startIndex} | |
112 | + </if> | |
113 | + </select> | |
114 | + | |
115 | + <!-- | |
116 | + 작성자: 최정우 | |
117 | + 작성일: 2020.01.27 | |
118 | + 내용: 커넥션된 데이터베이스의 테이블의 데이터 목록 총 갯수 조회 SQL입니다. | |
119 | + --> | |
120 | + <select id="getDBConnectionTableDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
121 | + SELECT | |
122 | + COUNT(0) | |
123 | + FROM | |
124 | + `${databaseNm}`.`${tableNm}` | |
125 | + WHERE 1 = 1 | |
126 | + | |
127 | + <!-- 검색 --> | |
128 | + <choose> | |
129 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
130 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
131 | + AND | |
132 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
133 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
134 | + `${item.columnName}` LIKE CONCAT('%', #{keyword}, '%') | |
135 | + </foreach> | |
136 | + </foreach> | |
137 | + </when> | |
138 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
139 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
140 | + <otherwise> | |
141 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
142 | + AND | |
143 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
144 | + `${searchCondition}` LIKE CONCAT('%', #{keyword}, '%') | |
145 | + </foreach> | |
146 | + </if> | |
147 | + </otherwise> | |
148 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
149 | + </choose> | |
150 | + <!-- //검색 --> | |
151 | + </select> | |
152 | + | |
153 | + <!-- | |
154 | + 작성자: 최정우 | |
155 | + 작성일: 2020.01.27 | |
156 | + 내용: 커스텀 테이블 데이터 조회 (페이징사용 유무에 따라 페이징 처리) SQL입니다. | |
157 | + --> | |
158 | + <select id="getDBConnectionCustomQueryDataList" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
159 | + SELECT | |
160 | + a.* | |
161 | + FROM ( | |
162 | + ${query} | |
163 | + ) a | |
164 | + <if test="limit > 0"> | |
165 | + LIMIT #{limit} | |
166 | + </if> | |
167 | + </select> | |
168 | + | |
169 | + <!-- | |
170 | + 작성자: 최정우 | |
171 | + 작성일: 2020.01.27 | |
172 | + 내용: 커스텀 테이블 실행형 | |
173 | + --> | |
174 | + <update id="executeCustomQuery" parameterType="DataTable"> | |
175 | + /*+ RULE */ | |
176 | + ${query} | |
177 | + </update> | |
178 | + | |
179 | + <!-- | |
180 | + 작성자: 최정우 | |
181 | + 작성일: 2020.01.27 | |
182 | + 내용: 커스텀 테이블 데이터 목록 총 갯수 조회 SQL입니다. | |
183 | + --> | |
184 | + <select id="getDBConnectionCustomQueryDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
185 | + SELECT | |
186 | + COUNT(0) | |
187 | + FROM ( | |
188 | + ${query} | |
189 | + ) a | |
190 | + </select> | |
191 | + | |
192 | + <!-- | |
193 | + 작성자: 최정우 | |
194 | + 작성일: 2020.01.27 | |
195 | + 내용: DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴) | |
196 | + --> | |
197 | + <select id="getDBCollectionQueryDataList" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
198 | + SELECT | |
199 | + <foreach item="item" index="index" collection="columnDatas" open="" separator="," close=""> | |
200 | + a.`${item.originColumnName}` AS '${item.columnName}' | |
201 | + </foreach> | |
202 | + FROM ( | |
203 | + ${query} | |
204 | + ) a | |
205 | + | |
206 | + <!-- 검색 --> | |
207 | + <choose> | |
208 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
209 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
210 | + AND | |
211 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
212 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
213 | + a.`${item.originColumnName}` LIKE CONCAT('%', #{keyword}, '%') | |
214 | + </foreach> | |
215 | + </foreach> | |
216 | + </when> | |
217 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
218 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
219 | + <otherwise> | |
220 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
221 | + AND | |
222 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
223 | + a.`${searchCondition}` LIKE CONCAT('%', #{keyword}, '%') | |
224 | + </foreach> | |
225 | + </if> | |
226 | + </otherwise> | |
227 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
228 | + </choose> | |
229 | + <!-- //검색 --> | |
230 | + | |
231 | + <!-- 정렬 --> | |
232 | + <if test="order != null and order != ''"> | |
233 | + ORDER BY `${order}` | |
234 | + <choose> | |
235 | + <!-- 오름차순일 때 --> | |
236 | + <when test="isOrderASC == true"> | |
237 | + ASC | |
238 | + </when> | |
239 | + <!-- //오름차순일 때 --> | |
240 | + <!-- 내림차순일 때 --> | |
241 | + <otherwise> | |
242 | + DESC | |
243 | + </otherwise> | |
244 | + <!-- 내림차순일 때 --> | |
245 | + </choose> | |
246 | + ) AS NUM | |
247 | + </if> | |
248 | + <!-- //정렬 --> | |
249 | + | |
250 | + <if test="isUsePaging == true"> | |
251 | + LIMIT #{perPage} OFFSET #{startIndex} | |
252 | + </if> | |
253 | + </select> | |
254 | + | |
255 | + <!-- | |
256 | + 작성자: 최정우 | |
257 | + 작성일: 2020.01.27 | |
258 | + 내용: DB연계 데이터 목록 총 갯수 조회 | |
259 | + --> | |
260 | + <select id="getDBCollectionQueryDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
261 | + SELECT | |
262 | + COUNT(0) | |
263 | + FROM ( | |
264 | + ${query} | |
265 | + ) a | |
266 | + | |
267 | + <!-- 검색 --> | |
268 | + <choose> | |
269 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
270 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
271 | + AND | |
272 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
273 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
274 | + a.`${item.originColumnName}` LIKE CONCAT('%', #{keyword}, '%') | |
275 | + </foreach> | |
276 | + </foreach> | |
277 | + </when> | |
278 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
279 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
280 | + <otherwise> | |
281 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
282 | + AND | |
283 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
284 | + a.`${searchCondition}` LIKE CONCAT('%', #{keyword}, '%') | |
285 | + </foreach> | |
286 | + </if> | |
287 | + </otherwise> | |
288 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
289 | + </choose> | |
290 | + <!-- //검색 --> | |
291 | + </select> | |
292 | + | |
293 | + <!-- | |
294 | + 작성자: 최정우 | |
295 | + 작성일: 2020.11.29 | |
296 | + 내용: 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) | |
297 | + --> | |
298 | + <select id="getCustomQueryPrimaryOverlapCount" parameterType="DataTable" resultType="java.lang.Integer"> | |
299 | + SELECT | |
300 | + IFNULL(SUM(a.overlapCount), 0) AS totalOverlapCount | |
301 | + FROM ( | |
302 | + SELECT | |
303 | + COUNT(0) AS overlapCount | |
304 | + FROM ( | |
305 | + ${query} | |
306 | + ) t | |
307 | + GROUP BY | |
308 | + <foreach item="item" index="index" collection="columnData" open="" separator="," close=""> | |
309 | + t.`${item.columnName}` | |
310 | + </foreach> | |
311 | + HAVING | |
312 | + COUNT(0) > 1 | |
313 | + ) a | |
314 | + </select> | |
315 | + | |
316 | + <!-- | |
317 | + 작성자 : 김성원 | |
318 | + 작성일 : 2021.01.17 | |
319 | + 내용 : 데이터 셋의 DB화 (테이블 생성) | |
320 | + --> | |
321 | + <update id="datasetTableCreate" parameterType="DataTable"> | |
322 | + CREATE TABLE `${tableNm}` ( | |
323 | + <foreach item="item" index="index" collection="columnDatas" separator=","> | |
324 | + `${item.columnName}` ${item.dbDataType} | |
325 | + <if test="item.dbDataType == 'varchar'">(#{item.size})</if> | |
326 | + <choose> | |
327 | + <when test="item.isPrimary == true"> NOT NULL</when> | |
328 | + <otherwise> DEFAULT NULL</otherwise> | |
329 | + </choose> | |
330 | + </foreach> | |
331 | + , PRIMARY KEY ( | |
332 | + <foreach item="item" index="index" collection="columnDatas" separator=","> | |
333 | + <if test="item.isPrimary == true"> | |
334 | + `${item.columnName}` | |
335 | + </if> | |
336 | + </foreach> | |
337 | + ) | |
338 | + <foreach item="item" index="index" collection="columnDatas"> | |
339 | + <if test="item.isUniq == true"> | |
340 | + , UNIQUE INDEX `${tableNm}_${item.columnName}_UNIQUE` (`${item.columnName}` ASC) | |
341 | + </if> | |
342 | + </foreach> | |
343 | + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 | |
344 | + <if test="title != null and title != ''"> | |
345 | + COMMENT = #{title} | |
346 | + </if> | |
347 | + </update> | |
348 | + | |
349 | + <!-- | |
350 | + 작성자 : 김성원 | |
351 | + 작성일 : 2021.01.17 | |
352 | + 내용 : 데이터 셋의 DB화 (테이블 생성) | |
353 | + --> | |
354 | + <update id="datasetDefaultTableCreate" parameterType="DataTable"> | |
355 | + CREATE TABLE `${tableNm}` ( | |
356 | + `spm_row` bigint NOT NULL AUTO_INCREMENT | |
357 | + <foreach item="item" index="index" collection="columnDatas"> | |
358 | + ,`${item.columnName}` ${item.dbDataType} | |
359 | + <if test="item.dbDataType == 'varchar'"> | |
360 | + (#{item.size}) | |
361 | + </if> | |
362 | + DEFAULT NULL | |
363 | + </foreach> | |
364 | + , PRIMARY KEY (`spm_row`) | |
365 | + <foreach item="item" index="index" collection="columnDatas"> | |
366 | + <if test="item.isUniq == true"> | |
367 | + , UNIQUE INDEX `${tableNm}_${item.columnName}_UNIQUE` (`${item.columnName}` ASC) | |
368 | + </if> | |
369 | + </foreach> | |
370 | + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 | |
371 | + <if test="title != null and title != ''"> | |
372 | + COMMENT = #{title} | |
373 | + </if> | |
374 | + </update> | |
375 | + | |
376 | + <!-- | |
377 | + 작성자 : 김성원 | |
378 | + 작성일 : 2021.01.17 | |
379 | + 내용 : 데이터 셋의 DB화 (데이터 생성 및 업데이트) | |
380 | + --> | |
381 | + <update id="datasetDataUpdate" parameterType="DataTable"> | |
382 | + REPLACE INTO `${tableNm}` | |
383 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator="," close=")"> | |
384 | + `${item.columnName}` | |
385 | + </foreach> | |
386 | + VALUES | |
387 | + <foreach item="row" collection="rowData" separator=","> | |
388 | + ( | |
389 | + <foreach item="cell" index="index" collection="row" separator=","> | |
390 | + #{cell} | |
391 | + <!-- | |
392 | + <choose> | |
393 | + <when test="columnDatas[index].dbDataType == 'varchar' or columnDatas[index].dbDataType == 'datetime'">#{cell}</when> | |
394 | + <otherwise>${cell}</otherwise> | |
395 | + </choose> | |
396 | + --> | |
397 | + </foreach> | |
398 | + ) | |
399 | + </foreach> | |
400 | + </update> | |
401 | + | |
402 | + | |
403 | + <!-- | |
404 | + 작성자 : 김성원 | |
405 | + 작성일 : 2021.01.17 | |
406 | + 내용 : 데이터 셋의 ROW 삭제 | |
407 | + --> | |
408 | + <update id="datasetDataDelete" parameterType="DataTable"> | |
409 | + DELETE FROM ${tableNm} | |
410 | + WHERE | |
411 | + 1 = 1 | |
412 | + <foreach item="item" index="index" collection="columnDatas" open=" AND " separator=" AND " close=""> | |
413 | + `${item.columnName}` in | |
414 | + <foreach item="items" index="indexs" collection="item.values" open="(" separator=", " close=")"> | |
415 | + #{items.value} | |
416 | + </foreach> | |
417 | + </foreach> | |
418 | + </update> | |
419 | + | |
420 | + <!-- | |
421 | + 작성자 : 김성원 | |
422 | + 작성일 : 2021.01.17 | |
423 | + 내용 : 중복 테이블명 체크 | |
424 | + --> | |
425 | + <select id="duplicateChecktableNm" parameterType="Map" resultType="INTEGER"> | |
426 | + SELECT count(*) | |
427 | + FROM | |
428 | + Information_schema.tables | |
429 | + WHERE | |
430 | + TABLE_SCHEMA = #{schema} | |
431 | + AND | |
432 | + TABLE_NAME = #{tableNm}; | |
433 | + </select> | |
434 | + | |
435 | + <!-- | |
436 | + 작성자 : 김성원 | |
437 | + 작성일 : 2021.01.17 | |
438 | + 내용: 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징) | |
439 | + --> | |
440 | + <select id="getRowData" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
441 | + SELECT | |
442 | + <foreach item="item" index="index" collection="columnDatas" open="" separator="," close=""> | |
443 | + `${item.columnName}`<!-- AS `${item.displayColumnName}` --> | |
444 | + </foreach> | |
445 | + FROM | |
446 | + `${tableNm}` | |
447 | + WHERE 1 | |
448 | + | |
449 | + <!-- 검색 --> | |
450 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
451 | + AND | |
452 | + `${searchCondition}` LIKE CONCAT('%', #{searchKeyword}, '%') | |
453 | + </if> | |
454 | + <!-- //검색 --> | |
455 | + | |
456 | + <!-- 정렬 --> | |
457 | + <if test="order != null and order != ''"> | |
458 | + ORDER BY `${order}` | |
459 | + <choose> | |
460 | + <!-- 오름차순일 때 --> | |
461 | + <when test="isOrderASC == true"> | |
462 | + ASC | |
463 | + </when> | |
464 | + <!-- //오름차순일 때 --> | |
465 | + <!-- 내림차순일 때 --> | |
466 | + <otherwise> | |
467 | + DESC | |
468 | + </otherwise> | |
469 | + <!-- 내림차순일 때 --> | |
470 | + </choose> | |
471 | + ) AS NUM | |
472 | + </if> | |
473 | + <!-- //정렬 --> | |
474 | + | |
475 | + LIMIT #{perPage} OFFSET #{startIndex} | |
476 | + </select> | |
477 | + | |
478 | + <!-- | |
479 | + 작성자: 김성원 | |
480 | + 작성일: 2022.01.17 | |
481 | + 내용: 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(노페이징) | |
482 | + --> | |
483 | + <select id="getRowDataAll" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
484 | + SELECT | |
485 | + <foreach item="item" index="index" collection="columnDatas" open="" separator="," close=""> | |
486 | + `${item.columnName}`<!-- AS `${item.displayColumnName}` --> | |
487 | + </foreach> | |
488 | + FROM | |
489 | + `${tableNm}` | |
490 | + <if test="query != null and query != ''"> | |
491 | + WHERE 1 | |
492 | + ${query} | |
493 | + </if> | |
494 | + </select> | |
495 | + | |
496 | + <!-- | |
497 | + 작성자: 김성원 | |
498 | + 작성일: 2022.01.17 | |
499 | + 내용: 데이터 셋의 컬럼 정보 목록 총 갯수 조회 SQL | |
500 | + --> | |
501 | + <select id="getRowDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
502 | + SELECT | |
503 | + COUNT(0) | |
504 | + FROM | |
505 | + `${tableNm}` | |
506 | + WHERE 1 | |
507 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
508 | + AND | |
509 | + `${searchCondition}` LIKE CONCAT('%', #{searchKeyword}, '%') | |
510 | + </if> | |
511 | + </select> | |
512 | + | |
513 | + <!-- | |
514 | + 작성자: 김성원 | |
515 | + 작성일: 2022.01.17 | |
516 | + 내용 : 데이터 셋의 비우기 (데이터 셋 내용삭제) | |
517 | + --> | |
518 | + <delete id="emptyDataset" parameterType="DataTable"> | |
519 | + DELETE FROM `${tableNm}` | |
520 | + </delete> | |
521 | + | |
522 | + <!-- | |
523 | + 작성자 : 김성원 | |
524 | + 작성일 : 2022.01.20 | |
525 | + 내용 : 실제 생성된 컬럼 변경 | |
526 | + --> | |
527 | + <update id="tableColumnChange" parameterType="TableBasicInfo"> | |
528 | + ALTER TABLE `${tableNm}` ${process} `${columnName}` | |
529 | + <if test="process == 'CHANGE'"> | |
530 | + `${tobeColumnName}` ${dataType} | |
531 | + </if> | |
532 | + <if test="process == 'MODIFY' || process == 'ADD' ">${dataType}</if><if test="dataType == 'varchar' and process != 'DROP'">(${size})</if> | |
533 | + </update> | |
534 | + | |
535 | + | |
536 | + <!-- | |
537 | + 작성자 : 김성원 | |
538 | + 작성일 : 2022.01.20 | |
539 | + 내용 : 실제 생성된 테이블 PK처리 | |
540 | + --> | |
541 | + <update id="changePromaryKey" parameterType="TableBasicInfo"> | |
542 | + ALTER TABLE `${tableNm}` ${process} PRIMARY KEY | |
543 | + <if test="process != 'DROP'"> | |
544 | + <foreach item="item" index="index" collection="primaryList" open=" (" separator=", " close=")"> | |
545 | + ${item} | |
546 | + </foreach> | |
547 | + </if> | |
548 | + </update> | |
549 | + | |
550 | + <!-- | |
551 | + 작성자 : 김성원 | |
552 | + 작성일 : 2022.01.20 | |
553 | + 내용 : AI PK 생성 | |
554 | + --> | |
555 | + <update id="createAutoIncrement" parameterType="TableBasicInfo"> | |
556 | + ALTER TABLE `${tableNm}` ADD `${columnName}` | |
557 | + BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST | |
558 | + </update> | |
559 | + | |
560 | + <!-- | |
561 | + 작성자 : 김성원 | |
562 | + 작성일 : 2022.09.30 | |
563 | + 내용 : 테이블 메타정보 변경 (comments) | |
564 | + --> | |
565 | + <update id="updateTableMetaInfo" parameterType="DataTable"> | |
566 | + ALTER TABLE ${tableNm} | |
567 | + COMMENT = #{title} | |
568 | + </update> | |
569 | + | |
570 | + | |
571 | +</mapper>(No newline at end of file) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/mybatis/sql/postgre-SQL.xml
... | ... | @@ -0,0 +1,601 @@ |
1 | +<?xml version="1.0" encoding="UTF-8" ?> | |
2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
3 | + | |
4 | +<!-- | |
5 | + 작성자 : 최정우 | |
6 | + 작성일 : 2019.11.17 | |
7 | + 내용 : PostgreSQL 접속 모듈에 관련된 SQL입니다. | |
8 | + --> | |
9 | +<mapper namespace="PostgresqlDAO"> | |
10 | + | |
11 | + <!-- | |
12 | + 작성자 : 최정우 | |
13 | + 작성일 : 2020.01.27 | |
14 | + 내용 : 커넥션된 데이터베이스의 테이블 목록 조회 SQL입니다. | |
15 | + --> | |
16 | + <select id="getDBConnectionTableList" parameterType="ConnectionDB" resultType="Dataset"> | |
17 | + SELECT | |
18 | + schemaname AS "databaseNm" | |
19 | + , tableName AS "tableNm" | |
20 | + FROM | |
21 | + PG_TABLES | |
22 | + WHERE | |
23 | + schemaname = #{schemaNm} | |
24 | + ORDER BY | |
25 | + tableName ASC | |
26 | + </select> | |
27 | + | |
28 | + <!-- | |
29 | + 작성자 : 최정우 | |
30 | + 작성일 : 2020.01.27 | |
31 | + 내용 : 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
32 | + --> | |
33 | + <select id="getDBConnectionTableColumnList" parameterType="Dataset" resultType="ColumnData"> | |
34 | + SELECT | |
35 | + A.TABLE_SCHEMA AS "databaseNm" | |
36 | + , A.TABLE_NAME AS "tableNm" | |
37 | + , A.COLUMN_NAME AS "columnNm" | |
38 | + , A.COLUMN_NAME AS "displyColumnNm" | |
39 | + , A.COLUMN_NAME AS "orginlColumnNm" | |
40 | + , A.ORDINAL_POSITION as "ordr" | |
41 | + , A.DATA_TYPE AS "dbDataType" | |
42 | + , A.CHARACTER_MAXIMUM_LENGTH AS "dataSize" | |
43 | + , case when c.constraint_type = 'PRIMARY KEY' then true else false end as "pkAt" | |
44 | + , case when c.constraint_type = 'UNIQUE' then true else false end as "uniqeAt" | |
45 | + FROM | |
46 | + INFORMATION_SCHEMA.columns A | |
47 | + left join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE B on A.table_name = B.table_name and B.column_name = A.column_name | |
48 | + left join INFORMATION_SCHEMA.TABLE_CONSTRAINTS C on B.constraint_name = C.constraint_name | |
49 | + WHERE | |
50 | + A.table_catalog = #{databaseNm} | |
51 | + AND | |
52 | + A.TABLE_NAME = #{tableNm} | |
53 | + | |
54 | + </select> | |
55 | + | |
56 | + <!-- | |
57 | + 작성자: 최정우 | |
58 | + 작성일: 2020.01.27 | |
59 | + 내용: 커넥션된 데이터베이스의 테이블의 데이터 목록 조회 SQL입니다.(페이징) | |
60 | + --> | |
61 | + <select id="getDBConnectionTableDataList" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
62 | + SELECT | |
63 | + * | |
64 | + FROM | |
65 | + ${tableNm} | |
66 | + WHERE 1 = 1 | |
67 | + <!-- 검색 --> | |
68 | + <choose> | |
69 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
70 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
71 | + AND | |
72 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
73 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
74 | + ${item.columnName} LIKE CONCAT('%', #{keyword}, '%') | |
75 | + </foreach> | |
76 | + </foreach> | |
77 | + </when> | |
78 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
79 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
80 | + <otherwise> | |
81 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
82 | + AND | |
83 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
84 | + ${searchCondition} LIKE CONCAT('%', #{keyword}, '%') | |
85 | + </foreach> | |
86 | + </if> | |
87 | + </otherwise> | |
88 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
89 | + </choose> | |
90 | + <!-- //검색 --> | |
91 | + | |
92 | + <!-- 정렬 --> | |
93 | + <if test="order != null and order != ''"> | |
94 | + ORDER BY ${order} | |
95 | + <choose> | |
96 | + <!-- 오름차순일 때 --> | |
97 | + <when test="isOrderASC == true"> | |
98 | + ASC | |
99 | + </when> | |
100 | + <!-- //오름차순일 때 --> | |
101 | + <!-- 내림차순일 때 --> | |
102 | + <otherwise> | |
103 | + DESC | |
104 | + </otherwise> | |
105 | + <!-- 내림차순일 때 --> | |
106 | + </choose> | |
107 | + ) AS NUM | |
108 | + </if> | |
109 | + <!-- //정렬 --> | |
110 | + | |
111 | + <if test="isUsePaging == true"> | |
112 | + LIMIT #{perPage} OFFSET #{startIndex} | |
113 | + </if> | |
114 | + </select> | |
115 | + | |
116 | + <!-- | |
117 | + 작성자: 최정우 | |
118 | + 작성일: 2020.01.27 | |
119 | + 내용: 커넥션된 데이터베이스의 테이블의 데이터 목록 총 갯수 조회 SQL입니다. | |
120 | + --> | |
121 | + <select id="getDBConnectionTableDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
122 | + SELECT | |
123 | + COUNT(0) | |
124 | + FROM | |
125 | + ${tableNm} | |
126 | + WHERE 1 = 1 | |
127 | + <!-- 검색 --> | |
128 | + <choose> | |
129 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
130 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
131 | + AND | |
132 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
133 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
134 | + ${item.columnName} LIKE CONCAT('%', #{keyword}, '%') | |
135 | + </foreach> | |
136 | + </foreach> | |
137 | + </when> | |
138 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
139 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
140 | + <otherwise> | |
141 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
142 | + AND | |
143 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
144 | + ${searchCondition} LIKE CONCAT('%', #{keyword}, '%') | |
145 | + </foreach> | |
146 | + </if> | |
147 | + </otherwise> | |
148 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
149 | + </choose> | |
150 | + <!-- //검색 --> | |
151 | + </select> | |
152 | + | |
153 | + <!-- | |
154 | + 작성자: 최정우 | |
155 | + 작성일: 2020.01.27 | |
156 | + 내용: 커스텀 테이블 데이터 조회 (페이징사용 유무에 따라 페이징 처리) SQL입니다. | |
157 | + --> | |
158 | + <select id="getDBConnectionCustomQueryDataList" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
159 | + SELECT | |
160 | + a.* | |
161 | + FROM ( | |
162 | + ${query} | |
163 | + ) a | |
164 | + <if test="limit > 0"> | |
165 | + LIMIT #{limit} | |
166 | + </if> | |
167 | + </select> | |
168 | + | |
169 | + <!-- | |
170 | + 작성자: 최정우 | |
171 | + 작성일: 2020.01.27 | |
172 | + 내용: 커스텀 테이블 실행형 | |
173 | + --> | |
174 | + <update id="executeCustomQuery" parameterType="DataTable"> | |
175 | + /*+ RULE */ | |
176 | + ${query} | |
177 | + </update> | |
178 | + | |
179 | + <!-- | |
180 | + 작성자: 최정우 | |
181 | + 작성일: 2020.01.27 | |
182 | + 내용: 커스텀 테이블 데이터 목록 총 갯수 조회 SQL입니다. | |
183 | + --> | |
184 | + <select id="getDBConnectionCustomQueryDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
185 | + SELECT | |
186 | + COUNT(0) | |
187 | + FROM ( | |
188 | + ${query} | |
189 | + ) a | |
190 | + </select> | |
191 | + | |
192 | + <!-- | |
193 | + 작성자: 최정우 | |
194 | + 작성일: 2020.01.27 | |
195 | + 내용: DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴) | |
196 | + --> | |
197 | + <select id="getDBCollectionQueryDataList" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
198 | + SELECT | |
199 | + <foreach item="item" index="index" collection="columnDatas" open="" separator="," close=""> | |
200 | + a.${item.originColumnName} AS '${item.columnName}' | |
201 | + </foreach> | |
202 | + FROM ( | |
203 | + ${query} | |
204 | + ) a | |
205 | + | |
206 | + <!-- 검색 --> | |
207 | + <choose> | |
208 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
209 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
210 | + AND | |
211 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
212 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
213 | + a.${item.originColumnName} LIKE CONCAT('%', #{keyword}, '%') | |
214 | + </foreach> | |
215 | + </foreach> | |
216 | + </when> | |
217 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
218 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
219 | + <otherwise> | |
220 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
221 | + AND | |
222 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
223 | + a.${searchCondition} LIKE CONCAT('%', #{keyword}, '%') | |
224 | + </foreach> | |
225 | + </if> | |
226 | + </otherwise> | |
227 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
228 | + </choose> | |
229 | + <!-- //검색 --> | |
230 | + | |
231 | + <!-- 정렬 --> | |
232 | + <if test="order != null and order != ''"> | |
233 | + ORDER BY ${order} | |
234 | + <choose> | |
235 | + <!-- 오름차순일 때 --> | |
236 | + <when test="isOrderASC == true"> | |
237 | + ASC | |
238 | + </when> | |
239 | + <!-- //오름차순일 때 --> | |
240 | + <!-- 내림차순일 때 --> | |
241 | + <otherwise> | |
242 | + DESC | |
243 | + </otherwise> | |
244 | + <!-- 내림차순일 때 --> | |
245 | + </choose> | |
246 | + ) AS NUM | |
247 | + </if> | |
248 | + <!-- //정렬 --> | |
249 | + | |
250 | + <if test="isUsePaging == true"> | |
251 | + LIMIT #{perPage} OFFSET #{startIndex} | |
252 | + </if> | |
253 | + </select> | |
254 | + | |
255 | + <!-- | |
256 | + 작성자: 최정우 | |
257 | + 작성일: 2020.01.27 | |
258 | + 내용: DB연계 데이터 목록 총 갯수 조회 | |
259 | + --> | |
260 | + <select id="getDBCollectionQueryDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
261 | + SELECT | |
262 | + COUNT(0) | |
263 | + FROM ( | |
264 | + ${query} | |
265 | + ) a | |
266 | + | |
267 | + <!-- 검색 --> | |
268 | + <choose> | |
269 | + <!-- 컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
270 | + <when test="columnDatas != null and columnDatas.size() > 0 and (searchCondition == null or searchCondition == '') and searchKeyword != null and searchKeyword != ''"> | |
271 | + AND | |
272 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator=" OR " close=")"> | |
273 | + <foreach item="keyword" index="index2" collection="searchKeywordList" separator=" OR "> | |
274 | + a.${item.originColumnName} LIKE CONCAT('%', #{keyword}, '%') | |
275 | + </foreach> | |
276 | + </foreach> | |
277 | + </when> | |
278 | + <!-- //컬럼 데이터 목록이 존재하고, 검색 조건이 없고, 검색 키워드가 있을 때 --> | |
279 | + <!-- 컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
280 | + <otherwise> | |
281 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
282 | + AND | |
283 | + <foreach item="keyword" index="index2" collection="searchKeywordList" open="(" separator=" OR " close=")"> | |
284 | + a.${searchCondition} LIKE CONCAT('%', #{keyword}, '%') | |
285 | + </foreach> | |
286 | + </if> | |
287 | + </otherwise> | |
288 | + <!-- //컬럼 데이터 목록이 존재하지 않거나, 검색 조건이 있거나, 검색 키워드가 있을 때 --> | |
289 | + </choose> | |
290 | + <!-- //검색 --> | |
291 | + </select> | |
292 | + | |
293 | + <!-- | |
294 | + 작성자: 최정우 | |
295 | + 작성일: 2020.11.29 | |
296 | + 내용: 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) | |
297 | + --> | |
298 | + <select id="getCustomQueryPrimaryOverlapCount" parameterType="DataTable" resultType="java.lang.Integer"> | |
299 | + SELECT | |
300 | + IFNULL(SUM(a.overlapCount), 0) AS totalOverlapCount | |
301 | + FROM ( | |
302 | + SELECT | |
303 | + COUNT(0) AS overlapCount | |
304 | + FROM ( | |
305 | + ${query} | |
306 | + ) t | |
307 | + GROUP BY | |
308 | + <foreach item="item" index="index" collection="columnData" open="" separator="," close=""> | |
309 | + t.${item.columnName} | |
310 | + </foreach> | |
311 | + HAVING | |
312 | + COUNT(0) > 1 | |
313 | + ) a | |
314 | + </select> | |
315 | + | |
316 | + <!-- | |
317 | + 작성자 : 김성원 | |
318 | + 작성일 : 2021.01.17 | |
319 | + 내용 : 데이터 셋의 DB화 (테이블 생성) | |
320 | + --> | |
321 | + <update id="datasetTableCreate" parameterType="DataTable"> | |
322 | + CREATE TABLE ${tableNm} ( | |
323 | + <foreach item="item" index="index" collection="columnDatas" separator=","> | |
324 | + ${item.columnName} ${item.dbDataType} | |
325 | + <if test="item.dbDataType == 'varchar'">(#{item.size})</if> | |
326 | + <choose> | |
327 | + <when test="item.isPrimary == true"> NOT NULL</when> | |
328 | + <otherwise> DEFAULT NULL</otherwise> | |
329 | + </choose> | |
330 | + </foreach> | |
331 | + , PRIMARY KEY ( | |
332 | + <foreach item="item" index="index" collection="columnDatas" separator=","> | |
333 | + <if test="item.isPrimary == true"> | |
334 | + ${item.columnName} | |
335 | + </if> | |
336 | + </foreach> | |
337 | + ) | |
338 | + <foreach item="item" index="index" collection="columnDatas"> | |
339 | + <if test="item.isUniq == true"> | |
340 | + , UNIQUE INDEX ${tableNm}_${item.columnName}_UNIQUE (${item.columnName} ASC) | |
341 | + </if> | |
342 | + </foreach> | |
343 | + ) ; | |
344 | + <if test="title != null and title != ''"> | |
345 | + COMMENT ON TABLE ${tableNm} IS #{title}; | |
346 | + </if> | |
347 | + </update> | |
348 | + | |
349 | + <!-- | |
350 | + 작성자 : 김성원 | |
351 | + 작성일 : 2021.01.17 | |
352 | + 내용 : 데이터 셋의 DB화 (테이블 생성) | |
353 | + --> | |
354 | + <update id="datasetDefaultTableCreate" parameterType="DataTable"> | |
355 | + CREATE TABLE ${tableNm} ( | |
356 | + spm_row SERIAL PRIMARY KEY | |
357 | + <foreach item="item" index="index" collection="columnDatas"> | |
358 | + <if test="item.dbDataType == 'double'"> | |
359 | + , ${item.columnName} numeric | |
360 | + </if> | |
361 | + <if test="item.dbDataType != 'double'"> | |
362 | + , ${item.columnName} ${item.dbDataType} | |
363 | + </if> | |
364 | + <if test="item.dbDataType == 'varchar'"> | |
365 | + (${item.size}) | |
366 | + </if> | |
367 | + DEFAULT NULL | |
368 | + </foreach> | |
369 | + <foreach item="item" index="index" collection="columnDatas"> | |
370 | + <if test="item.isUniq == true"> | |
371 | + , UNIQUE INDEX ${tableNm}_${item.columnName}_UNIQUE (${item.columnName} ASC) | |
372 | + </if> | |
373 | + </foreach> | |
374 | + ); | |
375 | + <if test="title != null and title != ''"> | |
376 | + COMMENT ON TABLE ${tableNm} IS '${title}'; | |
377 | + </if> | |
378 | + </update> | |
379 | + | |
380 | + <!-- | |
381 | + 작성자 : 김성원 | |
382 | + 작성일 : 2021.01.17 | |
383 | + 내용 : 데이터 셋의 DB화 (데이터 생성 및 업데이트) | |
384 | + --> | |
385 | + <update id="datasetDataUpdate" parameterType="DataTable"> | |
386 | + INSERT INTO ${tableNm} | |
387 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator="," close=")"> | |
388 | + <if test="columnDatas[index].AutoIncrement != null and columnDatas[index].AutoIncrement == false"> | |
389 | + ${item.columnName} | |
390 | + </if> | |
391 | + | |
392 | + </foreach> | |
393 | + VALUES | |
394 | + <foreach item="row" collection="rowData" separator=","> | |
395 | + ( | |
396 | + | |
397 | + <foreach item="cell" index="index" collection="row" separator=","> | |
398 | + <if test="columnDatas[index].AutoIncrement == false"> | |
399 | + <choose> | |
400 | + <when test="columnDatas[index].dbDataType == 'varchar' or columnDatas[index].dbDataType == 'datetime'">#{cell}</when> | |
401 | + <otherwise>${cell}</otherwise> | |
402 | + </choose> | |
403 | + </if> | |
404 | + </foreach> | |
405 | + ) | |
406 | + </foreach> | |
407 | + ON CONFLICT ON CONSTRAINT ${tableNm}_pkey | |
408 | + DO UPDATE | |
409 | + SET | |
410 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator="," close=")"> | |
411 | + <if test="columnDatas[index].AutoIncrement != null and columnDatas[index].AutoIncrement == false"> | |
412 | + ${item.columnName} | |
413 | + </if> | |
414 | + </foreach> | |
415 | + = | |
416 | + <foreach item="item" index="index" collection="columnDatas" open="(" separator="," close=")"> | |
417 | + <if test="columnDatas[index].AutoIncrement != null and columnDatas[index].AutoIncrement == false"> | |
418 | + ExCLUDED.${item.columnName} | |
419 | + </if> | |
420 | + </foreach> | |
421 | + </update> | |
422 | + | |
423 | + | |
424 | + <!-- | |
425 | + 작성자 : 김성원 | |
426 | + 작성일 : 2021.01.17 | |
427 | + 내용 : 데이터 셋의 ROW 삭제 | |
428 | + --> | |
429 | + <update id="datasetDataDelete" parameterType="DataTable"> | |
430 | + DELETE FROM ${tableNm} | |
431 | + WHERE | |
432 | + 1 = 1 | |
433 | + <foreach item="item" index="index" collection="columnDatas" open=" AND " separator=" AND " close=""> | |
434 | + ${item.columnName} in | |
435 | + <foreach item="items" index="indexs" collection="item.values" open="(" separator=", " close=")"> | |
436 | + #{items.value} | |
437 | + </foreach> | |
438 | + </foreach> | |
439 | + </update> | |
440 | + | |
441 | + <!-- | |
442 | + 작성자 : 김성원 | |
443 | + 작성일 : 2021.01.17 | |
444 | + 내용 : 중복 테이블명 체크 | |
445 | + --> | |
446 | + <select id="duplicateChecktableNm" parameterType="Map" resultType="INTEGER"> | |
447 | + SELECT count(*) | |
448 | + FROM | |
449 | + Information_schema.tables | |
450 | + WHERE | |
451 | + table_catalog = #{schema} | |
452 | + AND | |
453 | + TABLE_NAME = #{tableNm}; | |
454 | + </select> | |
455 | + | |
456 | + <!-- | |
457 | + 작성자 : 김성원 | |
458 | + 작성일 : 2021.01.17 | |
459 | + 내용: 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징) | |
460 | + --> | |
461 | + <select id="getRowData" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
462 | + SELECT | |
463 | + <foreach item="item" index="index" collection="columnDatas" open="" separator="," close=""> | |
464 | + ${item.columnName}<!-- AS `${item.displayColumnName}` --> | |
465 | + </foreach> | |
466 | + FROM | |
467 | + ${tableNm} | |
468 | + WHERE true | |
469 | + | |
470 | + <!-- 검색 --> | |
471 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
472 | + AND | |
473 | + ${searchCondition} LIKE CONCAT('%', #{searchKeyword}, '%') | |
474 | + </if> | |
475 | + <!-- //검색 --> | |
476 | + | |
477 | + <!-- 정렬 --> | |
478 | + <if test="order != null and order != ''"> | |
479 | + ORDER BY ${order} | |
480 | + <choose> | |
481 | + <!-- 오름차순일 때 --> | |
482 | + <when test="isOrderASC == true"> | |
483 | + ASC | |
484 | + </when> | |
485 | + <!-- //오름차순일 때 --> | |
486 | + <!-- 내림차순일 때 --> | |
487 | + <otherwise> | |
488 | + DESC | |
489 | + </otherwise> | |
490 | + <!-- 내림차순일 때 --> | |
491 | + </choose> | |
492 | + ) AS NUM | |
493 | + </if> | |
494 | + <!-- //정렬 --> | |
495 | + | |
496 | + LIMIT #{perPage} OFFSET #{startIndex} | |
497 | + </select> | |
498 | + | |
499 | + <!-- | |
500 | + 작성자: 김성원 | |
501 | + 작성일: 2022.01.17 | |
502 | + 내용: 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(노페이징) | |
503 | + --> | |
504 | + <select id="getRowDataAll" parameterType="DataTable" resultType="java.util.LinkedHashMap"> | |
505 | + SELECT | |
506 | + <foreach item="item" index="index" collection="columnDatas" open="" separator="," close=""> | |
507 | + ${item.columnName}<!-- AS `${item.displayColumnName}` --> | |
508 | + </foreach> | |
509 | + FROM | |
510 | + ${tableNm} | |
511 | + <if test="query != null and query != ''"> | |
512 | + WHERE 1 = 1 | |
513 | +<!-- AND --> | |
514 | + ${query} | |
515 | + </if> | |
516 | + </select> | |
517 | + | |
518 | + <!-- | |
519 | + 작성자: 김성원 | |
520 | + 작성일: 2022.01.17 | |
521 | + 내용: 데이터 셋의 컬럼 정보 목록 총 갯수 조회 SQL | |
522 | + --> | |
523 | + <select id="getRowDataTotalRows" parameterType="DataTable" resultType="java.lang.Integer"> | |
524 | + SELECT | |
525 | + COUNT(0) | |
526 | + FROM | |
527 | + ${tableNm} | |
528 | + WHERE 1=1 | |
529 | + <if test="searchCondition != null and searchCondition != '' and searchKeyword != null and searchKeyword != ''"> | |
530 | + AND | |
531 | + ${searchCondition} LIKE CONCAT('%', #{searchKeyword}, '%') | |
532 | + </if> | |
533 | + </select> | |
534 | + | |
535 | + <!-- | |
536 | + 작성자: 김성원 | |
537 | + 작성일: 2022.01.17 | |
538 | + 내용 : 데이터 셋의 비우기 (데이터 셋 내용삭제) | |
539 | + --> | |
540 | + <delete id="emptyDataset" parameterType="DataTable"> | |
541 | + DELETE FROM ${tableNm} | |
542 | + </delete> | |
543 | + | |
544 | + <!-- | |
545 | + 작성자 : 김성원 | |
546 | + 작성일 : 2022.01.20 | |
547 | + 내용 : 실제 생성된 컬럼 변경 | |
548 | + --> | |
549 | + <update id="tableColumnChange" parameterType="TableBasicInfo"> | |
550 | + ALTER TABLE ${tableNm} | |
551 | + | |
552 | + | |
553 | + ${process} | |
554 | + <if test="process == 'RENAME'"> | |
555 | + COLUMN | |
556 | + </if> | |
557 | + ${columnName} | |
558 | + <if test="process == 'RENAME'"> | |
559 | + TO ${tobeColumnName} | |
560 | + </if> | |
561 | + <if test="process == 'MODIFY' || process == 'ADD' ">${dataType}<if test="dataType == 'varchar' and process != 'DROP'">(${size})</if></if> | |
562 | + </update> | |
563 | + | |
564 | + | |
565 | + <!-- | |
566 | + 작성자 : 김성원 | |
567 | + 작성일 : 2022.01.20 | |
568 | + 내용 : 실제 생성된 테이블 PK처리 | |
569 | + --> | |
570 | + <update id="changePromaryKey" parameterType="TableBasicInfo"> | |
571 | + ALTER TABLE ${tableNm} ${process} PRIMARY KEY | |
572 | + <if test="process != 'DROP'"> | |
573 | + <foreach item="item" index="index" collection="primaryList" open=" (" separator=", " close=")"> | |
574 | + ${item} | |
575 | + </foreach> | |
576 | + </if> | |
577 | + </update> | |
578 | + | |
579 | + <!-- | |
580 | + 작성자 : 김성원 | |
581 | + 작성일 : 2022.01.20 | |
582 | + 내용 : AI PK 생성 | |
583 | + --> | |
584 | + <update id="createAutoIncrement" parameterType="TableBasicInfo"> | |
585 | + ALTER TABLE ${tableNm} ADD ${columnName} | |
586 | + BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST | |
587 | + </update> | |
588 | + | |
589 | + | |
590 | + <!-- | |
591 | + 작성자 : 김혜민 | |
592 | + 작성일 : 2022.09.30 | |
593 | + 내용 : 테이블 메타정보 변경 (comments) | |
594 | + --> | |
595 | + <update id="updateTableMetaInfo" parameterType="DataTable"> | |
596 | + COMMENT ON TABLE ${tableNm} IS #{title} | |
597 | + | |
598 | +<!-- ALTER TABLE ${tableNm} --> | |
599 | +<!-- COMMENT = #{title} --> | |
600 | + </update> | |
601 | +</mapper>(No newline at end of file) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionConfig.java
... | ... | @@ -0,0 +1,180 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.util; | |
2 | + | |
3 | +import java.sql.SQLException; | |
4 | + | |
5 | +import org.mybatis.spring.SqlSessionFactoryBean; | |
6 | +import org.mybatis.spring.SqlSessionTemplate; | |
7 | +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; | |
8 | +import org.springframework.jdbc.datasource.DataSourceTransactionManager; | |
9 | + | |
10 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
11 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
12 | +import com.zaxxer.hikari.HikariDataSource; | |
13 | + | |
14 | +/** | |
15 | + * @author 김성원 | |
16 | + * @since 2024.01.02 | |
17 | + * | |
18 | + * 동적 데이터 베이스 연계 관리 클래스 입니다. | |
19 | + */ | |
20 | +public class DBConnectionConfig { | |
21 | + | |
22 | + //프로젝트 내부 Class Path 정보 | |
23 | + // 한개 logger.debug(pathMatchingResourcePatternResolver.getResource("절대경로 혹은 classpath:이하경로").getFile().getAbsolutePath()); | |
24 | + // 여러개 Resource[] resource = pathMatchingResourcePatternResolver.getResources("절대경로 혹은 classpath:이하경로"); | |
25 | + private final static PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); | |
26 | + | |
27 | + //동적 Mybatis 연계 - mybatis 설정 정보 파일 경로 | |
28 | + private final static String DYNAMIC_MYBATIS_CONFIG = "com/takensoft/taken_bi_manager/common/connection/db/mybatis/config/config.xml"; | |
29 | + | |
30 | + //동적 Mybatis 연계 - mybatis Mapper 문서 파일 경로 | |
31 | + private final static String DYNAMIC_MYBATIS_MAPPERS = "com/takensoft/taken_bi_manager/common/connection/db/mybatis/sql/*-SQL.xml"; | |
32 | + | |
33 | + private HikariDataSource dataSource = null; | |
34 | + | |
35 | + private SqlSessionFactoryBean sqlSession = null; | |
36 | + | |
37 | + private SqlSessionTemplate template = null; | |
38 | + | |
39 | + private DataSourceTransactionManager dataSourceTransaction = null; | |
40 | + | |
41 | + public HikariDataSource getDataSource() { | |
42 | + return dataSource; | |
43 | + } | |
44 | + | |
45 | + public void setDataSource(HikariDataSource dataSource) { | |
46 | + this.dataSource = dataSource; | |
47 | + } | |
48 | + | |
49 | + public SqlSessionFactoryBean getSqlSession() { | |
50 | + return sqlSession; | |
51 | + } | |
52 | + | |
53 | + public void setSqlSession(SqlSessionFactoryBean sqlSession) { | |
54 | + this.sqlSession = sqlSession; | |
55 | + } | |
56 | + | |
57 | + public SqlSessionTemplate getTemplate() { | |
58 | + return template; | |
59 | + } | |
60 | + | |
61 | + public void setTemplate(SqlSessionTemplate template) { | |
62 | + this.template = template; | |
63 | + } | |
64 | + | |
65 | + | |
66 | + /** | |
67 | + * @author 김성원 | |
68 | + * @since 2024.01.08 | |
69 | + * | |
70 | + * 동적 DB + Mybatis 객체 생성 -> Mapper에 접근하기위한 SQL 템플릿 반환 | |
71 | + */ | |
72 | + public SqlSessionTemplate mybatisSqlTemplateCreate (ConnectionDB db) { | |
73 | + dataSource = dataSourceCreate(db); | |
74 | + sqlSession = sqlSessionCreate(dataSource); | |
75 | + template = sqlSessionTemplateCreate(sqlSession); | |
76 | + dataSourceTransaction = getTransaction(dataSource); | |
77 | + | |
78 | + return template; | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * @author 김성원 | |
83 | + * @since 2024.01.08 | |
84 | + * | |
85 | + * 동적 DataSource 생성 | |
86 | + */ | |
87 | + public HikariDataSource dataSourceCreate (ConnectionDB db) { | |
88 | + dataSource = null; | |
89 | + try { | |
90 | + dataSource = new HikariDataSource(); | |
91 | + DatabaseType dataBaseType = db.getDatabaseType(); | |
92 | + dataSource.setDriverClassName(dataBaseType.getDriverClassName()); | |
93 | + dataSource.setJdbcUrl(dataBaseType.getUrl(db)); | |
94 | + | |
95 | + dataSource.setUsername(db.getUserId()); | |
96 | + dataSource.setPassword(db.getUserPassword()); | |
97 | + } catch (Exception e) { | |
98 | + e.printStackTrace(); | |
99 | + } | |
100 | + | |
101 | + return dataSource; | |
102 | + } | |
103 | + | |
104 | + /** | |
105 | + * @author 김성원 | |
106 | + * @since 2024.01.08 | |
107 | + * | |
108 | + * 동적으로 생성한 DataSource정보와 Mybatis 설정 정보 연계 생성 | |
109 | + */ | |
110 | + private SqlSessionFactoryBean sqlSessionCreate (HikariDataSource dataSource) { | |
111 | + try { | |
112 | + sqlSession = new SqlSessionFactoryBean(); | |
113 | + sqlSession.setDataSource(dataSource); | |
114 | + sqlSession.setConfigLocation(resourceResolver.getResource(DYNAMIC_MYBATIS_CONFIG)); | |
115 | + sqlSession.setMapperLocations(resourceResolver.getResources(DYNAMIC_MYBATIS_MAPPERS)); | |
116 | + } catch (Exception e) { | |
117 | + e.printStackTrace(); | |
118 | + } | |
119 | + | |
120 | + return sqlSession; | |
121 | + } | |
122 | + | |
123 | + /** | |
124 | + * @author 김성원 | |
125 | + * @since 2024.01.08 | |
126 | + * | |
127 | + * 동적 Mybatis Mapper에 접근하기위한 SQL 템플릿 생성 | |
128 | + */ | |
129 | + private SqlSessionTemplate sqlSessionTemplateCreate (SqlSessionFactoryBean sqlSession) { | |
130 | + try { | |
131 | + template = new SqlSessionTemplate(sqlSession.getObject()); | |
132 | + template.clearCache(); | |
133 | + } catch (Exception e) { | |
134 | + e.printStackTrace(); | |
135 | + } | |
136 | + | |
137 | + return template; | |
138 | + } | |
139 | + | |
140 | + | |
141 | + /** | |
142 | + * @author 김성원 | |
143 | + * @since 2024.01.08 | |
144 | + * | |
145 | + * 동적 Mybatis Mapper에 접근하기위한 SQL 템플릿 생성 | |
146 | + */ | |
147 | + private DataSourceTransactionManager getTransaction (HikariDataSource dataSource) { | |
148 | + | |
149 | + this.dataSourceTransaction = new DataSourceTransactionManager(dataSource); | |
150 | + | |
151 | + return dataSourceTransaction; | |
152 | + } | |
153 | + | |
154 | + | |
155 | + | |
156 | + /** | |
157 | + * @author 김성원 | |
158 | + * @since 2024.01.08 | |
159 | + * | |
160 | + * 커넥션 닫기 | |
161 | + */ | |
162 | + public void close() throws SQLException { | |
163 | + try { | |
164 | + if (dataSource != null) { | |
165 | + dataSource.evictConnection(dataSource.getConnection()); | |
166 | + if (dataSource.getConnection() != null) { | |
167 | + dataSource.getConnection().close(); | |
168 | + } | |
169 | + dataSource.close(); | |
170 | + } | |
171 | + }catch(Exception e) { | |
172 | + if (dataSource != null) { | |
173 | + dataSource.close(); | |
174 | + } | |
175 | + } | |
176 | + | |
177 | + } | |
178 | + | |
179 | + | |
180 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionUtil.java
... | ... | @@ -0,0 +1,745 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.util; | |
2 | + | |
3 | +import java.sql.Connection; | |
4 | +import java.sql.SQLException; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.LinkedHashMap; | |
7 | +import java.util.List; | |
8 | +import java.util.Map; | |
9 | + | |
10 | +import org.slf4j.Logger; | |
11 | +import org.slf4j.LoggerFactory; | |
12 | +import org.springframework.transaction.annotation.Transactional; | |
13 | + | |
14 | +import com.takensoft.taken_bi_manager.common.connection.db.dao.DatabaseDAO; | |
15 | +import com.takensoft.taken_bi_manager.common.connection.db.dao.MariadbDAO; | |
16 | +import com.takensoft.taken_bi_manager.common.connection.db.dao.PostgresqlDAO; | |
17 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
18 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
19 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
20 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
21 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
22 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
23 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
24 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
25 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
26 | + | |
27 | + | |
28 | + | |
29 | +/** | |
30 | + * @author 최정우 | |
31 | + * @since 2019.11.12 | |
32 | + * | |
33 | + * 데이터 수집 - DB 데이터 연계 관련 Util 입니다. | |
34 | + */ | |
35 | +@Transactional | |
36 | +public class DBConnectionUtil { | |
37 | + | |
38 | + private Logger logger = LoggerFactory.getLogger(DBConnectionUtil.class); | |
39 | + | |
40 | + /** | |
41 | + * @author 김성원 | |
42 | + * @since 2024.01.04 | |
43 | + * | |
44 | + * 데이터베이스 접속 모듈 DAO 객체 생성 메서드입니다. | |
45 | + */ | |
46 | + public DatabaseDAO createDatabaseDAO (ConnectionDB db) throws Exception { | |
47 | + | |
48 | + DatabaseDAO databaseDao= null; | |
49 | + | |
50 | + if (db.getDatabaseType() == DatabaseType.MYSQL) { | |
51 | + // databaseDao = new MysqlDAO(db); | |
52 | + } else if (db.getDatabaseType() == DatabaseType.MARIADB) { | |
53 | + databaseDao = new MariadbDAO(db); | |
54 | + } else if (db.getDatabaseType() == DatabaseType.ORACLE) { | |
55 | + // databaseDao = new OracleDAO(db); | |
56 | + } else if (db.getDatabaseType() == DatabaseType.MSSQL) { | |
57 | + // databaseDao = new MssqlDAO(db); | |
58 | + } else if (db.getDatabaseType() == DatabaseType.TIBERO) { | |
59 | + // databaseDao = new TeberoDAO(db); | |
60 | + }else if (db.getDatabaseType() == DatabaseType.POSTGRESQL) { | |
61 | + return new PostgresqlDAO(db); | |
62 | + } else { | |
63 | + throw new Exception(); | |
64 | + } | |
65 | + return databaseDao; | |
66 | + } | |
67 | + | |
68 | + /** | |
69 | + * @author 김성원 | |
70 | + * @since 2024.01.04 | |
71 | + * | |
72 | + * DB 접속 테스트 입니다. | |
73 | + */ | |
74 | + public CheckMessage dbConnectionCheck (ConnectionDB dbCollection) throws Exception { | |
75 | + if(StringUtil.isEmpty(dbCollection.getConectIp()) == true) { | |
76 | + return new CheckMessage(false, "접속 IP를 입력해주세요"); | |
77 | + } else if(StringUtil.isEmpty(dbCollection.getConectPort()) == true) { | |
78 | + return new CheckMessage(false, "접속 Port를 입력해주세요"); | |
79 | + } else if(CommonUtil.isInt(dbCollection.getConectPort()) == false) { | |
80 | + return new CheckMessage(false, "접속 Port는 숫자로만 입력해주세요"); | |
81 | + } else if(StringUtil.isEmpty(dbCollection.getDatabaseNm()) == true) { | |
82 | + return new CheckMessage(false, "DB명을 입력해주세요"); | |
83 | + } else if(StringUtil.isEmpty(dbCollection.getConectIp()) == true) { | |
84 | + return new CheckMessage(false, "접속 ID를 입력해주세요."); | |
85 | + } else if(StringUtil.isEmpty(dbCollection.getUserPassword()) == true) { | |
86 | + return new CheckMessage(false, "접속 PW를 입력해주세요."); | |
87 | + } else { | |
88 | + /*if (CommonUtil.pingCheck(dbCollection.getIp()) == false) { | |
89 | + return new CheckMessage(false, "접속 IP(" + dbCollection.getIp() + ")와 연결할 수 없습니다"); | |
90 | + }*/ | |
91 | + if (CommonUtil.linkCheck(dbCollection.getConectIp(), Integer.parseInt(dbCollection.getConectPort())) == false) { | |
92 | + return new CheckMessage(false, "접속 IP(" + dbCollection.getConectIp() + ")의 Port(" + dbCollection.getConectPort() + ")와 연결할 수 없습니다"); | |
93 | + } | |
94 | + Connection connection = null; | |
95 | + DBConnectionConfig dbUtil = new DBConnectionConfig(); | |
96 | + try { | |
97 | + dbUtil.dataSourceCreate(dbCollection); | |
98 | + connection = dbUtil.getDataSource().getConnection(); | |
99 | + return new CheckMessage(true, "[" + dbCollection.getDatabaseType().getValue() + "] " + dbCollection.getDatabaseNm() + " 접속 성공"); | |
100 | + } catch (SQLException e) { | |
101 | + System.out.println(e.toString()); | |
102 | + return new CheckMessage(false, "접속 에러 : " + e.toString()); | |
103 | + } catch (Exception e) { | |
104 | + System.out.println(e.toString()); | |
105 | + return new CheckMessage(false, "접속 에러 : " + e.toString()); | |
106 | + } finally { | |
107 | + if (connection != null) { | |
108 | + try { | |
109 | + connection.close(); | |
110 | + } catch (Exception e) { | |
111 | + System.out.println(e.toString()); | |
112 | + return new CheckMessage(false, "접속 에러 : " + e.toString()); | |
113 | + } | |
114 | + } if (dbUtil != null) { | |
115 | + dbUtil.close(); | |
116 | + } | |
117 | + } | |
118 | + } | |
119 | + } | |
120 | + | |
121 | + /** | |
122 | + * @author 김성원 | |
123 | + * @since 2024.01.04 | |
124 | + * | |
125 | + * DB 접속 - 테이블 목록 조회 메소드 입니다. | |
126 | + */ | |
127 | + public List<Dataset> getDBConnectionTableList (ConnectionDB dbCollection) throws Exception { | |
128 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
129 | + | |
130 | + if (message.isSuccess() == false) { | |
131 | + logger.info("getDbConnectionTableList DB연결실패 : " + message.getMessage()); | |
132 | + return new ArrayList<Dataset>(); | |
133 | + } | |
134 | + | |
135 | + List<Dataset> dbConnectionTableList = new ArrayList<Dataset>(); | |
136 | + | |
137 | + //DAO 인스턴스 생성 | |
138 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
139 | + | |
140 | + try { | |
141 | + //테이블 목록 조회 | |
142 | + dbConnectionTableList = databaseDAO.getDBConnectionTableList(dbCollection); | |
143 | + }finally { | |
144 | + //DB연결 종료 | |
145 | + databaseDAO.dbConnectionClose(); | |
146 | + } | |
147 | + | |
148 | + | |
149 | + | |
150 | + return dbConnectionTableList; | |
151 | + } | |
152 | + | |
153 | + /** | |
154 | + * @author 김성원 | |
155 | + * @since 2024.01.04 | |
156 | + * | |
157 | + * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
158 | + */ | |
159 | + public List<ColumnData> getDBConnectionTableColumnList(ConnectionDB dbCollection, Dataset dataset) throws Exception { | |
160 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
161 | + | |
162 | + if (message.isSuccess() == false) { | |
163 | + logger.info("getDBConnectionTableColumnList DB연결실패 : " + message.getMessage()); | |
164 | + return new ArrayList<ColumnData>(); | |
165 | + } | |
166 | + | |
167 | + List<ColumnData> tableColumnList = new ArrayList<ColumnData>(); | |
168 | + | |
169 | + //DAO 인스턴스 생성 | |
170 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
171 | + | |
172 | + try { | |
173 | + //테이블 컬럼 목록 조회 | |
174 | + tableColumnList = databaseDAO.getDBConnectionTableColumnList(dataset); | |
175 | + }finally { | |
176 | + //DB연결 종료 | |
177 | + databaseDAO.dbConnectionClose(); | |
178 | + } | |
179 | + | |
180 | + return tableColumnList; | |
181 | + } | |
182 | + | |
183 | + /** | |
184 | + * @author 최정우 | |
185 | + * @since 2020.01.28 | |
186 | + * | |
187 | + * 커넥션된 데이터베이스의 테이블의 데이터에 대한 데이터 테이블 조회 메서드입니다. | |
188 | + */ | |
189 | + public void setDataTableByDBConnectionTable (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
190 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
191 | + | |
192 | + if (message.isSuccess() == false) { | |
193 | + dataTable.setCheckMessage(message); | |
194 | + logger.info("setDataTableByDBConnectionTable DB연결실패 : " + message.getMessage()); | |
195 | + return; | |
196 | + } | |
197 | + | |
198 | + //DAO 인스턴스 생성 | |
199 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
200 | + | |
201 | + int tableDataTotalRows = 0; | |
202 | + | |
203 | + List<LinkedHashMap<String, Object>> tableDataMapList = new ArrayList<LinkedHashMap<String, Object>>(); | |
204 | + | |
205 | + try { | |
206 | + | |
207 | + //테이블 기본 Select 정보(데이터베이스명, 테이블명) 입력 | |
208 | + Dataset dataset = new Dataset(); | |
209 | + dataset.setDatabaseNm(dbCollection.getDatabaseNm()); | |
210 | + dataset.setTableNm(dataTable.getTableNm()); | |
211 | + | |
212 | + //테이블 컬럼 목록 조회 | |
213 | + dataTable.setColumnDatas(databaseDAO.getDBConnectionTableColumnList(dataset));//테이블 컬럼 정보 set | |
214 | + dataTable.setColumnDatas( DataTypeUtil.convertDataTypeDbtoJavaList(dataTable.getColumnDatas(),dbCollection.getDatabaseType())); | |
215 | + | |
216 | + //테이블 데이터 조회 | |
217 | + if (dbCollection.getDatabaseType() == DatabaseType.ORACLE) { | |
218 | + dataTable.setDatabaseNm(dbCollection.getUserId()); | |
219 | + } | |
220 | + | |
221 | + tableDataMapList = databaseDAO.getDBConnectionTableDataList(dataTable); | |
222 | + dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList));//테이블 데이터 set | |
223 | + | |
224 | + //테이블 데이터 총 개수 조회 | |
225 | + tableDataTotalRows = databaseDAO.getDBConnectionTableDataTotalRows(dataTable); | |
226 | + dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set | |
227 | + | |
228 | + //SELECT 쿼리 생성 | |
229 | + dataTable.setQuery(); | |
230 | + | |
231 | + }catch(Exception e) { | |
232 | + | |
233 | + logger.error(e.toString()); | |
234 | + | |
235 | + }finally { | |
236 | + //DB연결 종료 | |
237 | + databaseDAO.dbConnectionClose(); | |
238 | + } | |
239 | + | |
240 | + //성공 메세지 입력 | |
241 | + dataTable.getCheckMessage().setSuccess(true); | |
242 | + dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)"); | |
243 | + } | |
244 | + | |
245 | + /** | |
246 | + * @author 김성원 | |
247 | + * @since 2024.01.04 | |
248 | + * | |
249 | + * 커스텀 쿼리를 통한 dataTable setting (페이징사용 유무에 따라 페이징 처리 - {rowDatas, columnDatas, query(이미 존재함)}) | |
250 | + */ | |
251 | + public void setDataTableByDBConnectionCustomQuery (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
252 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
253 | + | |
254 | + if (message.isSuccess() == false) { | |
255 | + dataTable.setCheckMessage(message); | |
256 | + logger.info("setDataTableByDBConnectionCustomQuery DB연결실패 : " + message.getMessage()); | |
257 | + return; | |
258 | + } | |
259 | + | |
260 | + int tableDataTotalRows = 0; | |
261 | + | |
262 | + List<LinkedHashMap<String, Object>> tableDataMapList = new ArrayList<LinkedHashMap<String, Object>>(); | |
263 | + | |
264 | + | |
265 | + //DAO 인스턴스 생성 | |
266 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
267 | + | |
268 | + try { | |
269 | + //테이블 데이터 조회 | |
270 | + tableDataMapList = databaseDAO.getDBConnectionCustomQueryDataList(dataTable); | |
271 | + | |
272 | + //DataTable에 조회된 데이터에서 첫번째 행 값의 컬럼 분리 후, columnDatas에 세팅 | |
273 | + //DataTable에 rowData 세팅 | |
274 | + if (tableDataMapList != null && tableDataMapList.size() > 0) { | |
275 | + | |
276 | + //테이블 데이터 set | |
277 | + dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList)); | |
278 | + | |
279 | + //컬럼명 set | |
280 | + List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
281 | + LinkedHashMap<String, Object> map = tableDataMapList.get(0); | |
282 | + | |
283 | + for(String key : map.keySet()){ | |
284 | + ColumnData column = new ColumnData(); | |
285 | + column.setColumnNm(key); | |
286 | + column.setDisplyColumnNm(key); | |
287 | + column.setOrginlColumnNm(key); | |
288 | + // 데이터 타입 정의 기능 | |
289 | + column.dataTyDefine(map.get(key)); | |
290 | + columnDatas.add(column); | |
291 | + } | |
292 | + | |
293 | + dataTable.setColumnDatas(columnDatas); | |
294 | + } | |
295 | + | |
296 | + //테이블 데이터 총 개수 조회 | |
297 | + tableDataTotalRows = databaseDAO.getDBConnectionCustomQueryDataTotalRows(dataTable); | |
298 | + dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set | |
299 | + }catch(Exception e) { | |
300 | + logger.error(e.toString()); | |
301 | + }finally { | |
302 | + //DB연결 종료 | |
303 | + databaseDAO.dbConnectionClose(); | |
304 | + } | |
305 | + //DB연결 종료 | |
306 | + databaseDAO.dbConnectionClose(); | |
307 | + | |
308 | + //성공 메세지 입력 | |
309 | + dataTable.getCheckMessage().setSuccess(true); | |
310 | + dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)"); | |
311 | + } | |
312 | + | |
313 | + | |
314 | + /** | |
315 | + * @author 김성원 | |
316 | + * @since 2024.01.04 | |
317 | + * | |
318 | + * 조회내용이 없는 실행형 커스텀 쿼리(update, delete 등) | |
319 | + */ | |
320 | + public int executeCustomQuery(ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
321 | + | |
322 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
323 | + | |
324 | + int result = 0; | |
325 | + try { | |
326 | + result = databaseDAO.executeCustomQuery(dataTable); | |
327 | + }catch(Exception e) { | |
328 | + | |
329 | + }finally{ | |
330 | + databaseDAO.dbConnectionClose(); | |
331 | + } | |
332 | + | |
333 | + return result; | |
334 | + } | |
335 | + | |
336 | + | |
337 | + /** | |
338 | + * @author 김성원 | |
339 | + * @since 2024.01.04 | |
340 | + * | |
341 | + * 커스텀 쿼리 지정된 PK로 테이블 생성이 가능한지 확인 | |
342 | + */ | |
343 | + public void setCustomQueryPrimaryCreatePossibleCheck (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
344 | + | |
345 | + if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) { | |
346 | + dataTable.getCheckMessage().setSuccess(false); | |
347 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 테이블을 생성할 컬럼이 없습니다."); | |
348 | + return; | |
349 | + } | |
350 | + | |
351 | + String primaryColumns = ""; | |
352 | + List<ColumnData> primaryColumnDatas = new ArrayList<ColumnData>(); | |
353 | + | |
354 | + for (int i = 0; i < dataTable.getColumnDatas().size(); i++) { | |
355 | + if (dataTable.getColumnDatas().get(i).isPkAt() == true) { | |
356 | + primaryColumns += ("[" + dataTable.getColumnDatas().get(i).getColumnNm() + "]"); | |
357 | + primaryColumnDatas.add(dataTable.getColumnDatas().get(i)); | |
358 | + } | |
359 | + } | |
360 | + | |
361 | + if (primaryColumnDatas.size() == 0) { | |
362 | + dataTable.getCheckMessage().setSuccess(true); | |
363 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - PK로 지정한 컬럼이 없습니다.(검사통과)"); | |
364 | + return; | |
365 | + } | |
366 | + | |
367 | + //DB Connecting | |
368 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
369 | + if (message.isSuccess() == false) { | |
370 | + dataTable.setCheckMessage(message); | |
371 | + logger.info("setDataTableByDBConnectionCustomQuery DB연결실패 : " + message.getMessage()); | |
372 | + return; | |
373 | + } | |
374 | + | |
375 | + //DAO 인스턴스 생성 | |
376 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
377 | + | |
378 | + DataTable param = new DataTable(); | |
379 | + param.setColumnDatas(primaryColumnDatas); | |
380 | + param.setQuery(dataTable.getQuery()); | |
381 | + | |
382 | + //커스텀 쿼리 지정된 PK로 테이블 생성이 가능한지 확인 | |
383 | + int totalOverlapCount = databaseDAO.getCustomQueryPrimaryOverlapCount(param); | |
384 | + | |
385 | + //DB연결 종료 | |
386 | + databaseDAO.dbConnectionClose(); | |
387 | + | |
388 | + //결과 메세지 입력 | |
389 | + if (totalOverlapCount == 0) { | |
390 | + dataTable.getCheckMessage().setSuccess(true); | |
391 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 지정한 컬럼(" + primaryColumns + ")으로 PrimaryKey 생성이 가능합니다."); | |
392 | + } else { | |
393 | + dataTable.getCheckMessage().setSuccess(false); | |
394 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 지정한 컬럼(" + primaryColumns + ")으로 PrimaryKey 생성이 불가능합니다.(중복되는 데이터 수 :" + totalOverlapCount + ")"); | |
395 | + } | |
396 | + } | |
397 | + | |
398 | + /** | |
399 | + * @author 김성원 | |
400 | + * @since 2024.01.04 | |
401 | + * | |
402 | + * 커넥션된 데이터베이스의 테이블의 데이터에 대한 데이터 테이블 조회 메서드입니다. | |
403 | + */ | |
404 | + public void setDataTableByDBCollectionQuery (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
405 | + if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) { | |
406 | + dataTable.getCheckMessage().setMessage("조회할 컬럼정보가 없습니다."); | |
407 | + dataTable.getCheckMessage().setSuccess(false); | |
408 | + logger.info("setDataTableByDBConnectionTable : " + dataTable.getCheckMessage().getMessage()); | |
409 | + return; | |
410 | + } | |
411 | + | |
412 | + //DB연결 확인 | |
413 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
414 | + if (message.isSuccess() == false) { | |
415 | + dataTable.setCheckMessage(message); | |
416 | + logger.info("setDataTableByDBConnectionTable DB연결실패 : " + message.getMessage()); | |
417 | + return; | |
418 | + } | |
419 | + | |
420 | + int tableDataTotalRows = 0; | |
421 | + | |
422 | + List<LinkedHashMap<String, Object>> tableDataMapList = new ArrayList<LinkedHashMap<String, Object>>(); | |
423 | + | |
424 | + //DAO 인스턴스 생성 | |
425 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
426 | + | |
427 | + try { | |
428 | + tableDataMapList = databaseDAO.getDBCollectionQueryDataList(dataTable); | |
429 | + dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList));//테이블 데이터 set | |
430 | + | |
431 | + //테이블 데이터 총 개수 조회 | |
432 | + tableDataTotalRows = databaseDAO.getDBCollectionQueryDataTotalRows(dataTable); | |
433 | + dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set | |
434 | + }catch(Exception e) { | |
435 | + | |
436 | + }finally { | |
437 | + //DB연결 종료 | |
438 | + databaseDAO.dbConnectionClose(); | |
439 | + } | |
440 | + | |
441 | + | |
442 | + //성공 메세지 입력 | |
443 | + dataTable.getCheckMessage().setSuccess(true); | |
444 | + dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)"); | |
445 | + } | |
446 | + | |
447 | + /** | |
448 | + * @author 김성원 | |
449 | + * @since 2024.01.04 | |
450 | + * | |
451 | + * 데이터 셋 목록 Convert List<TableBasicInfo> to List<ColumnData> | |
452 | + */ | |
453 | + /* | |
454 | + public List<ColumnData> tableColumnToColumnData (List<TableBasicInfo> tableBasicList) throws Exception { | |
455 | + List<ColumnData> columnDataList = new ArrayList<ColumnData>(); | |
456 | + for (int i = 0; i < tableBasicList.size(); i++) { | |
457 | + TableBasicInfo tableBasicInfo = tableBasicList.get(i); | |
458 | + ColumnData columnData = new ColumnData(); | |
459 | + columnData.setTableName(tableBasicInfo.getTableName()); | |
460 | + columnData.setColumnNm(tableBasicInfo.getColumnName()); | |
461 | + columnData.setOrginlColumnNm(tableBasicInfo.getColumnName()); | |
462 | + columnData.setDisplyColumnNm(tableBasicInfo.getColumnName()); | |
463 | + columnData.setDbDataType(tableBasicInfo.getDataType()); | |
464 | + columnData.setDataSize(tableBasicInfo.getSize()); | |
465 | + columnData.setPkAt(tableBasicInfo.isPrimary()); | |
466 | + | |
467 | + columnDataList.add(columnData); | |
468 | + } | |
469 | + return columnDataList; | |
470 | + } | |
471 | + */ | |
472 | + | |
473 | + /** | |
474 | + * @author 김성원 | |
475 | + * @since 2022.01.17 | |
476 | + * | |
477 | + * 커넥션된 데이터베이스의 실제 테이블 생성 | |
478 | + */ | |
479 | + public int datasetTableCreate(ConnectionDB dbCollection, DataTable datatable) throws Exception { | |
480 | + | |
481 | + int result = 0; | |
482 | + | |
483 | + //DAO 인스턴스 생성 | |
484 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
485 | + | |
486 | + try { | |
487 | + //테이블 컬럼 목록 조회 | |
488 | + result = databaseDAO.datasetTableCreate(datatable); | |
489 | + }finally { | |
490 | + //DB연결 종료 | |
491 | + databaseDAO.dbConnectionClose(); | |
492 | + } | |
493 | + | |
494 | + return result; | |
495 | + } | |
496 | + | |
497 | + /** | |
498 | + * @author 김성원 | |
499 | + * @since 2022.01.17 | |
500 | + * | |
501 | + * 커넥션된 데이터베이스의 실제 테이블 생성 | |
502 | + */ | |
503 | + public int datasetDefaultTableCreate(ConnectionDB dbCollection, DataTable datatable) throws Exception { | |
504 | + | |
505 | + int result = 0; | |
506 | + | |
507 | + //DAO 인스턴스 생성 | |
508 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
509 | + | |
510 | + try { | |
511 | + //테이블 컬럼 목록 조회 | |
512 | + result = databaseDAO.datasetDefaultTableCreate(datatable); | |
513 | + }catch(Exception e) { | |
514 | + | |
515 | + e.printStackTrace(); | |
516 | + | |
517 | + }finally { | |
518 | + //DB연결 종료 | |
519 | + databaseDAO.dbConnectionClose(); | |
520 | + } | |
521 | + | |
522 | + return result; | |
523 | + } | |
524 | + | |
525 | + /** | |
526 | + * @author 김성원 | |
527 | + * @since 2022.01.17 | |
528 | + * | |
529 | + * 커넥션된 데이터베이스의 실제 테이블 업데이트 | |
530 | + */ | |
531 | + public void datasetDataUpdate(ConnectionDB dbCollection, DataTable datatable) throws Exception { | |
532 | + | |
533 | + //DAO 인스턴스 생성 | |
534 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
535 | + //datatable.getColumnDatas().get(0).isAutoIncrement(); | |
536 | + try { | |
537 | + //테이블 컬럼 목록 조회 | |
538 | + databaseDAO.datasetDataUpdate(datatable); | |
539 | + }catch(Exception e) { | |
540 | + e.printStackTrace(); | |
541 | + } | |
542 | + finally { | |
543 | + //DB연결 종료 | |
544 | + databaseDAO.dbConnectionClose(); | |
545 | + } | |
546 | + | |
547 | + } | |
548 | + | |
549 | + /** | |
550 | + * @author 김성원 | |
551 | + * @since 2022.01.17 | |
552 | + * | |
553 | + * 커넥션된 데이터베이스의 실제 테이블 이름 중복검사 | |
554 | + */ | |
555 | + public int duplicateCheckTableName(ConnectionDB dbCollection, Map info) throws Exception { | |
556 | + | |
557 | + | |
558 | + int result = 0; | |
559 | + //DAO 인스턴스 생성 | |
560 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
561 | + try { | |
562 | + //테이블 컬럼 목록 조회 | |
563 | + result = databaseDAO.duplicateCheckTableName(info); | |
564 | + }finally { | |
565 | + //DB연결 종료 | |
566 | + databaseDAO.dbConnectionClose(); | |
567 | + } | |
568 | + | |
569 | + return result; | |
570 | + } | |
571 | + | |
572 | + /** | |
573 | + * @author 김성원 | |
574 | + * @since 2022.01.17 | |
575 | + * | |
576 | + * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징) | |
577 | + */ | |
578 | + public List<LinkedHashMap<String, Object>> getRowData (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
579 | + | |
580 | + List<LinkedHashMap<String, Object>> rowMapData = new ArrayList<LinkedHashMap<String, Object>>(); | |
581 | + | |
582 | + //DAO 인스턴스 생성 | |
583 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
584 | + try { | |
585 | + //테이블 컬럼 목록 조회 | |
586 | + rowMapData = databaseDAO.getRowData(dataTable); | |
587 | + }finally { | |
588 | + //DB연결 종료 | |
589 | + databaseDAO.dbConnectionClose(); | |
590 | + } | |
591 | + | |
592 | + return rowMapData; | |
593 | + } | |
594 | + | |
595 | + /** | |
596 | + * @author 김성원 | |
597 | + * @since 2022.01.17 | |
598 | + * | |
599 | + * 데이터 셋의 컬럼 정보 목록 조회 메소드 입니다.(페이징X) | |
600 | + */ | |
601 | + public List<LinkedHashMap<String, Object>> getRowDataAll (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
602 | + | |
603 | + List<LinkedHashMap<String, Object>> rowMapData = new ArrayList<LinkedHashMap<String, Object>>(); | |
604 | + //DAO 인스턴스 생성 | |
605 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
606 | + | |
607 | + try { | |
608 | + //테이블 컬럼 목록 조회 | |
609 | + rowMapData = databaseDAO.getRowDataAll(dataTable); | |
610 | + }finally { | |
611 | + //DB연결 종료 | |
612 | + databaseDAO.dbConnectionClose(); | |
613 | + } | |
614 | + | |
615 | + return rowMapData; | |
616 | + } | |
617 | + | |
618 | + /** | |
619 | + * @author 김성원 | |
620 | + * @since 2022.01.17 | |
621 | + * | |
622 | + * 데이터 셋의 컬럼 정보 목록 총 갯수 조회 메소드 입니다. | |
623 | + */ | |
624 | + public int getRowDataTotalRows (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
625 | + | |
626 | + int result = 0; | |
627 | + | |
628 | + //DAO 인스턴스 생성 | |
629 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
630 | + | |
631 | + try { | |
632 | + //테이블 컬럼 목록 조회 | |
633 | + result = databaseDAO.getRowDataTotalRows(dataTable); | |
634 | + }finally { | |
635 | + //DB연결 종료 | |
636 | + databaseDAO.dbConnectionClose(); | |
637 | + } | |
638 | + | |
639 | + return result; | |
640 | + } | |
641 | + | |
642 | + /** | |
643 | + * @author 김성원 | |
644 | + * @since 2022.01.17 | |
645 | + * | |
646 | + * 데이터 셋의 비우기 (데이터 셋 내용삭제) | |
647 | + */ | |
648 | + public int emptyDataset (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
649 | + | |
650 | + int result = 0; | |
651 | + //DAO 인스턴스 생성 | |
652 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
653 | + | |
654 | + try { | |
655 | + //테이블 컬럼 목록 조회 | |
656 | + result = databaseDAO.emptyDataset(dataTable); | |
657 | + }finally { | |
658 | + //DB연결 종료 | |
659 | + databaseDAO.dbConnectionClose(); | |
660 | + } | |
661 | + | |
662 | + return result; | |
663 | + } | |
664 | + | |
665 | + /** | |
666 | + * @author 김성원 | |
667 | + * @since 2022.01.17 | |
668 | + * | |
669 | + * 실제 생성된 컬럼 변경 | |
670 | + */ | |
671 | + public int tableColumnChange (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception { | |
672 | + | |
673 | + int result = 0; | |
674 | + | |
675 | + //테이블 컬럼 목록 조회 | |
676 | + result = databaseDAO.tableColumnChange(tableBasicInfo); | |
677 | + | |
678 | + return result; | |
679 | + } | |
680 | + | |
681 | + /** | |
682 | + * @author 김성원 | |
683 | + * @since 2022.01.17 | |
684 | + * | |
685 | + * 실제 생성된 테이블 키변경 | |
686 | + */ | |
687 | + public int changePromaryKey (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception { | |
688 | + | |
689 | + int result = 0; | |
690 | + | |
691 | + //테이블 컬럼 목록 조회 | |
692 | + result = databaseDAO.changePrimaryKey(tableBasicInfo); | |
693 | + | |
694 | + return result; | |
695 | + } | |
696 | + | |
697 | + /** | |
698 | + * @author 김성원 | |
699 | + * @since 2022.01.17 | |
700 | + * | |
701 | + * 데이터 셋의 ROW 삭제 | |
702 | + */ | |
703 | + public void datasetDataDelete (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
704 | + | |
705 | + //DAO 인스턴스 생성 | |
706 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
707 | + | |
708 | + //테이블 컬럼 목록 조회 | |
709 | + databaseDAO.datasetDataDelete(dataTable); | |
710 | + | |
711 | + //DB연결 종료 | |
712 | + databaseDAO.dbConnectionClose(); | |
713 | + } | |
714 | + | |
715 | + /** | |
716 | + * @author 김성원 | |
717 | + * @since 2022.01.17 | |
718 | + * | |
719 | + * AI PK 생성 | |
720 | + */ | |
721 | + public int createAutoIncrement (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception { | |
722 | + | |
723 | + int result = 0; | |
724 | + | |
725 | + //테이블 컬럼 목록 조회 | |
726 | + result = databaseDAO.createAutoIncrement(tableBasicInfo); | |
727 | + | |
728 | + return result; | |
729 | + } | |
730 | + | |
731 | + /** | |
732 | + * @author 김성원 | |
733 | + * @since 2022.01.17 | |
734 | + * | |
735 | + * 테이블 메타정보 변경 (comments) | |
736 | + */ | |
737 | + public void updateTableMetaInfo(ConnectionDB dbCollection,DataTable dataTable) throws Exception { | |
738 | + | |
739 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
740 | + | |
741 | + databaseDAO.updateTableMetaInfo(dataTable); | |
742 | + | |
743 | + } | |
744 | + | |
745 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DataTypeUtil.java
... | ... | @@ -0,0 +1,159 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.util; | |
2 | + | |
3 | +import java.util.Arrays; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType; | |
7 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
8 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
9 | + | |
10 | +/** | |
11 | + * @author 김성원 | |
12 | + * @since 2024.01.02 | |
13 | + * | |
14 | + * 데이터 타입별로 DB -> JAVA , JAVA -> DB 변경을 위한 인터페이스 입니다. | |
15 | + */ | |
16 | +public class DataTypeUtil { | |
17 | + | |
18 | + | |
19 | + /** | |
20 | + * @author 김성원 | |
21 | + * @since 2024.01.09 | |
22 | + * | |
23 | + * 데이터베이스 자료타입을 자바형태로 변환 | |
24 | + */ | |
25 | + public static DataType convertDataTypeDbtoJava (ColumnData column, DatabaseType databaseType ) { | |
26 | + | |
27 | + DataType dataType = null; | |
28 | + | |
29 | + if(databaseType.equals(DatabaseType.MARIADB) || databaseType.equals(DatabaseType.MYSQL)){ | |
30 | + dataType = mariadbDataConvertDBtoJava(column); | |
31 | + }else { | |
32 | + dataType = postgresqlDbDataConvertDBtoJava(column); | |
33 | + } | |
34 | + | |
35 | + return dataType; | |
36 | + } | |
37 | + | |
38 | + /** | |
39 | + * @author 김성원 | |
40 | + * @since 2024.01.09 | |
41 | + * | |
42 | + * 자바 자료형태를 DB 타입으로 변환 | |
43 | + */ | |
44 | + public static DataType convertDataTypeJavatoDB (ColumnData column, DatabaseType databaseType ) { | |
45 | + | |
46 | + | |
47 | + return null; | |
48 | + } | |
49 | + | |
50 | + public static List<ColumnData> convertDataTypeDbtoJavaList(List<ColumnData> ColumnDatas , DatabaseType databaseType){ | |
51 | + | |
52 | + for(ColumnData item : ColumnDatas) { | |
53 | + item.setDataTy(convertDataTypeDbtoJava(item,databaseType)); | |
54 | + } | |
55 | + | |
56 | + | |
57 | + return ColumnDatas; | |
58 | + } | |
59 | + | |
60 | + | |
61 | + /** | |
62 | + * @author 김성원 | |
63 | + * @since 2024.01.09 | |
64 | + * | |
65 | + * 마리아 및 myslq 데이터베이스 자료타입을 자바형태로 변환 | |
66 | + */ | |
67 | + private static DataType mariadbDataConvertDBtoJava(ColumnData column) { | |
68 | + | |
69 | + DataType dataType = null; | |
70 | + | |
71 | + // 스트링 타입 변환 | |
72 | + if(Arrays.asList("TEXT", "VARCHAR", "TINYTEXT", "LONGTEXT","ENUM","SET","CHAR","LONGBLOB","BLOB","TINYBLOB","VARBINARY","BINARY","CHAR").contains(column.getDbDataType().toUpperCase().trim())) { | |
73 | + dataType = DataType.STRING; | |
74 | + } | |
75 | + // boolean 타이 변환 | |
76 | + else if(Arrays.asList("BIT").contains(column.getDbDataType().toLowerCase().trim())) { | |
77 | + dataType = DataType.INT; | |
78 | + } | |
79 | + // Integer 타이 변환 | |
80 | + else if(Arrays.asList("TINYINT", "SMALLINT").contains(column.getDbDataType().toUpperCase().trim())) { | |
81 | + dataType = DataType.INT; | |
82 | + } | |
83 | + // Long 타이 변환 | |
84 | + else if(Arrays.asList("MEDIUMINT", "INT","BIGINT").contains(column.getDbDataType().toUpperCase().trim())) { | |
85 | + dataType = DataType.INT; | |
86 | + } | |
87 | + // float 타이 변환 | |
88 | + else if(Arrays.asList("FLOAT").contains(column.getDbDataType().toUpperCase().trim())) { | |
89 | + dataType = DataType.FLOAT; | |
90 | + } | |
91 | + // double 타이 변환 | |
92 | + else if(Arrays.asList("DOUBLE").contains(column.getDbDataType().toUpperCase().trim())) { | |
93 | + dataType = DataType.DOUBLE; | |
94 | + } | |
95 | + // DECIMAL 타이 변환 | |
96 | + else if(Arrays.asList("DECIMAL").contains(column.getDbDataType().toUpperCase().trim())) { | |
97 | + dataType = DataType.DECIMAL; | |
98 | + } | |
99 | + // DATE 타이 변환 | |
100 | + else if(Arrays.asList("DATE").contains(column.getDbDataType().toUpperCase().trim())) { | |
101 | + dataType = DataType.DATE; | |
102 | + } | |
103 | + // TIMESTAMP 타이 변환 | |
104 | + else if(Arrays.asList("DATETIME,TIMESTAMP,TIME").contains(column.getDbDataType().toUpperCase().trim())) { | |
105 | + dataType = DataType.TIMESTAMP; | |
106 | + } | |
107 | + | |
108 | + return dataType; | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * @author 김성원 | |
113 | + * @since 2024.01.09 | |
114 | + * | |
115 | + * 마리아 및 myslq 데이터베이스 자료타입을 자바형태로 변환 | |
116 | + */ | |
117 | + private static DataType postgresqlDbDataConvertDBtoJava(ColumnData column) { | |
118 | + | |
119 | + DataType dataType = null; | |
120 | + | |
121 | + // 스트링 타입 변환 | |
122 | + if(Arrays.asList("character varying", "character","text").contains(column.getDbDataType().toLowerCase().trim())) { | |
123 | + dataType = DataType.STRING; | |
124 | + } | |
125 | + // boolean 타이 변환 | |
126 | + else if(Arrays.asList("bit").contains(column.getDbDataType().toLowerCase().trim())) { | |
127 | + dataType = DataType.BOOL; | |
128 | + } | |
129 | + // Integer 타이 변환 | |
130 | + else if(Arrays.asList("integer","smallint","serial").contains(column.getDbDataType().toLowerCase().trim())) { | |
131 | + dataType = DataType.INT; | |
132 | + } | |
133 | + // Long 타이 변환 | |
134 | + else if(Arrays.asList("bigint", "bigserial").contains(column.getDbDataType().toLowerCase().trim())) { | |
135 | + dataType = DataType.LONG; | |
136 | + } | |
137 | + // float 타이 변환 | |
138 | + else if(Arrays.asList("real").contains(column.getDbDataType().toLowerCase().trim())) { | |
139 | + dataType = DataType.FLOAT; | |
140 | + } | |
141 | + // double 타이 변환 | |
142 | + else if(Arrays.asList("double precision","numeric").contains(column.getDbDataType().toLowerCase().trim())) { | |
143 | + dataType = DataType.DOUBLE; | |
144 | + } | |
145 | + // DATE 타이 변환 | |
146 | + else if(Arrays.asList("date","time without time zone").contains(column.getDbDataType().toLowerCase().trim())) { | |
147 | + dataType = DataType.DATE; | |
148 | + } | |
149 | + // TIMESTAMP 타이 변환 | |
150 | + else if(Arrays.asList("time","timestamp","timestamp with time zone","timestamp without time zone", "time with time zone").contains(column.getDbDataType().toLowerCase().trim())) { | |
151 | + dataType = DataType.TIMESTAMP; | |
152 | + }else { | |
153 | + dataType = DataType.STRING; | |
154 | + } | |
155 | + | |
156 | + return dataType; | |
157 | + } | |
158 | + | |
159 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/ConnectionDB.java
... | ... | @@ -0,0 +1,70 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
6 | + | |
7 | +import lombok.Getter; | |
8 | +import lombok.Setter; | |
9 | + | |
10 | +@Getter | |
11 | +@Setter | |
12 | +public class ConnectionDB { | |
13 | + | |
14 | + // 커넥션 설명 | |
15 | + private String conectNm; | |
16 | + | |
17 | + // 커넥션 이름 | |
18 | + private String conect_dc; | |
19 | + | |
20 | + // 데이터베이스명(데이터 베이스 > 스키마) | |
21 | + private String databaseNm; | |
22 | + | |
23 | + // 스키마명 | |
24 | + private String schemaNm; | |
25 | + | |
26 | + // 데이터 베이스 타입 | |
27 | + private DatabaseType databaseType; | |
28 | + | |
29 | + // IP or URL | |
30 | + private String conectIp; | |
31 | + | |
32 | + // 접속 포트 | |
33 | + private String conectPort; | |
34 | + | |
35 | + // 접속 아이디 | |
36 | + private String userId; | |
37 | + | |
38 | + // 접속 비밀번호 | |
39 | + private String userPassword; | |
40 | + | |
41 | + // 접속 옵션 | |
42 | + private String option; | |
43 | + | |
44 | + // 사용여부 | |
45 | + private String useAt; | |
46 | + | |
47 | + | |
48 | + | |
49 | + /** | |
50 | + * 오라클 | |
51 | + * SERVICE: true | |
52 | + * SID: false | |
53 | + * 인지 아닌지 | |
54 | + */ | |
55 | + private boolean isGroupDatabase; | |
56 | + | |
57 | + // 생성일 | |
58 | + private Timestamp creatDt; | |
59 | + | |
60 | + // 생성자ID | |
61 | + private String creatId; | |
62 | + | |
63 | + // 수정일 | |
64 | + private Timestamp updtDt; | |
65 | + | |
66 | + // 수정자 ID | |
67 | + private String updtId; | |
68 | + | |
69 | + | |
70 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/DataType.java
... | ... | @@ -0,0 +1,269 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | +import java.math.BigDecimal; | |
4 | +import java.sql.Timestamp; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.Date; | |
7 | +import java.util.LinkedHashMap; | |
8 | +import java.util.List; | |
9 | +import java.util.Map; | |
10 | +import java.util.regex.Pattern; | |
11 | + | |
12 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
13 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
14 | + | |
15 | +/** | |
16 | + * @author 김성원 | |
17 | + * @since 2024.01.02 | |
18 | + * | |
19 | + * 데이터 타입을 정의한 상수 Class 입니다. | |
20 | + * 상수명(java데이터타입, 초기값, mysql데이터타입, display데이터타입 | |
21 | + */ | |
22 | + | |
23 | +public enum DataType { | |
24 | + NULL(null, null) | |
25 | + , BYTE(Byte.class, 0) | |
26 | + , BOOL(Boolean.class, false) | |
27 | + , CHAR(Character.class, '\u0000') | |
28 | + , STRING(String.class, "") | |
29 | + , SHORT(Short.class, 0) | |
30 | + , INT(Integer.class, 0) | |
31 | + , DECIMAL(BigDecimal.class,0) | |
32 | + , LONG(Long.class, 0) | |
33 | + , FLOAT(Float.class, 0.0) | |
34 | + , DOUBLE(Double.class, 0.0) | |
35 | + , DATE(Date.class, "") | |
36 | + , DATETIME(Date.class, "") | |
37 | + , TIMESTAMP(Timestamp.class, "") | |
38 | + , ENTER(Character.class,'\n'); | |
39 | + | |
40 | + /** | |
41 | + * enum(열거형데이터)의 생성자 | |
42 | + * 1. 상수에 나열된 parameter와 형태가 똑같이 만들어줘야함. | |
43 | + * 2. 접근제한자는 private로만 다른 접근제한자는 허용하지 않음 | |
44 | + */ | |
45 | + private DataType (Class<?> javaType, Object iniValue) { | |
46 | + this.javaType = javaType; | |
47 | + this.initValue = iniValue; | |
48 | + } | |
49 | + | |
50 | + /** | |
51 | + * java데이터타입 | |
52 | + */ | |
53 | + final private Class<?> javaType; | |
54 | + | |
55 | + /** | |
56 | + * 초기값 | |
57 | + */ | |
58 | + final private Object initValue; | |
59 | + | |
60 | + public Class<?> getJavaType() { | |
61 | + return javaType; | |
62 | + } | |
63 | + public Object getInitValue() { | |
64 | + return initValue; | |
65 | + } | |
66 | + | |
67 | + | |
68 | + /** | |
69 | + * 데이터 타입 검사, DataType 조회 | |
70 | + */ | |
71 | + public static Map<DataType, String> getDataTypeList () { | |
72 | + Map<DataType, String> info = new LinkedHashMap<DataType, String>(); | |
73 | + info.put(STRING, "문자열"); | |
74 | + info.put(LONG, "정수"); | |
75 | + info.put(DOUBLE, "실수"); | |
76 | + info.put(DATE, "날짜"); | |
77 | + info.put(DATETIME,"날짜,시간"); | |
78 | + return info; | |
79 | + } | |
80 | + | |
81 | + | |
82 | + /** | |
83 | + * 데이터 타입 검사, DataType 조회 | |
84 | + */ | |
85 | + public static List<DataType> getDataTypeArray () { | |
86 | + List<DataType> info = new ArrayList<DataType>(); | |
87 | + info.add(STRING); | |
88 | + info.add(LONG); | |
89 | + info.add(DOUBLE); | |
90 | + info.add(DATE); | |
91 | + info.add(DATETIME); | |
92 | + info.add(BOOL); | |
93 | + return info; | |
94 | + } | |
95 | + | |
96 | + /** | |
97 | + * 데이터 타입 검사, DataType 조회 | |
98 | + */ | |
99 | + public static DataType getDataType (String text) { | |
100 | + /* | |
101 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
102 | + * | |
103 | + * | |
104 | + * 전화번호 정규식*/ | |
105 | + String regExp = "^\\d{2,3}-\\d{3,4}-\\d{4}$"; | |
106 | + 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])"; | |
107 | + String regDate = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"; | |
108 | + | |
109 | + if(StringUtil.isEmpty(text)) { | |
110 | + return NULL; | |
111 | + } else if(CommonUtil.isLong(text)) { | |
112 | + /* | |
113 | + * 숫자로 변환 가능 하지만 앞에 '0'이 붙어 있으면 문자열로 봄 | |
114 | + * ex) 0102 -> String, 1102 -> Long | |
115 | + */ | |
116 | + if (text.length() > 1 && text.indexOf("0") == 0) { | |
117 | + return STRING; | |
118 | + } else { | |
119 | + return LONG; | |
120 | + } | |
121 | + }else if(CommonUtil.isDouble(text)) { | |
122 | + | |
123 | + return DOUBLE; | |
124 | + | |
125 | + } else if (CommonUtil.isDate(text)) { | |
126 | + /* | |
127 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
128 | + * | |
129 | + * | |
130 | + * 전화번호 정규식*/ | |
131 | + boolean expResult = Pattern.matches(regExp, text); | |
132 | + boolean dateTimeResult = Pattern.matches(regDateTime, text); | |
133 | + boolean dateResult = Pattern.matches(regDate, text); | |
134 | + | |
135 | + if(expResult) { | |
136 | + return STRING; | |
137 | + }else if(dateResult) { | |
138 | + return DATE; | |
139 | + }else { | |
140 | + return DATETIME; | |
141 | + } | |
142 | + | |
143 | + } else { | |
144 | + return STRING; | |
145 | + } | |
146 | + } | |
147 | + | |
148 | + /** | |
149 | + * 데이터 타입 검사, dbDataType 조회 | |
150 | + */ | |
151 | + public static String convertDbDataType (DataType datatype, Integer size) { | |
152 | + final int MAX_VARCHAR_SIZE = 765; | |
153 | + | |
154 | + if (datatype == STRING) { | |
155 | + if (size == null || size <= MAX_VARCHAR_SIZE) { | |
156 | + return "varchar"; | |
157 | + } else { | |
158 | + return "text"; | |
159 | + } | |
160 | + } else if (datatype == DATE) { | |
161 | + return "date"; | |
162 | + } else if (datatype == DATETIME){ | |
163 | + return "datetime"; | |
164 | + } else if (datatype == LONG) { | |
165 | + return "bigint"; | |
166 | + } else if (datatype == DOUBLE) { | |
167 | + return "double"; | |
168 | + } else { | |
169 | + return "varchar"; | |
170 | + } | |
171 | + } | |
172 | + | |
173 | + /** | |
174 | + * 데이터 타입 검사, dbDataType -> javaType 조회 | |
175 | + */ | |
176 | + public static DataType convertDataTypeDbtoJava (DataType datatype, Integer size) { | |
177 | + | |
178 | + | |
179 | + return null; | |
180 | + } | |
181 | + | |
182 | + | |
183 | + /** | |
184 | + * 데이터 타입 형태로 값 변경 | |
185 | + */ | |
186 | + public static Object parse(DataType dataType, Object value) { | |
187 | + if (CommonUtil.isNull(value) == true) { | |
188 | + return null; | |
189 | + } | |
190 | + | |
191 | + Class<?> javaType = dataType.getJavaType(); | |
192 | + try { | |
193 | + if (javaType.getSimpleName().equals("Byte")) { | |
194 | + return Byte.parseByte(value.toString()); | |
195 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
196 | + return Boolean.parseBoolean(value.toString()); | |
197 | + } else if (javaType.getSimpleName().equals("Character")) { | |
198 | + return value.toString().toCharArray(); | |
199 | + } else if (javaType.getSimpleName().equals("String")) { | |
200 | + return value.toString(); | |
201 | + } else if (javaType.getSimpleName().equals("Short")) { | |
202 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
203 | + return Short.parseShort(value.toString()); | |
204 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
205 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
206 | + return Integer.parseInt(value.toString()); | |
207 | + } else if (javaType.getSimpleName().equals("Long")) { | |
208 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
209 | + return Long.parseLong(value.toString()); | |
210 | + } else if (javaType.getSimpleName().equals("Float")) { | |
211 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
212 | + return Float.parseFloat(value.toString()); | |
213 | + } else if (javaType.getSimpleName().equals("Double")) { | |
214 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
215 | + return Double.parseDouble(value.toString()); | |
216 | + } else { | |
217 | + return value; | |
218 | + } | |
219 | + } catch (Exception e) { | |
220 | + e.printStackTrace(); | |
221 | + return dataType.getInitValue(); | |
222 | + } | |
223 | + } | |
224 | + | |
225 | + /** | |
226 | + * 데이터 타입 형태로 값 변경 | |
227 | + */ | |
228 | + public static boolean parseCheck (DataType dataType, Object value) { | |
229 | + if (CommonUtil.isNull(value) == true) { | |
230 | + return false; | |
231 | + } | |
232 | + | |
233 | + Class<?> javaType = dataType.getJavaType(); | |
234 | + try { | |
235 | + if (javaType.getSimpleName().equals("Byte")) { | |
236 | + Byte.parseByte(value.toString()); | |
237 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
238 | + Boolean.parseBoolean(value.toString()); | |
239 | + } else if (javaType.getSimpleName().equals("Character")) { | |
240 | + value.toString().toCharArray(); | |
241 | + } else if (javaType.getSimpleName().equals("String")) { | |
242 | + value.toString(); | |
243 | + } else if (javaType.getSimpleName().equals("Short")) { | |
244 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
245 | + Short.parseShort(value.toString()); | |
246 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
247 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
248 | + Integer.parseInt(value.toString()); | |
249 | + } else if (javaType.getSimpleName().equals("Long")) { | |
250 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
251 | + Long.parseLong(value.toString()); | |
252 | + } else if (javaType.getSimpleName().equals("Float")) { | |
253 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
254 | + Float.parseFloat(value.toString()); | |
255 | + } else if (javaType.getSimpleName().equals("Double")) { | |
256 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
257 | + Double.parseDouble(value.toString()); | |
258 | + } | |
259 | + | |
260 | + return true; | |
261 | + } catch (Exception e) { | |
262 | + //e.printStackTrace(); | |
263 | + return false; | |
264 | + } | |
265 | + } | |
266 | + | |
267 | + | |
268 | +} | |
269 | + |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicColumn.java
... | ... | @@ -0,0 +1,56 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.01.04 | |
9 | + * | |
10 | + * 데이터 베이스 기본 정보를 담는 Class 입니다. | |
11 | + */ | |
12 | +@Getter | |
13 | +@Setter | |
14 | +public class TableBasicColumn implements Cloneable{ | |
15 | + | |
16 | + public TableBasicColumn () {} | |
17 | + | |
18 | + public TableBasicColumn (TableBasicInfo tableBasicInfo) { | |
19 | + this.columnName = tableBasicInfo.getColumnName(); | |
20 | + this.tobeColumnName = tableBasicInfo.getTobeColumnName(); | |
21 | + this.dataType = tableBasicInfo.getDataType(); | |
22 | + this.size = tableBasicInfo.getSize(); | |
23 | + } | |
24 | + | |
25 | + /** | |
26 | + * 컬럼명 | |
27 | + */ | |
28 | + private String columnName; | |
29 | + | |
30 | + /** | |
31 | + * 바뀔 컬럼명 | |
32 | + */ | |
33 | + private String tobeColumnName; | |
34 | + | |
35 | + /** | |
36 | + * 컬럼의 데이터 타입(DB기준) | |
37 | + */ | |
38 | + private String dataType; | |
39 | + | |
40 | + /** | |
41 | + * 컬럼의 데이터 size | |
42 | + */ | |
43 | + private long size; | |
44 | + | |
45 | + /** | |
46 | + * 해당 열의 PK인지 아닌지에 대한 여부 | |
47 | + */ | |
48 | + private boolean isPrimary; | |
49 | + | |
50 | + | |
51 | + | |
52 | + public TableBasicColumn clone() throws CloneNotSupportedException { | |
53 | + return (TableBasicColumn)super.clone(); | |
54 | + } | |
55 | + | |
56 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicInfo.java
... | ... | @@ -0,0 +1,85 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import lombok.Getter; | |
7 | +import lombok.Setter; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2024.01.04 | |
12 | + * | |
13 | + * 데이터 베이스 기본 설정 변경시 사용할 class 입니다. | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class TableBasicInfo { | |
18 | + | |
19 | + public TableBasicInfo () {} | |
20 | + | |
21 | + public TableBasicInfo (String databaseName, String tableName, String columnName) { | |
22 | + this.databaseName = databaseName; | |
23 | + this.tableName = tableName; | |
24 | + this.columnName = columnName; | |
25 | + } | |
26 | + | |
27 | + /** | |
28 | + * 데이터 베이스 명 (스키마명) | |
29 | + */ | |
30 | + private String databaseName; | |
31 | + | |
32 | + /** | |
33 | + * 데이터 베이스 접속 아이디 | |
34 | + */ | |
35 | + private String id; | |
36 | + | |
37 | + /** | |
38 | + * 테이블명 | |
39 | + */ | |
40 | + private String tableName; | |
41 | + | |
42 | + /** | |
43 | + * 컬럼명 | |
44 | + */ | |
45 | + private String columnName; | |
46 | + | |
47 | + /** | |
48 | + * 바뀔 컬럼명 | |
49 | + */ | |
50 | + private String tobeColumnName; | |
51 | + | |
52 | + /** | |
53 | + * 컬럼의 데이터 타입(DB기준) | |
54 | + */ | |
55 | + private String dataType; | |
56 | + | |
57 | + /** | |
58 | + * 컬럼의 데이터 size | |
59 | + */ | |
60 | + private long size; | |
61 | + | |
62 | + /** | |
63 | + * 해당 열의 PK인지 아닌지에 대한 여부 | |
64 | + */ | |
65 | + private boolean isPrimary; | |
66 | + | |
67 | + /** | |
68 | + * PK 리스트 | |
69 | + */ | |
70 | + private List<String> primaryList; | |
71 | + | |
72 | + /** | |
73 | + * PK 리스트 | |
74 | + */ | |
75 | + private String process; | |
76 | + | |
77 | + | |
78 | + /** | |
79 | + * 컬럼의 데이터 목록 | |
80 | + */ | |
81 | + List<TableBasicColumn> tableBasicColumns = new ArrayList<TableBasicColumn>(); | |
82 | + | |
83 | + | |
84 | + | |
85 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/CmmnFile.java
... | ... | @@ -0,0 +1,48 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2023-12-28 | |
11 | + * | |
12 | + * 공통파일 관리 객체 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CmmnFile { | |
17 | + | |
18 | + // 파일ID | |
19 | + private String fileId; | |
20 | + | |
21 | + // 파일명 | |
22 | + private String name; | |
23 | + | |
24 | + // 파일 마스크 먕 | |
25 | + private String maskName; | |
26 | + | |
27 | + // 파일사이즈 | |
28 | + private long size; | |
29 | + | |
30 | + // 콘텐츠 타입? | |
31 | + private String contentType; | |
32 | + | |
33 | + // 파일 경로 | |
34 | + private String fullPath; | |
35 | + | |
36 | + // 파일 서브 경로 | |
37 | + private String subPath; | |
38 | + | |
39 | + // 파일 확장자 | |
40 | + private String extention; | |
41 | + | |
42 | + // 생성일 | |
43 | + private Timestamp creatDt; | |
44 | + | |
45 | + // 파일매니저 ID | |
46 | + private String fileManagerId; | |
47 | + | |
48 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileInfo.java
... | ... | @@ -0,0 +1,119 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.vo; | |
2 | + | |
3 | +import java.io.File; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2024.01.12 | |
11 | + * | |
12 | + * 파일변환 관련 Object입니다. | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class FileInfo { | |
17 | + | |
18 | + | |
19 | + /** | |
20 | + * 생성자(파일) | |
21 | + */ | |
22 | + public FileInfo(File file) { | |
23 | + this.file = file; | |
24 | + } | |
25 | + | |
26 | + /** | |
27 | + * 생성자(파일, 확장자) | |
28 | + */ | |
29 | + public FileInfo(File file, String fileFome) { | |
30 | + this.file = file; | |
31 | + this.fileFom = fileFome; | |
32 | + } | |
33 | + | |
34 | + | |
35 | + /** | |
36 | + * 생성자(파일및, 확장자, 구분자) | |
37 | + */ | |
38 | + public FileInfo(File file, String fileFome, String suffix) { | |
39 | + this.file = file; | |
40 | + this.fileFom = fileFome; | |
41 | + this.suffix = suffix; | |
42 | + | |
43 | + } | |
44 | + | |
45 | + | |
46 | + /** | |
47 | + * 관리 파일 | |
48 | + */ | |
49 | + private File file; | |
50 | + | |
51 | + /** | |
52 | + * 파일 명 | |
53 | + */ | |
54 | + private String fileName; | |
55 | + | |
56 | + | |
57 | + /** | |
58 | + * 파일 수집 타입 : 전체, 포함, 특정 | |
59 | + */ | |
60 | + private String type; | |
61 | + | |
62 | + /** | |
63 | + * 마지막 파일 옵션 | |
64 | + */ | |
65 | + private boolean lastData; | |
66 | + | |
67 | + /** | |
68 | + * 데이터셋 업데이트 보다 최신 파일만 선택 옵션 | |
69 | + */ | |
70 | + private boolean datasetAfter; | |
71 | + | |
72 | + /** | |
73 | + * 데이터셋 아이디 | |
74 | + */ | |
75 | + private String datasetId; | |
76 | + | |
77 | + /** | |
78 | + * 데이터(행,열)의 컬럼인 Row의 Index | |
79 | + */ | |
80 | + private int rowDataColumnIndex; | |
81 | + | |
82 | + /** | |
83 | + * 데이터(행,열)의 Row 시작 Index | |
84 | + */ | |
85 | + private int startRowIndex; | |
86 | + | |
87 | + /** | |
88 | + * 데이터(행,열)의 Cell 시작 Index | |
89 | + */ | |
90 | + private int startCellIndex; | |
91 | + | |
92 | + /** | |
93 | + * 파일 쓰기 옵션 | |
94 | + */ | |
95 | + private boolean streOptn = true; | |
96 | + | |
97 | + /** | |
98 | + * 파일 타입 : xlsx, xls, csv, text, json, xml ... | |
99 | + */ | |
100 | + private String fileFom = "xlsx"; | |
101 | + | |
102 | + /** | |
103 | + * 날짜시간 형식 | |
104 | + */ | |
105 | + private String suffix = "_YYYYMMDDHHmmss"; | |
106 | + | |
107 | + /** | |
108 | + * 일계산 | |
109 | + */ | |
110 | + private int addDay = 0; | |
111 | + | |
112 | + /** | |
113 | + * file 구분자 | |
114 | + */ | |
115 | + private String delimiter = ","; | |
116 | + | |
117 | + | |
118 | + | |
119 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileManage.java
... | ... | @@ -0,0 +1,132 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.vo; | |
2 | + | |
3 | + | |
4 | +import java.sql.Timestamp; | |
5 | +import java.util.Date; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.FileType; | |
8 | + | |
9 | +import lombok.Getter; | |
10 | +import lombok.Setter; | |
11 | + | |
12 | + | |
13 | + | |
14 | +/** | |
15 | + * @author 김성원 | |
16 | + * @since 2023.12.29 | |
17 | + * | |
18 | + * File 관리 Domain 입니다. | |
19 | + */ | |
20 | +@Getter | |
21 | +@Setter | |
22 | +public class FileManage { | |
23 | + | |
24 | + public FileManage() {}; | |
25 | + | |
26 | + public FileManage(String fileManagerId) { | |
27 | + this.fileManagerId = fileManagerId; | |
28 | + }; | |
29 | + | |
30 | + public FileManage(long fileSeq) { | |
31 | + this.fileId = fileSeq; | |
32 | + }; | |
33 | + | |
34 | + public FileManage(String fileManagerId, long fileSeq) { | |
35 | + this.fileManagerId = fileManagerId; | |
36 | + this.fileId = fileSeq; | |
37 | + }; | |
38 | + | |
39 | + public FileManage(FileType fileType) { | |
40 | + this.fileType = fileType; | |
41 | + }; | |
42 | + | |
43 | + public FileManage(FileType fileType, String contentType) { | |
44 | + this.fileType = fileType; | |
45 | + this.contentType = contentType; | |
46 | + }; | |
47 | + | |
48 | + public FileManage(String fileManagerId, FileType fileType) { | |
49 | + this.fileManagerId = fileManagerId; | |
50 | + this.fileType = fileType; | |
51 | + }; | |
52 | + | |
53 | + public FileManage(String fileManagerId, FileType fileType, String contentType) { | |
54 | + this.fileManagerId = fileManagerId; | |
55 | + this.fileType = fileType; | |
56 | + this.contentType = contentType; | |
57 | + }; | |
58 | + | |
59 | + /** | |
60 | + * 파일 관리 아이디 | |
61 | + */ | |
62 | + private String fileManagerId; | |
63 | + | |
64 | + /** | |
65 | + * 파일 타입 | |
66 | + */ | |
67 | + private FileType fileType; | |
68 | + | |
69 | + /** | |
70 | + * 등록한 컨텐츠 타입 | |
71 | + */ | |
72 | + private String contentType; | |
73 | + | |
74 | + /** | |
75 | + * 파일 SEQ | |
76 | + */ | |
77 | + private long fileId; | |
78 | + | |
79 | + /** | |
80 | + * 파일명 | |
81 | + */ | |
82 | + private String name; | |
83 | + | |
84 | + /** | |
85 | + * 마스크 파일명 | |
86 | + */ | |
87 | + private String maskName; | |
88 | + | |
89 | + /** | |
90 | + * 파일 사이즈. | |
91 | + */ | |
92 | + private long size; | |
93 | + | |
94 | + /** | |
95 | + * 서브 디렉토리. | |
96 | + */ | |
97 | + private String subDir; | |
98 | + | |
99 | + /** | |
100 | + * 데이터 셋 파일 절대 경로 | |
101 | + */ | |
102 | + private String fullDir; | |
103 | + | |
104 | + /** | |
105 | + * 파일 확장자. | |
106 | + */ | |
107 | + private String extension; | |
108 | + | |
109 | + /** | |
110 | + * 파일 생성일. | |
111 | + */ | |
112 | + private Date createDate; | |
113 | + | |
114 | + | |
115 | + | |
116 | + | |
117 | + | |
118 | + /** | |
119 | + * file 관련 메세지 | |
120 | + */ | |
121 | + //private CheckMessage checkMessage = new CheckMessage(); | |
122 | + | |
123 | +// public CheckMessage getCheckMessage() { | |
124 | +// return checkMessage; | |
125 | +// } | |
126 | +// | |
127 | +// public void setCheckMessage(CheckMessage checkMessage) { | |
128 | +// this.checkMessage = checkMessage; | |
129 | +// } | |
130 | + | |
131 | + | |
132 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/AuthUtil.java
... | ... | @@ -0,0 +1,100 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | +import org.slf4j.Logger; | |
5 | +import org.slf4j.LoggerFactory; | |
6 | + | |
7 | +import jakarta.servlet.http.HttpSession; | |
8 | + | |
9 | +import java.util.HashMap; | |
10 | + | |
11 | +public class AuthUtil { | |
12 | + | |
13 | + private static final Logger LOGGER = LoggerFactory.getLogger(AuthUtil.class); | |
14 | + | |
15 | + //Session에 등록된 Login User ID Key | |
16 | + public static final String LOGIN_USER_SESSION = "loginUser"; | |
17 | + | |
18 | + //중복 로그인가능 여부 | |
19 | + public static final boolean IS_POSSIBLE_DUPLICATION_LOGIN = false; | |
20 | + | |
21 | + //Session Max 시간(초) | |
22 | + public static final int SESSION_MAX_TIME = 60*60*6;//6시간 | |
23 | + | |
24 | + public static HashMap<String, Object> getLoginUser () { | |
25 | + try { | |
26 | + //현재 client의 HttpSession 조회 | |
27 | + HttpSession session = CommonUtil.getHttpSession(false); | |
28 | + if(session == null || session.getAttribute(LOGIN_USER_SESSION) == null || ((HashMap<String, Object>) session.getAttribute(LOGIN_USER_SESSION)).get("user_id") == null) { | |
29 | + return null; | |
30 | + }else { | |
31 | + return (HashMap<String, Object>) session.getAttribute(LOGIN_USER_SESSION); | |
32 | + } | |
33 | + } catch(NullPointerException e) { | |
34 | + LOGGER.error(e.toString()); | |
35 | + // System.out.println("AuthUtil getLoginUser Error : "); | |
36 | + // e.printStackTrace(); | |
37 | + return null; | |
38 | + } | |
39 | + } | |
40 | + | |
41 | + public static String getLoginUserId () { | |
42 | + HashMap<String, Object> user = getLoginUser(); | |
43 | + if (user != null) { | |
44 | + return (String) user.get("user_id"); | |
45 | + } else { | |
46 | + return null; | |
47 | + } | |
48 | + } | |
49 | + public static HashMap<String, Object> getKey () { | |
50 | + try { | |
51 | + //현재 client의 HttpSession 조회 | |
52 | + HttpSession session = CommonUtil.getHttpSession(true); | |
53 | + if(session == null || session.getAttribute("key") == null || ((HashMap<String, Object>) session.getAttribute("key")).get("salt") == null) { | |
54 | + return null; | |
55 | + }else { | |
56 | + return ((HashMap<String, Object>) session.getAttribute("key")); | |
57 | + } | |
58 | + } catch(NullPointerException e) { | |
59 | + LOGGER.error(e.toString()); | |
60 | + return null; | |
61 | + } | |
62 | + } | |
63 | + | |
64 | + public static String getKeySaltKey () { | |
65 | + HashMap<String, Object> key = getKey(); | |
66 | + if (key != null ) { | |
67 | + if(key.get("salt") != null) { | |
68 | + return key.get("salt").toString(); | |
69 | + }else { | |
70 | + return null; | |
71 | + } | |
72 | + } else { | |
73 | + return null; | |
74 | + } | |
75 | + } | |
76 | + public static String getKeyIvtKey () { | |
77 | + HashMap<String, Object> key = getKey(); | |
78 | + if (key != null ) { | |
79 | + if(key != null) { | |
80 | + return key.get("iv").toString(); | |
81 | + }else { | |
82 | + return null; | |
83 | + } | |
84 | + } else { | |
85 | + return null; | |
86 | + } | |
87 | + } | |
88 | + public static String getKeyENC_KEY () { | |
89 | + HashMap<String, Object> key = getKey(); | |
90 | + if (key != null ) { | |
91 | + if(key.get("ENC_KEY") != null) { | |
92 | + return key.get("ENC_KEY").toString(); | |
93 | + }else{ | |
94 | + return null; | |
95 | + } | |
96 | + } else { | |
97 | + return null; | |
98 | + } | |
99 | + } | |
100 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/CommonUtil.java
... | ... | @@ -0,0 +1,718 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.IOException; | |
6 | +import java.lang.reflect.Field; | |
7 | +import java.lang.reflect.Modifier; | |
8 | +import java.math.BigDecimal; | |
9 | +import java.net.InetAddress; | |
10 | +import java.net.InetSocketAddress; | |
11 | +import java.net.Socket; | |
12 | +import java.net.UnknownHostException; | |
13 | +import java.text.SimpleDateFormat; | |
14 | +import java.util.ArrayList; | |
15 | +import java.util.Arrays; | |
16 | +import java.util.Collection; | |
17 | +import java.util.Date; | |
18 | +import java.util.HashMap; | |
19 | +import java.util.LinkedHashMap; | |
20 | +import java.util.List; | |
21 | +import java.util.Map; | |
22 | +import java.util.Set; | |
23 | +import java.util.UUID; | |
24 | + | |
25 | +import jakarta.servlet.http.HttpServletRequest; | |
26 | +import jakarta.servlet.http.HttpSession; | |
27 | + | |
28 | +import org.json.XML; | |
29 | +import org.json.simple.JSONArray; | |
30 | +import org.json.simple.JSONObject; | |
31 | +import org.springframework.web.context.request.RequestContextHolder; | |
32 | +import org.springframework.web.context.request.ServletRequestAttributes; | |
33 | + | |
34 | +import com.fasterxml.jackson.core.JsonParseException; | |
35 | +import com.fasterxml.jackson.core.type.TypeReference; | |
36 | +import com.fasterxml.jackson.databind.JsonMappingException; | |
37 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
38 | +import com.fasterxml.jackson.databind.SerializationFeature; | |
39 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
40 | + | |
41 | +public class CommonUtil { | |
42 | + | |
43 | + /** | |
44 | + * @author 최정우 | |
45 | + * @since 2019.12.11 | |
46 | + * | |
47 | + * 데이터의 표준화 사용 유무 | |
48 | + */ | |
49 | + private static boolean IS_USE_STANDARD = true; | |
50 | + | |
51 | + public static void setIsUseStandard (boolean isUseStandard) { | |
52 | + IS_USE_STANDARD = isUseStandard; | |
53 | + } | |
54 | + | |
55 | + public static boolean getIsUseStandard () { | |
56 | + return IS_USE_STANDARD; | |
57 | + } | |
58 | + | |
59 | + /** | |
60 | + * @author 최정우 | |
61 | + * @since 2019.11.13 | |
62 | + * | |
63 | + * 빈 문자열 검사 | |
64 | + */ | |
65 | + public static boolean isNull(Object obj) { | |
66 | + return obj == null; | |
67 | + } | |
68 | + | |
69 | + | |
70 | + /** | |
71 | + * @author 최정우 | |
72 | + * @since 2019.11.13 | |
73 | + * | |
74 | + * string to int check | |
75 | + */ | |
76 | + public static boolean isInt (String text) { | |
77 | + try { | |
78 | + Integer.parseInt(text); | |
79 | + return true; | |
80 | + } catch(NumberFormatException e) { | |
81 | + return false; | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + /** | |
86 | + * @author 최정우 | |
87 | + * @since 2019.11.13 | |
88 | + * | |
89 | + * string to int check | |
90 | + */ | |
91 | + public static boolean isLong (String text) { | |
92 | + try { | |
93 | + Long.parseLong(text); | |
94 | + return true; | |
95 | + } catch(NumberFormatException e) { | |
96 | + return false; | |
97 | + } | |
98 | + } | |
99 | + | |
100 | + /** | |
101 | + * @author 최정우 | |
102 | + * @since 2019.11.13 | |
103 | + * | |
104 | + * string to double check | |
105 | + */ | |
106 | + public static boolean isDouble (String text) { | |
107 | + try { | |
108 | + Double.parseDouble(text); | |
109 | + return true; | |
110 | + } catch (NumberFormatException e) { | |
111 | + return false; | |
112 | + } catch (Exception e) { | |
113 | + return false; | |
114 | + } | |
115 | + } | |
116 | + | |
117 | + /** | |
118 | + * @author 최정우 | |
119 | + * @since 2020.01.08 | |
120 | + * | |
121 | + * object to int | |
122 | + */ | |
123 | + public static int parseInt (Object obj) { | |
124 | + try { | |
125 | + return Integer.parseInt(obj.toString()); | |
126 | + } catch(Exception e) { | |
127 | + return 0; | |
128 | + } | |
129 | + } | |
130 | + | |
131 | + /** | |
132 | + * @author 최정우 | |
133 | + * @since 2020.01.08 | |
134 | + * | |
135 | + * string to int | |
136 | + */ | |
137 | + public static int parseInt (String text) { | |
138 | + try { | |
139 | + return Integer.parseInt(text); | |
140 | + } catch(NumberFormatException e) { | |
141 | + return 0; | |
142 | + } | |
143 | + } | |
144 | + | |
145 | + /** | |
146 | + * @author 최정우 | |
147 | + * @since 2020.01.08 | |
148 | + * | |
149 | + * int to double | |
150 | + */ | |
151 | + public static long parseLong (int number) { | |
152 | + try { | |
153 | + return (long) number; | |
154 | + } catch(Exception e) { | |
155 | + return 0; | |
156 | + } | |
157 | + } | |
158 | + | |
159 | + /** | |
160 | + * @author 최정우 | |
161 | + * @since 2020.01.08 | |
162 | + * | |
163 | + * object to double | |
164 | + */ | |
165 | + public static long parseLong (String text) { | |
166 | + try { | |
167 | + return Long.parseLong(text); | |
168 | + } catch(Exception e) { | |
169 | + return 0; | |
170 | + } | |
171 | + } | |
172 | + | |
173 | + /** | |
174 | + * @author 최정우 | |
175 | + * @since 2020.01.08 | |
176 | + * | |
177 | + * object to double | |
178 | + */ | |
179 | + public static long parseLong (Object obj) { | |
180 | + try { | |
181 | + if (obj instanceof Integer) { | |
182 | + return (long) obj; | |
183 | + } else { | |
184 | + return Long.parseLong(obj.toString()); | |
185 | + } | |
186 | + } catch(Exception e) { | |
187 | + return 0; | |
188 | + } | |
189 | + } | |
190 | + | |
191 | + /** | |
192 | + * @author 최정우 | |
193 | + * @since 2020.01.08 | |
194 | + * | |
195 | + * int to double | |
196 | + */ | |
197 | + public static double parseDouble (int number) { | |
198 | + try { | |
199 | + return (double) number; | |
200 | + } catch(Exception e) { | |
201 | + return 0.0; | |
202 | + } | |
203 | + } | |
204 | + | |
205 | + /** | |
206 | + * @author 최정우 | |
207 | + * @since 2020.01.08 | |
208 | + * | |
209 | + * object to double | |
210 | + */ | |
211 | + public static double parseDouble (String text) { | |
212 | + try { | |
213 | + return Double.parseDouble(text); | |
214 | + } catch(Exception e) { | |
215 | + return 0.0; | |
216 | + } | |
217 | + } | |
218 | + | |
219 | + /** | |
220 | + * @author 최정우 | |
221 | + * @since 2020.01.08 | |
222 | + * | |
223 | + * object to double | |
224 | + */ | |
225 | + public static double parseDouble (Object obj) { | |
226 | + try { | |
227 | + if (obj instanceof Integer) { | |
228 | + return (double) obj; | |
229 | + } else { | |
230 | + return Double.parseDouble(obj.toString()); | |
231 | + } | |
232 | + } catch(Exception e) { | |
233 | + return 0.0; | |
234 | + } | |
235 | + } | |
236 | + | |
237 | + /** | |
238 | + * @author 최정우 | |
239 | + * @since 2019.11.13 | |
240 | + * | |
241 | + * 문자열의 모든 공백 제거 | |
242 | + */ | |
243 | + public static String allTrim(String text) { | |
244 | + return text.replaceAll("\\p{Z}", ""); | |
245 | + } | |
246 | + | |
247 | + /** | |
248 | + * @author 최정우 | |
249 | + * @since 2019.11.13 | |
250 | + * | |
251 | + * 문자열 앞뒤 공백 제거후, 문자열 사이에 존재하는 공백을 한개의 공백으로 치환 | |
252 | + * ex) " abcd efg hijk " => "abcd efg hijk" | |
253 | + */ | |
254 | + public static String normalizeSpace(String text) { | |
255 | + return text.trim().replaceAll("\\s+", " "); | |
256 | + } | |
257 | + | |
258 | + /** | |
259 | + * @author 최정우 | |
260 | + * @since 2019.11.13 | |
261 | + * | |
262 | + * 숫자 빼고 모든 문자 제거 | |
263 | + */ | |
264 | + public static String getOnlyNumber (String text) { | |
265 | + return text.replaceAll("[^0-9]", ""); | |
266 | + } | |
267 | + | |
268 | + /** | |
269 | + * @author 최정우 | |
270 | + * @since 2019.11.13 | |
271 | + * | |
272 | + * 문자 빼고 모든 숫자 제거 | |
273 | + */ | |
274 | + public static String getOnlyText (String text) { | |
275 | + return text.replaceAll("[0-9]", ""); | |
276 | + } | |
277 | + | |
278 | + /** | |
279 | + * @author 최정우 | |
280 | + * @since 2019.11.13 | |
281 | + * | |
282 | + * 특정 문자열 개수 check | |
283 | + */ | |
284 | + public static int getWordCount (String text, String word) { | |
285 | + int size = 0; | |
286 | + int fromIndex = -1; | |
287 | + while ((fromIndex = text.indexOf(word, fromIndex + 1)) >= 0) { | |
288 | + size++; | |
289 | + } | |
290 | + return size; | |
291 | + } | |
292 | + | |
293 | + /** | |
294 | + * @author 최정우 | |
295 | + * @since 2019.11.13 | |
296 | + * | |
297 | + * 문자열 to Date문자열 | |
298 | + */ | |
299 | + public static boolean isDate (String text) { | |
300 | + if (StringUtil.isEmpty(text) == true || StringUtil.isEmpty(getOnlyNumber(text)) == true || getOnlyNumber(text).length() < 6) { | |
301 | + return false; | |
302 | + } | |
303 | + | |
304 | + //공백을 제외한 문자얻기, 대문자로 치환 | |
305 | + String newText = allTrim(text).toUpperCase(); | |
306 | + | |
307 | + try { | |
308 | + //문자열의 날짜 패턴 생성 | |
309 | + String pattern = createDatePattern(newText); | |
310 | + if (pattern == null) { | |
311 | + return false; | |
312 | + } | |
313 | + | |
314 | + SimpleDateFormat newPattern = new SimpleDateFormat(pattern); | |
315 | + //문자열 날짜 형태로 변환 | |
316 | + newPattern.parse(newText); | |
317 | + return true; | |
318 | + } catch (Exception e) { | |
319 | + //e.printStackTrace(); | |
320 | + return false; | |
321 | + } | |
322 | + } | |
323 | + | |
324 | + /** | |
325 | + * @author 최정우 | |
326 | + * @since 2019.11.13 | |
327 | + * | |
328 | + * 문자열 to Date문자열 | |
329 | + */ | |
330 | + public static String parseDateText (String text) { | |
331 | + if (StringUtil.isEmpty(text) == true || StringUtil.isEmpty(getOnlyNumber(text)) == true || getOnlyNumber(text).length() < 6) { | |
332 | + return null; | |
333 | + } | |
334 | + | |
335 | + //공백을 제외한 문자얻기, 대문자로 치환 | |
336 | + String newText = allTrim(text).toUpperCase(); | |
337 | + | |
338 | + //문자열의 날짜 패턴 생성 | |
339 | + String pattern = createDatePattern(newText); | |
340 | + if (pattern == null) { | |
341 | + return null; | |
342 | + } | |
343 | + | |
344 | + Date date = null; | |
345 | + String dateText = null; | |
346 | + try { | |
347 | + SimpleDateFormat newPattern = new SimpleDateFormat(pattern); | |
348 | + | |
349 | + //문자열 날짜 형태로 변환 | |
350 | + date = newPattern.parse(newText); | |
351 | + | |
352 | + //DB에 저장할 날짜 패턴 | |
353 | + SimpleDateFormat defalutPattern = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
354 | + dateText = defalutPattern.format(date); | |
355 | + } catch (Exception e) { | |
356 | + //e.printStackTrace(); | |
357 | + } | |
358 | + return dateText; | |
359 | + } | |
360 | + | |
361 | + public static <T> List<T> mapToList (Map<?, T> map) { | |
362 | + List<T> items = new ArrayList<T>(); | |
363 | + | |
364 | + if (map != null) { | |
365 | + for(Map.Entry<?, T> item : map.entrySet()) { | |
366 | + items.add(item.getValue()); | |
367 | + } | |
368 | + } | |
369 | + | |
370 | + return items; | |
371 | + } | |
372 | + | |
373 | + public static Map objectToMap(Object obj) { | |
374 | + if (obj != null) { | |
375 | + try { | |
376 | + return (Map) obj; | |
377 | + } catch (Exception e) { | |
378 | + return new HashMap(); | |
379 | + } | |
380 | + } else { | |
381 | + return new HashMap(); | |
382 | + } | |
383 | + } | |
384 | + | |
385 | + | |
386 | + /* | |
387 | + * 시간 타입 | |
388 | + * PM, AM | |
389 | + */ | |
390 | + public final static List<String> TIME_TYPES = Arrays.asList(new String[] {"AM", "PM", "오전", "오후"}); | |
391 | + | |
392 | + /* | |
393 | + * 날짜 포맷 패턴's | |
394 | + */ | |
395 | + public final static List<Character> DATE_PATTERNS = Arrays.asList(new Character[] {'y', 'M', 'd', 'H', 'm', 's'}); | |
396 | + | |
397 | + /* | |
398 | + * 날짜 포맷 패턴's의 최대 문자열 수 | |
399 | + */ | |
400 | + public final static List<Integer> DATE_PATTERNS_MAX_LENGTH = Arrays.asList(new Integer[] {4, 2, 2, 2, 2, 2}); | |
401 | + | |
402 | + /** | |
403 | + * @author 최정우 | |
404 | + * @since 2019.11.13 | |
405 | + * | |
406 | + * 문자열의 날짜 패턴 생성 | |
407 | + */ | |
408 | + public static String createDatePattern (String date) { | |
409 | + | |
410 | + List<Character> DATE_PATTERNS = Arrays.asList(new Character[] {'y', 'M', 'd', 'H', 'm', 's'}); | |
411 | + | |
412 | + //시간 표기가 (0~12 -> AM, PM사용)인지 (0~23)인지 확인 후, 날짜 포맷 패턴's에 있는 시간 패턴 변경 | |
413 | + int timeTypeFindIndex = -1; | |
414 | + for (int i = 0; i < TIME_TYPES.size(); i++) { | |
415 | + //("AM", "PM", "오전", "오후" 중 1개)가 포함된 단어가 있는지 확인, Index 위치를 담기(없으면 -1) | |
416 | + if ((timeTypeFindIndex = date.indexOf(TIME_TYPES.get(i))) > -1) { | |
417 | + //문자열에 포함된 ("AM", "PM", "오전", "오후" 중 1개) 삭제 | |
418 | + date = date.replaceAll(TIME_TYPES.get(i), ""); | |
419 | + //시간 패턴 변경 [H -> h] | |
420 | + DATE_PATTERNS.set(3, 'h'); | |
421 | + break; | |
422 | + } | |
423 | + } | |
424 | + | |
425 | + //숫자를 뺀 나머지 문자열 가지고오기 ex) "2020.08.03" -> ".." | |
426 | + //숫자를 뺀 나머지 문자열 가지고오기 ex) "2020.08.03 19:20:21" -> "..::" | |
427 | + final char[] separators = getOnlyText(date).toCharArray(); | |
428 | + | |
429 | + | |
430 | + | |
431 | + //사용할 최대 패턴 수 | |
432 | + int maxPatterSize = 0; | |
433 | + if (DATE_PATTERNS.size() <= separators.length) { | |
434 | + maxPatterSize = DATE_PATTERNS.size(); | |
435 | + } else { | |
436 | + maxPatterSize = separators.length; | |
437 | + } | |
438 | + | |
439 | + //구분자별 Index 위치's (사용할 최대 패턴 수 + 시작점:-1, 종료점:date문자열의 최종 길이) | |
440 | + List<Integer> sizeByPatterns = new ArrayList<Integer>(); | |
441 | + | |
442 | + | |
443 | + //구분자 별 Index 위치 파악 후, 앞에 있는 문자열의 수 찾은 후, 추가 (마지막 패턴 뒤에 있는 문자열을 따로 처리해줘야함) | |
444 | + int fromIndex = -1; | |
445 | + for (int i = 0; i < maxPatterSize; i++) { | |
446 | + //구분자 | |
447 | + char separator = separators[i]; | |
448 | + | |
449 | + //'현재 찾은 위치' : 이전에 찾은 위치(찾기 시작할 위치 => fromIndex) + 1 부터 찾기 시작함 | |
450 | + int currentFromIndex = date.indexOf(separator, fromIndex + 1); | |
451 | + | |
452 | + //현재 패턴의 문자열 수 = '현재 찾은 위치' - '이전에 찾은 위치' - 1 [추가] | |
453 | + sizeByPatterns.add(currentFromIndex - fromIndex - 1); | |
454 | + | |
455 | + //'현재 찾은 위치'는 '이전에 찾은 위치'가 됨 | |
456 | + fromIndex = currentFromIndex; | |
457 | + } | |
458 | + //마지막 패턴 뒤에 있는 문자열 = '문자열의 길이' - '마지막에 찾은 위치(이전에 찾은 위치)' - 1 [추가] | |
459 | + sizeByPatterns.add(date.length() - fromIndex - 1); | |
460 | + | |
461 | + | |
462 | + //패턴을 담을 변수 | |
463 | + StringBuilder pattern = new StringBuilder(); | |
464 | + | |
465 | + //DATE_PATTERS 순서 대로, 각 구분자 별 Index 위치 크기만큼 문자열에 패턴 삽입 + 구분자 삽입 | |
466 | + //마지막 전까지만 for문 돌림 | |
467 | + for (int i = 0, patternIndex = 0; i < sizeByPatterns.size() && patternIndex < DATE_PATTERNS.size(); i++, patternIndex++) { | |
468 | + | |
469 | + //패턴 추가 | |
470 | + int usingSize = 0; | |
471 | + for (int j = 0; j < sizeByPatterns.get(i); j++) { | |
472 | + if (j >= usingSize + DATE_PATTERNS_MAX_LENGTH.get(patternIndex)) { | |
473 | + usingSize += DATE_PATTERNS_MAX_LENGTH.get(patternIndex++); | |
474 | + | |
475 | + /*단 한개의 패턴이라도 '최대 문자열 수'를 넘어서면 -> '날짜 아님'*/ | |
476 | + if (i >= sizeByPatterns.size() || patternIndex >= DATE_PATTERNS.size()) { | |
477 | + return null; | |
478 | + } | |
479 | + } | |
480 | + | |
481 | + pattern.append(DATE_PATTERNS.get(patternIndex)); | |
482 | + } | |
483 | + | |
484 | + //날짜 구분자 추가 (마지막 구분자까지만) | |
485 | + if (i < separators.length) { | |
486 | + pattern.append(separators[i]); | |
487 | + } | |
488 | + | |
489 | + | |
490 | + } | |
491 | + | |
492 | + if (timeTypeFindIndex > -1) { | |
493 | + pattern.insert(timeTypeFindIndex, 'a'); | |
494 | + } | |
495 | + | |
496 | + if(!(pattern.toString().equals("-") || pattern.toString().equals("/") || pattern.toString().equals("."))){ | |
497 | + pattern = null; | |
498 | + } | |
499 | + | |
500 | + return pattern.toString(); | |
501 | + } | |
502 | + | |
503 | + | |
504 | + /** | |
505 | + * @author 최정우 | |
506 | + * @since 2020.01.26 | |
507 | + * | |
508 | + * ping 체크 | |
509 | + */ | |
510 | + public static boolean pingCheck (String ip) { | |
511 | + InetAddress inetAddress; | |
512 | + try { | |
513 | + inetAddress = InetAddress.getByName(ip); | |
514 | + return inetAddress.isReachable(1000); | |
515 | + } catch (UnknownHostException e) { | |
516 | + return false; | |
517 | + } catch (IOException e) { | |
518 | + return false; | |
519 | + } catch (Exception e) { | |
520 | + return false; | |
521 | + } | |
522 | + } | |
523 | + | |
524 | + /** | |
525 | + * @author 김성원 | |
526 | + * @since 2024.01.04 | |
527 | + * | |
528 | + * 접속 체크 (ip + port) | |
529 | + */ | |
530 | + public static boolean linkCheck(String ip, int port) { | |
531 | + Socket socket = new Socket(); | |
532 | + try { | |
533 | + socket.connect(new InetSocketAddress(ip, port), 1000); | |
534 | + boolean isConnect = socket.isConnected(); | |
535 | + socket.close(); | |
536 | + return isConnect; | |
537 | + } catch (UnknownHostException e) { | |
538 | + return false; | |
539 | + } catch (IOException e) { | |
540 | + return false; | |
541 | + } catch (Exception e) { | |
542 | + return false; | |
543 | + } | |
544 | + } | |
545 | + | |
546 | + | |
547 | + /** | |
548 | + * @author 최정우 | |
549 | + * @since 2019.12.09 | |
550 | + * | |
551 | + * 데이터 셋 목록 Convert LinkedHashMap<String, Object> to List<String> | |
552 | + */ | |
553 | + public static List<List<Object>> rowDataMapToList (List<LinkedHashMap<String, Object>> rowMapData) throws Exception { | |
554 | + List<List<Object>> rowData = new ArrayList<List<Object>>(); | |
555 | + for (int i = 0; i < rowMapData.size(); i++) { | |
556 | + List<Object> row = new ArrayList<Object>(); | |
557 | + LinkedHashMap<String, Object> mapdata = rowMapData.get(i); | |
558 | + for( String key : mapdata.keySet() ){ | |
559 | + if (mapdata.get(key) == null) { | |
560 | + row.add(null);//null값 대체 | |
561 | + } else { | |
562 | + row.add(mapdata.get(key).toString()); | |
563 | + } | |
564 | + } | |
565 | + rowData.add(row); | |
566 | + } | |
567 | + return rowData; | |
568 | + } | |
569 | + | |
570 | + /** | |
571 | + * @author 최정우 | |
572 | + * @since 2020.01.26 | |
573 | + * | |
574 | + * 현재 client의 HttpServletRequest 조회 | |
575 | + */ | |
576 | + public static HttpServletRequest getHttpServletRequest () { | |
577 | + try { | |
578 | + ServletRequestAttributes servletRequestAttribute = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); | |
579 | + return servletRequestAttribute.getRequest(); | |
580 | + } catch (NullPointerException e) { | |
581 | + return null; | |
582 | + } | |
583 | + } | |
584 | + | |
585 | + | |
586 | + /** | |
587 | + * @author 최정우 | |
588 | + * @since 2020.01.26 | |
589 | + * | |
590 | + * 현재 client의 HttpSession 조회 | |
591 | + */ | |
592 | + public static HttpSession getHttpSession (boolean create) { | |
593 | + try { | |
594 | + HttpServletRequest request = getHttpServletRequest(); | |
595 | + if (request != null) { | |
596 | + return request.getSession(create); | |
597 | + } else { | |
598 | + return null; | |
599 | + } | |
600 | + } catch (NullPointerException e) { | |
601 | + return null; | |
602 | + } | |
603 | + } | |
604 | + | |
605 | + /** | |
606 | + * @author 김성원 | |
607 | + * @since 2024.01.10 | |
608 | + * | |
609 | + * 사용자 세션 정보 조회 | |
610 | + */ | |
611 | + public static HashMap<String, Object> getHttpSessionMember () { | |
612 | + try { | |
613 | + HttpServletRequest request = getHttpServletRequest(); | |
614 | + if(request.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) { | |
615 | + return (HashMap<String, Object>)request.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
616 | + }else { | |
617 | + return null; | |
618 | + } | |
619 | + } catch (NullPointerException e) { | |
620 | + return null; | |
621 | + } | |
622 | + } | |
623 | + | |
624 | + /** | |
625 | + * @author 최정우 | |
626 | + * @since 2020.01.26 | |
627 | + * | |
628 | + * HttpServletRequest를 활용한 Client IP 가지고오기 | |
629 | + * Header의 X-FORWARDED-FOR 값을 통해 IP 조회, 만약 Header에 X-FORWARDED-FOR가 없으면 getRemoteAddr() 이걸로 조회 | |
630 | + */ | |
631 | + public static String getClientIp () { | |
632 | + try { | |
633 | + HttpServletRequest request = getHttpServletRequest(); | |
634 | + if (null != request.getHeader("X-FORWARDED-FOR")) { | |
635 | + return request.getHeader("X-FORWARDED-FOR"); | |
636 | + } else { | |
637 | + return request.getRemoteAddr(); | |
638 | + } | |
639 | + } catch (NullPointerException e) { | |
640 | + return null; | |
641 | + } | |
642 | + } | |
643 | + | |
644 | + | |
645 | + | |
646 | + /** | |
647 | + * @author 최정우 | |
648 | + * @since 2019.12.09 | |
649 | + * | |
650 | + * JSONObject to Map<String, Object> | |
651 | + */ | |
652 | + public static Map<String, Object> jsonObjectToMap( JSONObject jsonObj ) { | |
653 | + Map<String, Object> map = null; | |
654 | + try { | |
655 | + map = new ObjectMapper().readValue(jsonObj.toJSONString(), Map.class) ; | |
656 | + | |
657 | + } catch (JsonParseException e) { | |
658 | + e.printStackTrace(); | |
659 | + } catch (JsonMappingException e) { | |
660 | + e.printStackTrace(); | |
661 | + } catch (IOException e) { | |
662 | + e.printStackTrace(); | |
663 | + } | |
664 | + return map; | |
665 | + } | |
666 | + | |
667 | + /** | |
668 | + * @author 최정우 | |
669 | + * @since 2019.12.09 | |
670 | + * | |
671 | + * JSONObject to List<Map<String, Object>> | |
672 | + */ | |
673 | + public static List<Map<String, Object>> jsonArrayToMap( JSONArray jsonObj ) { | |
674 | + List<Map<String, Object>> map = null; | |
675 | + try { | |
676 | + map = new ObjectMapper().readValue(jsonObj.toJSONString(), new TypeReference<List<Map<String, Object>>>(){}) ; | |
677 | + | |
678 | + } catch (JsonParseException e) { | |
679 | + e.printStackTrace(); | |
680 | + } catch (JsonMappingException e) { | |
681 | + e.printStackTrace(); | |
682 | + } catch (IOException e) { | |
683 | + e.printStackTrace(); | |
684 | + } | |
685 | + return map; | |
686 | + } | |
687 | + | |
688 | + /** | |
689 | + * @author 최정우 | |
690 | + * @since 2019.12.09 | |
691 | + * | |
692 | + * xmlStr to JsonStr | |
693 | + */ | |
694 | + public static String xmlStrToJsonStr(String xmlStr) throws Exception { | |
695 | + org.json.JSONObject jObject = XML.toJSONObject(xmlStr); | |
696 | + ObjectMapper mapper = new ObjectMapper(); | |
697 | + mapper.enable(SerializationFeature.INDENT_OUTPUT); | |
698 | + Object json = mapper.readValue(jObject.toString(), Object.class); | |
699 | + String output = mapper.writeValueAsString(json); | |
700 | + return output; | |
701 | + } | |
702 | + | |
703 | + | |
704 | + | |
705 | + /** | |
706 | + * @author 김성원 | |
707 | + * @since 2024.01.10 | |
708 | + * | |
709 | + * 데이터베이스 난수생성 | |
710 | + */ | |
711 | + public static String getRandKey(String prifix) { | |
712 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); | |
713 | + long timeInMillis =System.currentTimeMillis(); | |
714 | + Date timeInDate = new Date(timeInMillis); | |
715 | + return prifix+"_"+sdf.format(timeInDate)+UUID.randomUUID().toString().substring(0,5); | |
716 | + } | |
717 | + | |
718 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/CryptoUtil.java
... | ... | @@ -0,0 +1,221 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | +import java.nio.ByteBuffer; | |
5 | +import java.nio.charset.StandardCharsets; | |
6 | +import java.util.Base64; | |
7 | +import java.util.Base64.Decoder; | |
8 | +import java.util.Base64.Encoder; | |
9 | +import java.util.HashMap; | |
10 | +import java.util.Map; | |
11 | + | |
12 | +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |
13 | +import org.springframework.security.crypto.encrypt.AesBytesEncryptor; | |
14 | +import org.springframework.security.crypto.factory.PasswordEncoderFactories; | |
15 | +import org.springframework.security.crypto.password.DelegatingPasswordEncoder; | |
16 | +import org.springframework.security.crypto.password.PasswordEncoder; | |
17 | + | |
18 | +/** | |
19 | + * @author 김성원 | |
20 | + * @since 2024.01.02 | |
21 | + * | |
22 | + * 암호화 관련 클래스 | |
23 | + */ | |
24 | +public class CryptoUtil { | |
25 | + | |
26 | + | |
27 | + private final static String encoderKey = "bcrypt"; | |
28 | + private final static String secret = "takenbmsc!@#"; | |
29 | + private final static String salt = "70726574657374"; | |
30 | + | |
31 | + /** | |
32 | + * @author 김성원 | |
33 | + * @since 2024.01.09 | |
34 | + * | |
35 | + * 기본 단방향 엔코드 생성 | |
36 | + */ | |
37 | + public static PasswordEncoder createDelegatingPasswordEncoder() { | |
38 | + Map<String, PasswordEncoder> encoders = new HashMap<>(); | |
39 | + encoders.put(encoderKey, new BCryptPasswordEncoder()); | |
40 | + return new DelegatingPasswordEncoder(encoderKey, encoders); | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * @author 김성원 | |
45 | + * @since 2024.01.09 | |
46 | + * | |
47 | + * 커스텀 key기반의 단방향 엔코드 생성 | |
48 | + */ | |
49 | + public static PasswordEncoder createDelegatingPasswordEncoder(String key) { | |
50 | + Map<String, PasswordEncoder> encoders = new HashMap<>(); | |
51 | + encoders.put(key, new BCryptPasswordEncoder()); | |
52 | + return new DelegatingPasswordEncoder(key, encoders); | |
53 | + } | |
54 | + | |
55 | + | |
56 | + /** | |
57 | + * @author 김성원 | |
58 | + * @since 2024.01.09 | |
59 | + * | |
60 | + * 기본 단방향 암호화 | |
61 | + */ | |
62 | + public static String PasswordEncoder(String data) { | |
63 | + | |
64 | + PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); | |
65 | + Encoder encoder = Base64.getEncoder(); | |
66 | + return encoder.encodeToString(passwordEncoder.encode(data).getBytes(StandardCharsets.UTF_8)) ; | |
67 | + } | |
68 | + | |
69 | + /** | |
70 | + * @author 김성원 | |
71 | + * @since 2024.01.09 | |
72 | + * | |
73 | + * 커스텀 key기반의 단방향 암호화 | |
74 | + */ | |
75 | + public static String PasswordEncoder(String key , String data) { | |
76 | + | |
77 | + if(StringUtil.isEmpty(data)) { | |
78 | + return data; | |
79 | + } | |
80 | + | |
81 | + PasswordEncoder passwordEncoder = createDelegatingPasswordEncoder(key); | |
82 | + | |
83 | + return passwordEncoder.encode(data); | |
84 | + } | |
85 | + | |
86 | + | |
87 | + | |
88 | + /** | |
89 | + * @author 김성원 | |
90 | + * @since 2024.01.09 | |
91 | + * | |
92 | + * 단방향 암호화 비교구문 | |
93 | + */ | |
94 | + public static boolean passwordMatch(String data, String checkData) { | |
95 | + | |
96 | + PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); | |
97 | + Decoder decoder = Base64.getDecoder(); | |
98 | + return passwordEncoder.matches(data,new String(decoder.decode(checkData), StandardCharsets.UTF_8) ); | |
99 | + | |
100 | + } | |
101 | + | |
102 | + | |
103 | + /** | |
104 | + * @author 김성원 | |
105 | + * @since 2024.01.09 | |
106 | + * | |
107 | + * 기본 key, salt 기반의 양방향 암호화 객체 생성 | |
108 | + */ | |
109 | + public static AesBytesEncryptor aesBytesEncryptor() { | |
110 | + return new AesBytesEncryptor("232323", salt); | |
111 | + } | |
112 | + | |
113 | + /** | |
114 | + * @author 김성원 | |
115 | + * @since 2024.01.09 | |
116 | + * | |
117 | + * 커스텀 key, salt 기반의 양방향 암호화 객체 생성 | |
118 | + */ | |
119 | + public static AesBytesEncryptor aesBytesEncryptor(String key, String salt) { | |
120 | + return new AesBytesEncryptor(key, salt); | |
121 | + | |
122 | + } | |
123 | + | |
124 | + /** | |
125 | + * @author 김성원 | |
126 | + * @since 2024.01.09 | |
127 | + * | |
128 | + * 기본 key, salt 기반의 양방향 암호화 | |
129 | + */ | |
130 | + public static String encryptData(String data) { | |
131 | + if(StringUtil.isEmpty(data)) { | |
132 | + return data; | |
133 | + } | |
134 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(); | |
135 | + byte[] encrypt = bytesEncryptor.encrypt(data.getBytes(StandardCharsets.UTF_8)); | |
136 | + Encoder encoder = Base64.getEncoder(); | |
137 | + return encoder.encodeToString(encrypt); | |
138 | + } | |
139 | + | |
140 | + /** | |
141 | + * @author 김성원 | |
142 | + * @since 2024.01.09 | |
143 | + * | |
144 | + * 커스텀 key, salt 기반의 양방향 암호화 | |
145 | + */ | |
146 | + public static String encryptData(String key, String salt, String data) { | |
147 | + if(StringUtil.isEmpty(data)) { | |
148 | + return data; | |
149 | + } | |
150 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(key, salt); | |
151 | + byte[] encrypt = bytesEncryptor.encrypt(data.getBytes(StandardCharsets.UTF_8)); | |
152 | + Encoder encoder = Base64.getEncoder(); | |
153 | + return encoder.encodeToString(encrypt); | |
154 | + } | |
155 | + | |
156 | + | |
157 | + | |
158 | + /** | |
159 | + * @author 김성원 | |
160 | + * @since 2024.01.09 | |
161 | + * | |
162 | + * 기본 key, salt 기반의 양방향 복호화 | |
163 | + */ | |
164 | + public static String decryptData(String data) { | |
165 | + if(StringUtil.isEmpty(data)) { | |
166 | + return data; | |
167 | + } | |
168 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(); | |
169 | + Decoder decoder = Base64.getDecoder(); | |
170 | + byte[] decrypt = bytesEncryptor.decrypt(decoder.decode(data)); | |
171 | + return new String(decrypt, StandardCharsets.UTF_8); | |
172 | + } | |
173 | + | |
174 | + /** | |
175 | + * @author 김성원 | |
176 | + * @since 2024.01.09 | |
177 | + * | |
178 | + * 커스텀 key, salt 기반의 양방향 복호화 | |
179 | + */ | |
180 | + public static String decryptData(String key, String salt, String data) { | |
181 | + if(StringUtil.isEmpty(data)) { | |
182 | + return data; | |
183 | + } | |
184 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(key, salt); | |
185 | + Decoder decoder = Base64.getDecoder(); | |
186 | + byte[] decrypt = bytesEncryptor.decrypt(decoder.decode(data)); | |
187 | + return new String(decrypt, StandardCharsets.UTF_8); | |
188 | + } | |
189 | + | |
190 | + | |
191 | + /** | |
192 | + * @author 김성원 | |
193 | + * @since 2024.01.09 | |
194 | + * | |
195 | + * * 바이트 스트링 변환 | |
196 | + */ | |
197 | + public static String byteArrayToString(byte[] bytes) { | |
198 | + StringBuilder sb = new StringBuilder(); | |
199 | + for (byte abyte :bytes){ | |
200 | + sb.append(abyte); | |
201 | + sb.append(" "); | |
202 | + } | |
203 | + return sb.toString(); | |
204 | + } | |
205 | + | |
206 | + /** | |
207 | + * @author 김성원 | |
208 | + * @since 2024.01.09 | |
209 | + * | |
210 | + * 스트링 바이트 변환 | |
211 | + */ | |
212 | + public static byte[] stringToByteArray(String byteString) { | |
213 | + String[] split = byteString.split("\\s"); | |
214 | + ByteBuffer buffer = ByteBuffer.allocate(split.length); | |
215 | + for (String s : split) { | |
216 | + buffer.put((byte) Integer.parseInt(s)); | |
217 | + } | |
218 | + return buffer.array(); | |
219 | + } | |
220 | + | |
221 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/HTTPUtil.java
... | ... | @@ -0,0 +1,145 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.BufferedReader; | |
6 | +import java.io.DataOutputStream; | |
7 | +import java.io.IOException; | |
8 | +import java.io.InputStreamReader; | |
9 | +import java.io.UnsupportedEncodingException; | |
10 | +import java.net.HttpURLConnection; | |
11 | +import java.net.MalformedURLException; | |
12 | +import java.net.URL; | |
13 | +import java.net.URLEncoder; | |
14 | +import java.util.List; | |
15 | +import java.util.Map; | |
16 | + | |
17 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam; | |
18 | + | |
19 | + | |
20 | +/** | |
21 | + * @author 김성원 | |
22 | + * @since 2024.01.12 | |
23 | + * | |
24 | + * 데이터 수집 - HTTP통신 관련 Util 입니다. | |
25 | + */ | |
26 | +public class HTTPUtil { | |
27 | + | |
28 | + | |
29 | + /** | |
30 | + * @author 김성원 | |
31 | + * @since 2024.01.12 | |
32 | + * | |
33 | + * [GET] HTTP 통신 | |
34 | + */ | |
35 | + public synchronized String HttpConnectionApi (String urlText, int type, List<ApiParam> parameter) { | |
36 | + StringBuffer response = new StringBuffer(); | |
37 | + | |
38 | + URL url = null; | |
39 | + try { | |
40 | + if (parameter.isEmpty() == false) { | |
41 | + urlText += "?" + createUrlQueryApi(parameter, "UTF-8"); | |
42 | + } | |
43 | + url = new URL(urlText); | |
44 | + } catch (MalformedURLException e) { | |
45 | + // TODO Auto-generated catch block | |
46 | + e.printStackTrace(); | |
47 | + } | |
48 | + | |
49 | + HttpURLConnection httpCon = null; | |
50 | + try { | |
51 | + | |
52 | + /* Connection */ | |
53 | + httpCon = (HttpURLConnection) url.openConnection(); | |
54 | + if(type == 1) { | |
55 | + httpCon.setRequestMethod("POST"); | |
56 | + }else { | |
57 | + httpCon.setRequestMethod("GET"); | |
58 | + } | |
59 | + | |
60 | + 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"); | |
61 | + httpCon.setConnectTimeout(1000 * 60);//http통신 최대 커넥션 시간(1분) | |
62 | + httpCon.setReadTimeout(1000 * 60);//http통신 커넥션 이후, 데이터를 받아오는데 걸리는 최대 시간(1분) | |
63 | + httpCon.setDoInput(true);//받아올 데이터가 있을 때, 사용 | |
64 | + | |
65 | + //HTTP Request 결과 코드 | |
66 | + int responseCode = httpCon.getResponseCode(); | |
67 | + if (responseCode == 200) { | |
68 | + //Response 결과 데이터 받기 | |
69 | + BufferedReader input = new BufferedReader(new InputStreamReader(httpCon.getInputStream(), "UTF-8")); | |
70 | + | |
71 | + //Response 결과 데이터를 문자열로 만들기 | |
72 | + String result = null; | |
73 | + while ((result = input.readLine()) != null) { | |
74 | + response.append(result); | |
75 | + } | |
76 | + | |
77 | + //InputStream, BufferedReader 종료 | |
78 | + input.close(); | |
79 | + | |
80 | + //HTTP Connection 종료 | |
81 | + httpCon.disconnect(); | |
82 | + | |
83 | + } else { | |
84 | + System.out.println("[HTTP]" + url + "(" + responseCode + " 에러)"); | |
85 | + } | |
86 | + | |
87 | + } catch (Exception e) { | |
88 | + e.printStackTrace(); | |
89 | + } | |
90 | + | |
91 | + //문자열로된 Response 결과 return | |
92 | + return response.toString(); | |
93 | + } | |
94 | + | |
95 | + /** | |
96 | + * @author 김성원 | |
97 | + * @since 2024.01.12 | |
98 | + * | |
99 | + * 파라메터 데이터를 HTTP통신을 위한 문자열로 변환시켜주는 메서드 | |
100 | + * Map -> String | |
101 | + */ | |
102 | + public String createUrlQueryApi (List<ApiParam> parameter, String incoding) { | |
103 | + if (parameter.isEmpty() == true) { | |
104 | + return ""; | |
105 | + } else { | |
106 | + | |
107 | + | |
108 | + StringBuilder query = new StringBuilder(); | |
109 | + for(ApiParam param : parameter) { | |
110 | + try { | |
111 | + | |
112 | + // 날짜 변경 처리 | |
113 | + if(param.isDateForm() == true) { | |
114 | + param.setValue(StringUtil.getTodayaddDate(param.getValue().toString(),param.getDateType(), param.getAddDate())); | |
115 | + | |
116 | + } | |
117 | + | |
118 | + if(query.length() > 0) { | |
119 | + query.append('&'); | |
120 | + } | |
121 | + | |
122 | + if (StringUtil.isEmpty(incoding) == true) { | |
123 | + query.append(param.getKey()); | |
124 | + query.append('='); | |
125 | + query.append(param.getValue()); | |
126 | + } else { | |
127 | + query.append(URLEncoder.encode(param.getKey(), incoding)); | |
128 | + query.append('='); | |
129 | + if(param.isDisableDecode()) { | |
130 | + query.append(param.getValue()); | |
131 | + }else { | |
132 | + query.append(URLEncoder.encode(String.valueOf(param.getValue()), incoding)); | |
133 | + } | |
134 | + } | |
135 | + | |
136 | + } catch (UnsupportedEncodingException e) { | |
137 | + e.printStackTrace(); | |
138 | + } | |
139 | + } | |
140 | + | |
141 | + return query.toString(); | |
142 | + } | |
143 | + } | |
144 | + | |
145 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/SesssionEventListener.java
... | ... | @@ -0,0 +1,293 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | +import org.slf4j.Logger; | |
5 | +import org.slf4j.LoggerFactory; | |
6 | + | |
7 | +import jakarta.servlet.annotation.WebListener; | |
8 | +import jakarta.servlet.http.HttpSession; | |
9 | +import jakarta.servlet.http.HttpSessionEvent; | |
10 | +import jakarta.servlet.http.HttpSessionListener; | |
11 | +import java.security.NoSuchAlgorithmException; | |
12 | +import java.security.SecureRandom; | |
13 | +import java.util.*; | |
14 | +import java.util.concurrent.ConcurrentHashMap; | |
15 | + | |
16 | +/** | |
17 | + * @author 서영석 | |
18 | + * @since 2023.05.31 | |
19 | + * | |
20 | + * Custom session 저장소를 만들어 놓고 | |
21 | + * Tomcat이 관리하는 session 생성 또는 소멸시, 발생하는 이벤트를 활용하여 (HttpSessionListener를 통해 이벤트를 받을 수 있음) | |
22 | + * Custom session 저장소에 추가, 삭제를 통해 | |
23 | + * session을 적절히 controll 하기위한 목적을 가진 Class 입니다. | |
24 | + */ | |
25 | +@WebListener | |
26 | +public class SesssionEventListener implements HttpSessionListener { | |
27 | + | |
28 | + private static final Logger LOGGER = LoggerFactory.getLogger(SesssionEventListener.class); | |
29 | + | |
30 | + //싱글턴패턴 사용을 위한 클래스변수 | |
31 | + public static SesssionEventListener sesssionEventListener = null; | |
32 | + | |
33 | + //싱글턴패턴으로 객체 생성 후 리턴. | |
34 | + public static synchronized SesssionEventListener getInstance() { | |
35 | + if(sesssionEventListener == null) { | |
36 | + sesssionEventListener = new SesssionEventListener(); | |
37 | + } | |
38 | + return sesssionEventListener; | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * Custom session 저장소 (tomcat이 관리하고있는 실제 session저장소는 아님) 목록 | |
43 | + * ConcurrentHashMap을 사용하는 이유 : | |
44 | + * HashMap은 Thread Safe 하지 않기 때문에 싱글턴 패턴에서 해당 session 저장소를 사용하기 위해서는 Thread Safe 한 ConcurrentHashMap를 사용 | |
45 | + * HashTable도 Thread Safe 하지만, 읽기 쓰기 둘다 한개의 Thread만 접근 가능함 | |
46 | + * ConcurrentHashMap은 쓰기에서한 한개의 Tread만 접근 가능하도록 해놓음 (읽기는 여러개의 쓰레드에서 동시 접근 가능) | |
47 | + */ | |
48 | + private static final Map<String, HttpSession> sessions = new ConcurrentHashMap<>(); | |
49 | + | |
50 | + /** | |
51 | + * @author 서영석 | |
52 | + * @since 2023.05.31 | |
53 | + * | |
54 | + * @param userId : 사용자(회원) ID | |
55 | + * | |
56 | + * userId와 동일한 로그인 session을 가진 session ID 목록 조회 | |
57 | + */ | |
58 | + public synchronized static List<String> duplicationLoginSessionIdSelectListByUserId (String userId) { | |
59 | + List<String> result = new ArrayList<>(); | |
60 | + try { | |
61 | + //Custom session 저장소에서 session ID는 다르지만 userId가 같은게 존재하는지 확인 | |
62 | + for (String key : sessions.keySet()) { | |
63 | + HttpSession session = sessions.get(key); | |
64 | + if (session == null || session.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) { | |
65 | + //세션이 존재하고, 로그인 정보가 없으면 continue; | |
66 | + continue; | |
67 | + } else { | |
68 | + //로그인 정보가 있으면 -> 중복 확인 | |
69 | + HashMap<String, Object> loginUser = (HashMap<String, Object>) session.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
70 | + String loginUserId = (String) loginUser.get("user_id"); | |
71 | + | |
72 | + /** 사용자(회원) ID와 동일한 로그인 정보 일 시 -> add **/ | |
73 | + if (userId.equals(loginUserId) == true) { | |
74 | + result.add(session.getId()); | |
75 | + } else { | |
76 | + //동일한 로그인 정보가 아니면 -> continue; | |
77 | + continue; | |
78 | + } | |
79 | + } | |
80 | + } | |
81 | + } catch (NullPointerException e) { | |
82 | + LOGGER.error(e.toString()); | |
83 | + } | |
84 | + | |
85 | + return result; | |
86 | + } | |
87 | + | |
88 | + | |
89 | + /** | |
90 | + * @author 서영석 | |
91 | + * @since 2023.05.31 | |
92 | + * | |
93 | + * 현재 client의 정보와 중복된 로그인 session ID 목록 조회 | |
94 | + * | |
95 | + * 현재 User의 세션과 Custom session 저장소에 저장된 session 중 | |
96 | + * session ID는 다르지만 userId가 같은 session List return | |
97 | + */ | |
98 | + public synchronized static List<String> duplicationLoginSessionIdSelectList () { | |
99 | + List<String> result = new ArrayList<>(); | |
100 | + | |
101 | + try { | |
102 | + //현재 사용자의 session | |
103 | + HttpSession currentUserSession = CommonUtil.getHttpSession(false); | |
104 | + //현재 사용자의 session이 존재하고, 로그인 정보가 있을 때 | |
105 | + if (currentUserSession != null && currentUserSession.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) { | |
106 | + //현재 사용자의 로그인 정보 | |
107 | + HashMap<String, Object> currentLoginUser = (HashMap<String, Object>) currentUserSession.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
108 | + String currentLoginUserId = (String) currentLoginUser.get("user_id"); | |
109 | + | |
110 | + //Custom session 저장소에서 session ID는 다르지만 userId가 같은게 존재하는지 확인 | |
111 | + for (String key : sessions.keySet()) { | |
112 | + HttpSession session = sessions.get(key); | |
113 | + if (session == null || session.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) { | |
114 | + //세션이 존재하고, 로그인 정보가 없으면 continue; | |
115 | + continue; | |
116 | + } else if (currentUserSession.getId().equals(session.getId()) == true) { | |
117 | + //동일한 세션 ID이면 continue; | |
118 | + continue; | |
119 | + } else { | |
120 | + //로그인 정보가 있으면 -> 중복 확인 | |
121 | + HashMap<String, Object> duplicationLoginUser = (HashMap<String, Object>) session.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
122 | + String duplicationLoginUserId = (String) duplicationLoginUser.get("user_id"); | |
123 | + | |
124 | + /** 동일한 로그인 정보 일 시 -> add **/ | |
125 | + if (currentLoginUserId.equals(duplicationLoginUserId) == true) { | |
126 | + result.add(session.getId()); | |
127 | + } else { | |
128 | + //동일한 로그인 정보가 아니면 -> continue; | |
129 | + continue; | |
130 | + } | |
131 | + } | |
132 | + } | |
133 | + } | |
134 | + } catch (NullPointerException e) { | |
135 | + LOGGER.error(e.toString()); | |
136 | + } | |
137 | + | |
138 | + return result; | |
139 | + } | |
140 | + | |
141 | + /** | |
142 | + * @author 서영석 | |
143 | + * @since 2023.05.31 | |
144 | + * | |
145 | + * @param userId : 사용자(회원) ID | |
146 | + * | |
147 | + * userId와 동일한 로그인 session을 가진 session ID 목록 삭제 | |
148 | + */ | |
149 | + public static int duplicationLoginSessionDeleteByUserId (String userId) { | |
150 | + int result = 0; | |
151 | + try { | |
152 | + List<String> sessionIds = duplicationLoginSessionIdSelectListByUserId(userId); | |
153 | + for (int i = 0; i < sessionIds.size(); i++) { | |
154 | + //Custom session 저장소에서 session 무효화 시키기 | |
155 | + sessions.get(sessionIds.get(i)).invalidate(); | |
156 | + //Custom session 저장소에서 session 삭제 | |
157 | + sessions.remove(sessionIds.get(i)); | |
158 | + } | |
159 | + } catch (NullPointerException e) { | |
160 | + LOGGER.error(e.toString()); | |
161 | + } | |
162 | + return result; | |
163 | + } | |
164 | + | |
165 | + /** | |
166 | + * @author 서영석 | |
167 | + * @since 2023.05.31 | |
168 | + * | |
169 | + * 현재 client의 정보와 중복된 로그인 session 전부 무효화 시키기 (완전 삭제는 못시킴) | |
170 | + */ | |
171 | + public static int duplicationLoginSessionDeleteAll () { | |
172 | + int result = 0; | |
173 | + try { | |
174 | + List<String> sessionIds = duplicationLoginSessionIdSelectList(); | |
175 | + for (int i = 0; i < sessionIds.size(); i++) { | |
176 | + //Custom session 저장소에서 session 무효화 시키기 | |
177 | + sessions.get(sessionIds.get(i)).invalidate(); | |
178 | + //Custom session 저장소에서 session 삭제 | |
179 | + sessions.remove(sessionIds.get(i)); | |
180 | + } | |
181 | + } catch (NullPointerException e) { | |
182 | + LOGGER.error(e.toString()); | |
183 | + } | |
184 | + return result; | |
185 | + } | |
186 | + | |
187 | + //난수생성 | |
188 | + public static String generateRandomHex(int length) { | |
189 | + SecureRandom random = new SecureRandom(); | |
190 | + byte[] randomBytes = new byte[length / 2]; // 16진수 문자열의 길이에 맞게 바이트 배열 크기를 조절 | |
191 | + | |
192 | + random.nextBytes(randomBytes); | |
193 | + | |
194 | + // 바이트 배열을 16진수 문자열로 변환 | |
195 | + StringBuilder hexStringBuilder = new StringBuilder(); | |
196 | + for (byte b : randomBytes) { | |
197 | + hexStringBuilder.append(String.format("%02x", b)); | |
198 | + } | |
199 | + | |
200 | + return hexStringBuilder.toString(); | |
201 | + } | |
202 | + | |
203 | + /** | |
204 | + * HttpSessionListener Interface로 부터 상속 받은 메소드 | |
205 | + * | |
206 | + * tomcat에서 session이 생성되었을 때(session timeout), 발생하는 이벤트 | |
207 | + * @param target : session 이벤트(생성) 객체 | |
208 | + * | |
209 | + * session 생성 이벤트가 발생하면 Custom session 저장소(sessions)에 해당 session ID 값을 Key로 잡고 저장 | |
210 | + * (※ Default로 session에 현재 Client의 IP를 넣어줌) | |
211 | + */ | |
212 | + @Override | |
213 | + public void sessionCreated(HttpSessionEvent target) { | |
214 | + //System.out.println("sessionCreated - 현재 세션 개수 : " + sessions.size() + "개"); | |
215 | + int i = 1; | |
216 | + for (String key : sessions.keySet()) { | |
217 | + HttpSession hs = sessions.get(key); | |
218 | + //System.out.println("sessionCreated - 세션 목록 " + (i++) + ". " + hs.getId()); | |
219 | + } | |
220 | +// System.out.println("sessionCreated - 이제 추가될 session id : " + target.getSession().getId()); | |
221 | + //System.out.println(""); | |
222 | + //System.out.println(""); | |
223 | + | |
224 | + // session에 key(salt) 값 넣기 시작 | |
225 | + HashMap<String, Object> key = new HashMap<String, Object>(); | |
226 | + | |
227 | + // "SHA1PRNG"은 알고리즘 이름 | |
228 | +// SecureRandom random = null; | |
229 | +// try { | |
230 | +// random = SecureRandom.getInstance("SHA1PRNG"); | |
231 | +// } catch (NoSuchAlgorithmException e) { | |
232 | +// e.printStackTrace(); | |
233 | +// } | |
234 | +// SecureRandom random = new SecureRandom(); | |
235 | +// | |
236 | +// byte[] saltBytes = new byte[24]; | |
237 | +// byte[] encKeyBytes = new byte[24]; | |
238 | +// byte[] ivBytes = new byte[24]; | |
239 | +// random.nextBytes(saltBytes); | |
240 | +// random.nextBytes(encKeyBytes); | |
241 | +// random.nextBytes(ivBytes); | |
242 | + //SALT 생성 | |
243 | +// String salt = Base64.getEncoder().encodeToString(saltBytes); | |
244 | +// String ENC_KEY = Base64.getEncoder().encodeToString(encKeyBytes); | |
245 | +// String iv = Base64.getEncoder().encodeToString(ivBytes); | |
246 | + String salt = generateRandomHex(32); | |
247 | + String ENC_KEY = generateRandomHex(32); | |
248 | + String iv = generateRandomHex(32); | |
249 | + key.put("salt",salt); | |
250 | + key.put("ENC_KEY",ENC_KEY); | |
251 | + key.put("iv",iv); | |
252 | + | |
253 | + target.getSession().setAttribute("key", key); | |
254 | + | |
255 | +// System.out.println("key : "+key); | |
256 | + //종료 | |
257 | + | |
258 | + | |
259 | + //현재 Client의 IP set | |
260 | + target.getSession().setAttribute("ip", CommonUtil.getClientIp()); | |
261 | +// target.getSession().setAttribute("key",); | |
262 | +// System.out.println("target test1: "+target); | |
263 | +// System.out.println("target.getSession() test1: "+target.getSession()); | |
264 | +// System.out.println("sessions test1: "+sessions); | |
265 | +// System.out.println("sessions test2: "+sessions.get(target.getSession().getId())); | |
266 | +// System.out.println("CommonUtil.getClientIp() test: "+CommonUtil.getClientIp()); | |
267 | +// System.out.println("target.getSession() test: "+target.getSession()); | |
268 | + | |
269 | + //세션 저장소에 set | |
270 | + sessions.put(target.getSession().getId(), target.getSession()); | |
271 | + } | |
272 | + | |
273 | + /** | |
274 | + * HttpSessionListener Interface로 부터 상속 받은 메소드 | |
275 | + * | |
276 | + * tomcat에서 session이 소멸되었을 때, 발생하는 이벤트 | |
277 | + * @param target : session 이벤트(소멸) 객체 | |
278 | + * | |
279 | + * session 제거 이벤트가 발생하면 Custom session 저장소(sessions)에 해당 session ID 값을 가지고 있는 session 무효화 및 제거 | |
280 | + */ | |
281 | + @Override | |
282 | + public void sessionDestroyed(HttpSessionEvent target) { | |
283 | + //소멸된 세션 Custom session 저장소에서 가지고 오기 | |
284 | + if (sessions.get(target.getSession().getId()) != null) { | |
285 | + //소멸된 세션 무효화 시키기 (가능한지 모르겠지만, 일단 작성해봄) | |
286 | + sessions.get(target.getSession().getId()).invalidate(); | |
287 | + //Custom session 저장소에서 해당 session 삭제 | |
288 | + sessions.remove(target.getSession().getId()); | |
289 | + } else { | |
290 | + return; | |
291 | + } | |
292 | + } | |
293 | +}(No newline at end of file) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/StringUtil.java
... | ... | @@ -0,0 +1,713 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.UnsupportedEncodingException; | |
6 | +import java.sql.Timestamp; | |
7 | +import java.text.SimpleDateFormat; | |
8 | +import java.util.ArrayList; | |
9 | +import java.util.Calendar; | |
10 | +import java.util.Date; | |
11 | +import java.util.GregorianCalendar; | |
12 | +import java.util.Locale; | |
13 | +import java.util.Random; | |
14 | + | |
15 | +import org.slf4j.Logger; | |
16 | +import org.slf4j.LoggerFactory; | |
17 | +import org.springframework.boot.web.servlet.server.Encoding.Type; | |
18 | + | |
19 | + | |
20 | +/** | |
21 | + * @author 최정우 | |
22 | + * @since 2019.11.13 | |
23 | + * | |
24 | + * 문자열과 관련된 기능을 정의 해놓은 Util입니다. | |
25 | + */ | |
26 | +public class StringUtil { | |
27 | + | |
28 | + private static final Logger LOGGER = LoggerFactory.getLogger(StringUtil.class); | |
29 | + | |
30 | + public static final String NULL_TEXT = "NULL"; | |
31 | + | |
32 | + public static String toString(Object obj) { | |
33 | + if (obj == null) { | |
34 | + return null; | |
35 | + } else { | |
36 | + try { | |
37 | + return obj.toString(); | |
38 | + } catch (Exception e) { | |
39 | + return null; | |
40 | + } | |
41 | + } | |
42 | + } | |
43 | + | |
44 | + public static String toStringNotNull(Object obj) { | |
45 | + if (obj == null) { | |
46 | + return ""; | |
47 | + } else { | |
48 | + try { | |
49 | + return obj.toString(); | |
50 | + } catch (Exception e) { | |
51 | + return ""; | |
52 | + } | |
53 | + } | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * @author 최정우 | |
58 | + * @since 2020.11.26 | |
59 | + * | |
60 | + * 객체를 문자열로 바꾼 후, 문자열 길이 반환 | |
61 | + */ | |
62 | + public static int stringLength(Object obj) { | |
63 | + if (obj == null) { | |
64 | + return 0; | |
65 | + } else { | |
66 | + try { | |
67 | + return obj.toString().length(); | |
68 | + } catch (Exception e) { | |
69 | + return 0; | |
70 | + } | |
71 | + } | |
72 | + } | |
73 | + | |
74 | + /** | |
75 | + * @author 최정우 | |
76 | + * @since 2020.11.26 | |
77 | + * | |
78 | + * 문자열이 Null or null or NULL인 경우 실제 null값 세팅 | |
79 | + */ | |
80 | + public static boolean isNullText(String text) { | |
81 | + if (isEmpty(text) == false && text.toUpperCase().equals(NULL_TEXT)) { | |
82 | + return true; | |
83 | + } else { | |
84 | + return false; | |
85 | + } | |
86 | + } | |
87 | + | |
88 | + /** | |
89 | + * @author 최정우 | |
90 | + * @since 2019.11.13 | |
91 | + * | |
92 | + * 빈 문자열 검사 | |
93 | + */ | |
94 | + public static boolean isEmpty(String text) { | |
95 | + return text == null || text.trim().length() == 0; | |
96 | + } | |
97 | + | |
98 | + /** | |
99 | + * @author 최정우 | |
100 | + * @since 2019.11.13 | |
101 | + * | |
102 | + * indexOf - 문자 검색 후, 해당 문자의 위치(index)반환 | |
103 | + */ | |
104 | + public static int indexOf(String text, String searchText) { | |
105 | + if (text == null || searchText == null) { | |
106 | + return -1; | |
107 | + } | |
108 | + return text.indexOf(searchText); | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * @author 최정우 | |
113 | + * @since 2019.11.13 | |
114 | + * | |
115 | + * lastIndexOf - 문자 검색 후, 해당 문자의 위치(index)반환 | |
116 | + */ | |
117 | + public static int lastIndexOf(String text, String searchText) { | |
118 | + if (text == null || searchText == null) { | |
119 | + return -1; | |
120 | + } | |
121 | + return text.lastIndexOf(searchText); | |
122 | + } | |
123 | + | |
124 | + /** | |
125 | + * @author 최정우 | |
126 | + * @since 2019.11.13 | |
127 | + * | |
128 | + * substringBetween - 특정 문자열 사이에 값을 뽑아내는 메서드 | |
129 | + */ | |
130 | + public static String substringBetween(String text, String startText, String endText) { | |
131 | + if (isEmpty(text) == true || isEmpty(startText) == true || isEmpty(endText) == true) { | |
132 | + return null; | |
133 | + } | |
134 | + text = text.toLowerCase(); | |
135 | + startText = startText.toLowerCase(); | |
136 | + endText = endText.toLowerCase(); | |
137 | + | |
138 | + int start = text.indexOf(startText); | |
139 | + if (start != -1) { | |
140 | + int end = text.indexOf(endText, start + startText.length()); | |
141 | + if (end != -1) { | |
142 | + return text.substring(start + startText.length(), end); | |
143 | + } | |
144 | + } | |
145 | + return null; | |
146 | + } | |
147 | + | |
148 | + /** | |
149 | + * @author 최정우 | |
150 | + * @since 2019.11.13 | |
151 | + * | |
152 | + * 모든 공백 제거 | |
153 | + */ | |
154 | + public static String removeSpace(String text) { | |
155 | + if (isEmpty(text)) { | |
156 | + return text; | |
157 | + } | |
158 | + int length = text.length(); | |
159 | + char[] newCharList = new char[length]; | |
160 | + int count = 0; | |
161 | + for (int i = 0; i < length; i++) { | |
162 | + if (Character.isWhitespace(text.charAt(i)) == false) { | |
163 | + newCharList[count++] = text.charAt(i); | |
164 | + } | |
165 | + } | |
166 | + if (count == length) { | |
167 | + return text; | |
168 | + } | |
169 | + | |
170 | + return new String(newCharList, 0, count); | |
171 | + } | |
172 | + | |
173 | + | |
174 | + | |
175 | + /** | |
176 | + * @author 최정우 | |
177 | + * @since 2019.11.13 | |
178 | + * | |
179 | + * 소문자 변환 | |
180 | + */ | |
181 | + public static String lowerCase(String text) { | |
182 | + if (isEmpty(text) == true) { | |
183 | + return text; | |
184 | + } else { | |
185 | + return text.toLowerCase(); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + /** | |
190 | + * 대문자 변환 | |
191 | + */ | |
192 | + public static String upperCase(String text) { | |
193 | + if (isEmpty(text) == true) { | |
194 | + return text; | |
195 | + } else { | |
196 | + return text.toUpperCase(); | |
197 | + } | |
198 | + } | |
199 | + | |
200 | + /** | |
201 | + * @author 최정우 | |
202 | + * @since 2019.11.13 | |
203 | + * | |
204 | + * 현재날짜(년,월,일)를 구하는 기능 | |
205 | + */ | |
206 | + public static String getToday() { | |
207 | + String pattern = "yyyy-MM-dd"; | |
208 | + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
209 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
210 | + return dateFormat.format(timestamp.getTime()); | |
211 | + } | |
212 | + | |
213 | + /** | |
214 | + * @author 최정우 | |
215 | + * @since 2019.11.13 | |
216 | + * | |
217 | + * 현재날짜(년,월,일)를 구하는 기능 | |
218 | + */ | |
219 | + public static String getToday(String pattern) { | |
220 | + String defaultPattern = "yyyy-MM-dd"; | |
221 | + if (isEmpty(pattern) == true) { | |
222 | + pattern = defaultPattern; | |
223 | + } | |
224 | + | |
225 | + SimpleDateFormat dateFormat = null; | |
226 | + try { | |
227 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
228 | + } catch (Exception e) { | |
229 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
230 | + } | |
231 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
232 | + return dateFormat.format(timestamp.getTime()); | |
233 | + } | |
234 | + | |
235 | + | |
236 | + /** | |
237 | + * @author 김성원 | |
238 | + * @since 2019.11.13 | |
239 | + * | |
240 | + * 현재날짜(년,월,일)에 특정 날짜 + - | |
241 | + */ | |
242 | + public static String getTodayaddDate(String pattern, String type, int date) { | |
243 | + String defaultPattern = "yyyy-MM-dd"; | |
244 | + if (isEmpty(pattern) == true) { | |
245 | + pattern = defaultPattern; | |
246 | + } | |
247 | + | |
248 | + SimpleDateFormat dateFormat = null; | |
249 | + try { | |
250 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
251 | + } catch (Exception e) { | |
252 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
253 | + } | |
254 | + | |
255 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
256 | + Calendar cal = Calendar.getInstance(); | |
257 | + if(type.equals("year")) { | |
258 | + cal.add(Calendar.YEAR, date); | |
259 | + }else if(type.equals("month")) { | |
260 | + cal.add(Calendar.MONTH, date); | |
261 | + }else if(type.equals("day")) { | |
262 | + cal.add(Calendar.DATE, date); | |
263 | + } | |
264 | + | |
265 | + return dateFormat.format(cal.getTime()); | |
266 | + } | |
267 | + | |
268 | + /** | |
269 | + * @author 최정우 | |
270 | + * @since 2019.11.13 | |
271 | + * | |
272 | + * 현재날짜(년,월,일)를 구하는 기능 | |
273 | + */ | |
274 | + public static String getToday(String yearSuffix, String monthSuffix, String daySuffix) { | |
275 | + String defaultPattern = "yyyy년MM월dd일"; | |
276 | + if (isEmpty(yearSuffix) == true) { | |
277 | + yearSuffix = ""; | |
278 | + } | |
279 | + if (isEmpty(monthSuffix) == true) { | |
280 | + monthSuffix = ""; | |
281 | + } | |
282 | + if (isEmpty(daySuffix) == true) { | |
283 | + daySuffix = ""; | |
284 | + } | |
285 | + | |
286 | + String pattern = "yyyy" + yearSuffix + "MM" + monthSuffix + "dd" + daySuffix; | |
287 | + | |
288 | + SimpleDateFormat dateFormat = null; | |
289 | + try { | |
290 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
291 | + } catch (Exception e) { | |
292 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
293 | + } | |
294 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
295 | + return dateFormat.format(timestamp.getTime()); | |
296 | + } | |
297 | + | |
298 | + /** | |
299 | + * @author 최정우 | |
300 | + * @since 2019.11.13 | |
301 | + * | |
302 | + * 17자리의 현재일시를 구하는 기능 | |
303 | + */ | |
304 | + public static String getDateTime() { | |
305 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
306 | + String pattern = "yyyyMMddHHmmssSSS"; | |
307 | + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
308 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
309 | + return dateFormat.format(timestamp.getTime()); | |
310 | + } | |
311 | + | |
312 | + /** | |
313 | + * @author 최정우 | |
314 | + * @since 2019.11.13 | |
315 | + * | |
316 | + * 원하는 패턴의 현재일시 구하는 기능 | |
317 | + */ | |
318 | + public static String getDateTime(String pattern) { | |
319 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
320 | + String defaultPattern = "yyyyMMddHHmmssSSS"; | |
321 | + if (isEmpty(pattern)) { | |
322 | + pattern = defaultPattern; | |
323 | + } | |
324 | + SimpleDateFormat dateFormat = null; | |
325 | + try { | |
326 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
327 | + } catch (Exception e) { | |
328 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
329 | + } | |
330 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
331 | + return dateFormat.format(timestamp.getTime()); | |
332 | + } | |
333 | + | |
334 | + /** | |
335 | + * @author 최정우 | |
336 | + * @since 2019.11.13 | |
337 | + * | |
338 | + * 현재 일시 - addDay => 원하는 패턴의 일시를 구하는 기능 | |
339 | + */ | |
340 | + public static String getDateTime(String pattern, int addDay) { | |
341 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
342 | + String defaultPattern = "yyyyMMddHHmmssSSS"; | |
343 | + if (pattern == null) { | |
344 | + pattern = defaultPattern; | |
345 | + } | |
346 | + SimpleDateFormat dateFormat = null; | |
347 | + try { | |
348 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
349 | + } catch (Exception e) { | |
350 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
351 | + } | |
352 | + Calendar cal = new GregorianCalendar(); | |
353 | + cal.add(Calendar.DATE, addDay); | |
354 | + Date date = cal.getTime(); | |
355 | + return dateFormat.format(date.getTime()); | |
356 | + } | |
357 | + | |
358 | + /** | |
359 | + * @author 최정우 | |
360 | + * @since 2019.11.13 | |
361 | + * | |
362 | + * 현재 일시 - addDay => 원하는 패턴의 일시를 구하는 기능 | |
363 | + */ | |
364 | + public static String getDateTime(String pattern, int addDay, int addHour, int addMin, int addSec) { | |
365 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
366 | + String defaultPattern = "yyyyMMddHHmmssSSS"; | |
367 | + if (pattern == null) { | |
368 | + pattern = defaultPattern; | |
369 | + } | |
370 | + SimpleDateFormat dateFormat = null; | |
371 | + try { | |
372 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
373 | + } catch (Exception e) { | |
374 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
375 | + } | |
376 | + Calendar cal = new GregorianCalendar(); | |
377 | + cal.add(Calendar.DATE, addDay); | |
378 | + cal.add(Calendar.HOUR, addHour); | |
379 | + cal.add(Calendar.MINUTE, addMin); | |
380 | + cal.add(Calendar.SECOND, addSec); | |
381 | + Date date = cal.getTime(); | |
382 | + return dateFormat.format(date.getTime()); | |
383 | + } | |
384 | + | |
385 | + /** | |
386 | + * @author 최정우 | |
387 | + * @since 2019.11.13 | |
388 | + * | |
389 | + * 현재 일시(17자리)와, 랜덤숫자(4자리)를 이용하여 키값 생성 | |
390 | + */ | |
391 | + public static String getCreateKey (String prefix) { | |
392 | + int random = new Random().nextInt(9999); | |
393 | + String result = prefix + "_" + getDateTime() + "_" + numberToText(random, 4); | |
394 | + return result; | |
395 | + } | |
396 | + | |
397 | + /** | |
398 | + * @author 최정우 | |
399 | + * @since 2019.11.13 | |
400 | + * | |
401 | + * 문자열이 Date문자열(yyyy-MM-dd)로 포맷 가능한지 | |
402 | + * text: 문자열 | |
403 | + * pattern: 문자열의 날짜 패턴 | |
404 | + */ | |
405 | + public static boolean isDate(String text, String pattern) { | |
406 | + try { | |
407 | + Date date = new SimpleDateFormat(pattern).parse(text); | |
408 | + text = new SimpleDateFormat("yyyy-MM-dd").format(date); | |
409 | + return true; | |
410 | + } catch (java.text.ParseException e) { | |
411 | + // TODO Auto-generated catch block | |
412 | + return false; | |
413 | + } | |
414 | + } | |
415 | + | |
416 | + /** | |
417 | + * @author 최정우 | |
418 | + * @since 2019.11.13 | |
419 | + * | |
420 | + * 문자열을 날짜형태로 Convert | |
421 | + * text: 문자열 | |
422 | + * pattern: 문자열의 날짜 패턴 | |
423 | + * newPattern: 해당 문자열을 Converting할 날짜 패턴 | |
424 | + */ | |
425 | + public static String textToDateText (String text, String pattern, String newPattern) { | |
426 | + String defaultPattern = "yyyy-MM-dd"; | |
427 | + if (isEmpty(newPattern) == true) { | |
428 | + newPattern = defaultPattern; | |
429 | + } | |
430 | + | |
431 | + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); | |
432 | + Date date = new Date(); | |
433 | + try { | |
434 | + date = dateFormat.parse(text); | |
435 | + dateFormat.applyPattern(newPattern); | |
436 | + return dateFormat.format(date); | |
437 | + } catch (Exception e) { | |
438 | + //e.printStackTrace(); | |
439 | + return text; | |
440 | + } | |
441 | + } | |
442 | + | |
443 | + /** | |
444 | + * @author 최정우 | |
445 | + * @since 2019.11.13 | |
446 | + * | |
447 | + * 숫자 -> 문자열 -> 문자열 길이가 length보다 작을 때, length길이 만큼될 수 있도록 앞에 '0'을 붙여줌 | |
448 | + */ | |
449 | + public static String numberToText (int number, int length) { | |
450 | + String text = Integer.toString(number); | |
451 | + if (text.length() < length) { | |
452 | + int emptyLength = length - text.length(); | |
453 | + for (int i = 0; i < emptyLength; i++) { | |
454 | + text = "0" + text; | |
455 | + } | |
456 | + } | |
457 | + return text; | |
458 | + } | |
459 | + | |
460 | + /** | |
461 | + * @author 최정우 | |
462 | + * @since 2019.11.13 | |
463 | + * | |
464 | + * 문자열이 지정한 길이를 초과했을때 해당 문자열을 삭제하는 메서드 | |
465 | + * @param text 원본 문자열 배열 | |
466 | + * @param maxLength 지정길이 | |
467 | + * @return 지정길이로 자른 문자열 | |
468 | + */ | |
469 | + public static String cutString(String text, int maxLength) { | |
470 | + String result = null; | |
471 | + if (text != null) { | |
472 | + if (text.length() > maxLength) { | |
473 | + result = text.substring(0, maxLength); | |
474 | + } else | |
475 | + result = text; | |
476 | + } | |
477 | + return result; | |
478 | + } | |
479 | + | |
480 | + | |
481 | + /** | |
482 | + * @author 최정우 | |
483 | + * @since 2019.11.13 | |
484 | + * | |
485 | + * 문자열이 지정한 길이를 초과했을때 지정한길이에다가 해당 문자열을 붙여주는 메서드. | |
486 | + * @param text 원본 문자열 배열 | |
487 | + * @param addText 더할문자열 | |
488 | + * @param maxLength 지정길이 | |
489 | + * @return 지정길이로 잘라서 더할분자열 합친 문자열 | |
490 | + */ | |
491 | + public static String cutString(String text, String addText, int maxLength) { | |
492 | + String result = null; | |
493 | + if (text != null) { | |
494 | + if (text.length() > maxLength) { | |
495 | + result = text.substring(0, maxLength) + addText; | |
496 | + } else | |
497 | + result = text; | |
498 | + } | |
499 | + return result; | |
500 | + } | |
501 | + | |
502 | + | |
503 | + /** | |
504 | + * @author 최정우 | |
505 | + * @since 2019.11.13 | |
506 | + * | |
507 | + * <p>기준 문자열에 포함된 모든 대상 문자(char)를 제거한다.</p> | |
508 | + * | |
509 | + * <pre> | |
510 | + * StringUtil.remove(null, *) = null | |
511 | + * StringUtil.remove("", *) = "" | |
512 | + * StringUtil.remove("queued", 'u') = "qeed" | |
513 | + * StringUtil.remove("queued", 'z') = "queued" | |
514 | + * </pre> | |
515 | + * | |
516 | + * @param str 입력받는 기준 문자열 | |
517 | + * @param remove 입력받는 문자열에서 제거할 대상 문자열 | |
518 | + * @return 제거대상 문자열이 제거된 입력문자열. 입력문자열이 null인 경우 출력문자열은 null | |
519 | + */ | |
520 | + public static String remove(String text, char remove) { | |
521 | + if (isEmpty(text) || text.indexOf(remove) == -1) { | |
522 | + return text; | |
523 | + } | |
524 | + char[] chars = text.toCharArray(); | |
525 | + int pos = 0; | |
526 | + for (int i = 0; i < chars.length; i++) { | |
527 | + if (chars[i] != remove) { | |
528 | + chars[pos++] = chars[i]; | |
529 | + } | |
530 | + } | |
531 | + | |
532 | + return new String(chars, 0, pos); | |
533 | + } | |
534 | + | |
535 | + | |
536 | + /** | |
537 | + * @author 최정우 | |
538 | + * @since 2019.11.13 | |
539 | + * | |
540 | + * 원본 문자열의 포함된 특정 문자열을 새로운 문자열로 변환하는 메서드 | |
541 | + * @param source 원본 문자열 | |
542 | + * @param subject 원본 문자열에 포함된 특정 문자열 | |
543 | + * @param object 변환할 문자열 | |
544 | + * @return sb.toString() 새로운 문자열로 변환된 문자열 | |
545 | + */ | |
546 | + public static String replace(String text, String subject, String object) { | |
547 | + StringBuffer rtnStr = new StringBuffer(); | |
548 | + String preStr = ""; | |
549 | + String nextStr = text; | |
550 | + String srcStr = text; | |
551 | + | |
552 | + while (srcStr.indexOf(subject) >= 0) { | |
553 | + preStr = srcStr.substring(0, srcStr.indexOf(subject)); | |
554 | + nextStr = srcStr.substring(srcStr.indexOf(subject) + subject.length(), srcStr.length()); | |
555 | + srcStr = nextStr; | |
556 | + rtnStr.append(preStr).append(object); | |
557 | + } | |
558 | + rtnStr.append(nextStr); | |
559 | + return rtnStr.toString(); | |
560 | + } | |
561 | + | |
562 | + /** | |
563 | + * @author 최정우 | |
564 | + * @since 2019.11.13 | |
565 | + * | |
566 | + * 원본 문자열의 포함된 특정 문자열 첫번째 한개만 새로운 문자열로 변환하는 메서드 | |
567 | + * @param source 원본 문자열 | |
568 | + * @param subject 원본 문자열에 포함된 특정 문자열 | |
569 | + * @param object 변환할 문자열 | |
570 | + * @return sb.toString() 새로운 문자열로 변환된 문자열 / source 특정문자열이 없는 경우 원본 문자열 | |
571 | + */ | |
572 | + public static String replaceOnce(String source, String subject, String object) { | |
573 | + StringBuffer rtnStr = new StringBuffer(); | |
574 | + String preStr = ""; | |
575 | + String nextStr = source; | |
576 | + if (source.indexOf(subject) >= 0) { | |
577 | + preStr = source.substring(0, source.indexOf(subject)); | |
578 | + nextStr = source.substring(source.indexOf(subject) + subject.length(), source.length()); | |
579 | + rtnStr.append(preStr).append(object).append(nextStr); | |
580 | + return rtnStr.toString(); | |
581 | + } else { | |
582 | + return source; | |
583 | + } | |
584 | + } | |
585 | + | |
586 | + /** | |
587 | + * @author 최정우 | |
588 | + * @since 2019.11.13 | |
589 | + * | |
590 | + * <code>subject</code>에 포함된 각각의 문자를 object로 변환한다. | |
591 | + * | |
592 | + * @param source 원본 문자열 | |
593 | + * @param subject 원본 문자열에 포함된 특정 문자열 | |
594 | + * @param object 변환할 문자열 | |
595 | + * @return sb.toString() 새로운 문자열로 변환된 문자열 | |
596 | + */ | |
597 | + public static String replaceChar(String source, String subject, String object) { | |
598 | + StringBuffer rtnStr = new StringBuffer(); | |
599 | + String preStr = ""; | |
600 | + String nextStr = source; | |
601 | + String srcStr = source; | |
602 | + | |
603 | + char chA; | |
604 | + | |
605 | + for (int i = 0; i < subject.length(); i++) { | |
606 | + chA = subject.charAt(i); | |
607 | + | |
608 | + if (srcStr.indexOf(chA) >= 0) { | |
609 | + preStr = srcStr.substring(0, srcStr.indexOf(chA)); | |
610 | + nextStr = srcStr.substring(srcStr.indexOf(chA) + 1, srcStr.length()); | |
611 | + srcStr = rtnStr.append(preStr).append(object).append(nextStr).toString(); | |
612 | + } | |
613 | + } | |
614 | + | |
615 | + return srcStr; | |
616 | + } | |
617 | + | |
618 | + /** | |
619 | + * @author 최정우 | |
620 | + * @since 2019.11.13 | |
621 | + * | |
622 | + * 문자열을 다양한 문자셋(EUC-KR[KSC5601],UTF-8..)을 사용하여 인코딩하는 기능 역으로 디코딩하여 원래의 문자열을 | |
623 | + * 복원하는 기능을 제공함 String temp = new String(문자열.getBytes("바꾸기전 인코딩"),"바꿀 인코딩"); | |
624 | + * String temp = new String(문자열.getBytes("8859_1"),"KSC5601"); => UTF-8 에서 | |
625 | + * EUC-KR | |
626 | + * | |
627 | + * @param text - 문자열 | |
628 | + * @param encoding - 원래의 인코딩된 값 | |
629 | + * @param decoding - 디코딩할 문자값 | |
630 | + * @return 인(디)코딩 문자열 | |
631 | + * @exception MyException | |
632 | + * @see | |
633 | + */ | |
634 | + public static String textDecoding(String text, String encoding, String decoding) { | |
635 | + if (text == null) { | |
636 | + return null; | |
637 | + } | |
638 | + | |
639 | + try { | |
640 | + text = new String(text.getBytes(encoding), decoding); | |
641 | + } catch (UnsupportedEncodingException e) { | |
642 | + text = null; | |
643 | + } | |
644 | + | |
645 | + return text; | |
646 | + } | |
647 | + | |
648 | + | |
649 | + /** | |
650 | + * @author 최정우 | |
651 | + * @since 2020.11.26 | |
652 | + * | |
653 | + * 문자열 특정 포맷팅으로 변환 ##-#### | |
654 | + */ | |
655 | + public static String formatConvert(String data, String format) { | |
656 | + | |
657 | + StringBuilder bf = new StringBuilder(); | |
658 | + | |
659 | + if(StringUtil.isEmpty(format) || StringUtil.isEmpty(data)) { | |
660 | + bf.append(data); | |
661 | + }else { | |
662 | + int num = data.length()-1; | |
663 | + for(int i = format.length()-1 ; i >= 0 ; i--) { | |
664 | + if(format.charAt(i) == '#') { | |
665 | + bf.insert(0, data.charAt(num--)); | |
666 | + }else { | |
667 | + bf.insert(0,format.charAt(i)); | |
668 | + } | |
669 | + } | |
670 | + } | |
671 | + | |
672 | + return bf.toString(); | |
673 | + } | |
674 | + | |
675 | + /** | |
676 | + * @author 김성원 | |
677 | + * @since 2022.07.06 | |
678 | + * | |
679 | + * 날짜형식 문자열 특정 포맷팅으로 변환 ##-#### | |
680 | + */ | |
681 | + public static String dateConvert(String date) { | |
682 | + | |
683 | + StringBuilder bf = new StringBuilder(); | |
684 | + | |
685 | + boolean dateForm = true; | |
686 | + | |
687 | + if(!date.contains("-") && date.length() > 4) { | |
688 | + dateForm = false; | |
689 | + } | |
690 | + | |
691 | + if(!StringUtil.isEmpty(date)) { | |
692 | + | |
693 | + String dateStr = date.replaceAll("[^0-9]", ""); | |
694 | + // 년도 처리 | |
695 | + if(dateStr.length() < 5) { | |
696 | + bf.append(date.substring(0,4)); | |
697 | + }else { | |
698 | + if(dateForm == true) { | |
699 | + bf.append(StringUtil.formatConvert(dateStr.substring(0,6),"####-##")); | |
700 | + }else { | |
701 | + bf.append(StringUtil.formatConvert(dateStr.substring(0,6),"####-##")); | |
702 | + //bf.append(dateStr.substring(0,4)); | |
703 | + //bf.append("년 "); | |
704 | + } | |
705 | + } | |
706 | + } | |
707 | + | |
708 | + return bf.toString(); | |
709 | + } | |
710 | + | |
711 | + | |
712 | + | |
713 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CheckMessage.java
... | ... | @@ -0,0 +1,73 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.01.04 | |
9 | + * | |
10 | + * 데이터 체크, 유효성 검사 등과 같이 검사와 관련된 변수를 정의한 Class 입니다. | |
11 | + */ | |
12 | +@Getter | |
13 | +@Setter | |
14 | +public class CheckMessage { | |
15 | + | |
16 | + public CheckMessage() {} | |
17 | + | |
18 | + public CheckMessage(boolean isSuccess) { | |
19 | + this.isSuccess = isSuccess; | |
20 | + } | |
21 | + | |
22 | + public CheckMessage(String message) { | |
23 | + this.message = message; | |
24 | + } | |
25 | + | |
26 | + public CheckMessage(boolean isSuccess, String message) { | |
27 | + this.isSuccess = isSuccess; | |
28 | + this.message = message; | |
29 | + } | |
30 | + | |
31 | + public CheckMessage(boolean isSuccess, String message, int status) { | |
32 | + this.isSuccess = isSuccess; | |
33 | + this.message = message; | |
34 | + this.status = status; | |
35 | + } | |
36 | + | |
37 | + public CheckMessage(boolean isSuccess, String message, String error) { | |
38 | + this.isSuccess = isSuccess; | |
39 | + this.message = message; | |
40 | + this.error = error; | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * 체크 완료(사용가능 or 성공) 여부 | |
45 | + */ | |
46 | + private boolean isSuccess; | |
47 | + | |
48 | + /** | |
49 | + * 체크한 상태의 메세지값 | |
50 | + */ | |
51 | + private String message; | |
52 | + | |
53 | + /** | |
54 | + * 에러 메세지 | |
55 | + */ | |
56 | + private String error; | |
57 | + | |
58 | + /** | |
59 | + * 체크한 상태의 상태값 -> 상황마다 다름 | |
60 | + */ | |
61 | + private int status; | |
62 | + | |
63 | + | |
64 | + // 오류처리 | |
65 | + public void setError(String message) { | |
66 | + this.message = message; | |
67 | + this.error = message; | |
68 | + this.isSuccess = false; | |
69 | + this.status = 0; | |
70 | + } | |
71 | + | |
72 | + | |
73 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CommonVO.java
... | ... | @@ -0,0 +1,139 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.List; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
8 | + | |
9 | +import lombok.Getter; | |
10 | +import lombok.Setter; | |
11 | + | |
12 | + | |
13 | + | |
14 | +/** | |
15 | + * @author 김성원 | |
16 | + * @since 2024.01.09 | |
17 | + * | |
18 | + * 공통 검색 VO 입니다.(상속받으세요) | |
19 | + */ | |
20 | +@Getter | |
21 | +@Setter | |
22 | +public class CommonVO { | |
23 | + | |
24 | + /**************************** 공통 ****************************/ | |
25 | + /** | |
26 | + * 검색조건 | |
27 | + */ | |
28 | + private String searchCondition = ""; | |
29 | + | |
30 | + /** | |
31 | + * 검색Keyword | |
32 | + */ | |
33 | + private String searchKeyword = ""; | |
34 | + | |
35 | + /** | |
36 | + * 검색Keyword | |
37 | + */ | |
38 | + private List<String> searchKeywordList = new ArrayList<String>(); | |
39 | + | |
40 | + /** | |
41 | + * 검색사용여부 | |
42 | + */ | |
43 | + private String searchUseYn = ""; | |
44 | + | |
45 | + /** | |
46 | + * 검색 시작일 | |
47 | + */ | |
48 | + private String startDate = ""; | |
49 | + | |
50 | + /** | |
51 | + * 검색 종료일 | |
52 | + */ | |
53 | + private String endDate = ""; | |
54 | + | |
55 | + /** | |
56 | + * 정렬 기준 (컬럼명) | |
57 | + */ | |
58 | + private String order = ""; | |
59 | + | |
60 | + /** | |
61 | + * 정렬 타입 | |
62 | + * true - ASC | |
63 | + * false - DESC | |
64 | + */ | |
65 | + private boolean isOrderASC = true; | |
66 | + | |
67 | + /** | |
68 | + * 현재페이지 | |
69 | + */ | |
70 | + private int currentPage = 1; | |
71 | + | |
72 | + /** | |
73 | + * 페이지갯수 | |
74 | + */ | |
75 | + private int perPage = 10; | |
76 | + | |
77 | + /** | |
78 | + * 총 개시물 수 | |
79 | + */ | |
80 | + private int totalRows; | |
81 | + | |
82 | + /** | |
83 | + * 페이징 사용 유무 | |
84 | + */ | |
85 | + private boolean isUsePaging = true; | |
86 | + | |
87 | + /** firstIndex */ | |
88 | + private int firstIndex = 1; | |
89 | + | |
90 | + /** lastIndex */ | |
91 | + private int lastIndex = 1; | |
92 | + | |
93 | + /** 페이지사이즈 */ | |
94 | + private int pageSize = 10; | |
95 | + | |
96 | + /** recordCountPerPage */ | |
97 | + private int recordCountPerPage = 10; | |
98 | + | |
99 | + | |
100 | + public boolean getIsUsePaging() { | |
101 | + return isUsePaging; | |
102 | + } | |
103 | + | |
104 | + public void setIsUsePaging(boolean isUsePaging) { | |
105 | + this.isUsePaging = isUsePaging; | |
106 | + } | |
107 | + /**************************** 공통 ****************************/ | |
108 | + | |
109 | + /**************************** 검색어 분할 ****************************/ | |
110 | + | |
111 | + | |
112 | + public void setSearchKeywordList(List<String> searchKeywordList) { | |
113 | + this.searchKeywordList = searchKeywordList; | |
114 | + } | |
115 | + /**************************** 검색어 분할 ****************************/ | |
116 | + | |
117 | + /**************************** 데이터베이스 별 페이징 ****************************/ | |
118 | + | |
119 | + | |
120 | + private int startIndex; | |
121 | + | |
122 | + /** | |
123 | + * 마지막 게시물의 인덱스 번호 (변환과정없음, 0부터 시작) | |
124 | + */ | |
125 | + private long limit = 0; | |
126 | + | |
127 | + | |
128 | + public void searchClear() { | |
129 | + searchCondition = ""; | |
130 | + searchKeyword = ""; | |
131 | + searchUseYn = ""; | |
132 | + startDate = ""; | |
133 | + endDate = ""; | |
134 | + order = ""; | |
135 | + } | |
136 | + | |
137 | + /**************************** 데이터베이스 별 페이징 ****************************/ | |
138 | + | |
139 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CustomeResultMap.java
... | ... | @@ -0,0 +1,27 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +import java.util.HashMap; | |
7 | + | |
8 | +/** | |
9 | + * 컨트롤러의 데이터를 반환할 기본 Map클래스 | |
10 | + * | |
11 | + * @author 김성원 | |
12 | + * @since 2023.12.28 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CustomeResultMap { | |
17 | + | |
18 | + // 결과메세지 | |
19 | + private CheckMessage checkMessage; | |
20 | + | |
21 | + // 결과 데이터 | |
22 | + private HashMap<String,Object> resultData; | |
23 | + | |
24 | + public CustomeResultMap(){ | |
25 | + checkMessage = new CheckMessage(true, "성공" , 200); | |
26 | + } | |
27 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchObject.java
... | ... | @@ -0,0 +1,35 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import lombok.Getter; | |
7 | +import lombok.Setter; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2024.01.09 | |
12 | + * | |
13 | + * 공통 검색용 VO 입니다 | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class SearchObject { | |
18 | + | |
19 | + /** | |
20 | + * 검색 key | |
21 | + */ | |
22 | + private String key; | |
23 | + | |
24 | + /** | |
25 | + * 검색 값 | |
26 | + */ | |
27 | + private Object value; | |
28 | + | |
29 | + /** | |
30 | + * 데이터 타입(날짜, 숫자, 문자) | |
31 | + */ | |
32 | + private String type; | |
33 | + | |
34 | + | |
35 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchVO.java
... | ... | @@ -0,0 +1,51 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import lombok.Getter; | |
7 | +import lombok.Setter; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2024.01.09 | |
12 | + * | |
13 | + * 공통 검색 VO 입니다 | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class SearchVO { | |
18 | + | |
19 | + /** | |
20 | + * 검색Keyword | |
21 | + */ | |
22 | + private List<SearchObject> searchObjectList = new ArrayList<SearchObject>(); | |
23 | + | |
24 | + /** | |
25 | + * 정렬 기준 (컬럼명) | |
26 | + */ | |
27 | + private String order = ""; | |
28 | + | |
29 | + /** | |
30 | + * 정렬 타입 | |
31 | + * true - ASC | |
32 | + * false - DESC | |
33 | + */ | |
34 | + private boolean isOrderASC = true; | |
35 | + | |
36 | + /** | |
37 | + * 현재페이지 | |
38 | + */ | |
39 | + private int currentPage = 1; | |
40 | + | |
41 | + /** | |
42 | + * 페이지갯수 | |
43 | + */ | |
44 | + private int perPage = 10; | |
45 | + | |
46 | + /** | |
47 | + * 총 개시물 수 | |
48 | + */ | |
49 | + private int totalRows; | |
50 | + | |
51 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SystemCode.java
... | ... | @@ -0,0 +1,495 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import java.math.BigDecimal; | |
4 | +import java.sql.Timestamp; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.Arrays; | |
7 | +import java.util.Date; | |
8 | +import java.util.HashMap; | |
9 | +import java.util.LinkedHashMap; | |
10 | +import java.util.List; | |
11 | +import java.util.Map; | |
12 | +import java.util.regex.Pattern; | |
13 | + | |
14 | +import com.sun.jna.platform.win32.Sspi.TimeStamp; | |
15 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
16 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
17 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
18 | + | |
19 | + | |
20 | + | |
21 | + | |
22 | +public class SystemCode { | |
23 | + | |
24 | + //191자 => mariaDB에서 indexing가능한 최대 크기 765Byte/한글 4Byte(utf8mb4) | |
25 | + public final static int DEFAULT_VARCHAR_SIZE = 191; | |
26 | + | |
27 | + //mariaDB에서 indexing가능한 varchar 최대 크기 765Byte | |
28 | + public final static int MAX_VARCHAR_SIZE = 765; | |
29 | + | |
30 | + | |
31 | + /** | |
32 | + * @author 최정우 | |
33 | + * @since 2019.11.13 | |
34 | + * | |
35 | + * 데이터 타입을 정의한 상수 Class 입니다. | |
36 | + * 상수명(java데이터타입, 초기값, mysql데이터타입, display데이터타입 | |
37 | + */ | |
38 | + public enum DataType { | |
39 | + NULL(null, null) | |
40 | + , BYTE(Byte.class, 0) | |
41 | + , BOOL(Boolean.class, false) | |
42 | + , CHAR(Character.class, '\u0000') | |
43 | + , STRING(String.class, "") | |
44 | + , SHORT(Short.class, 0) | |
45 | + , INT(Integer.class, 0) | |
46 | + , DECIMAL(BigDecimal.class,0) | |
47 | + , LONG(Long.class, 0) | |
48 | + , FLOAT(Float.class, 0.0) | |
49 | + , DOUBLE(Double.class, 0.0) | |
50 | + , DATE(Date.class, "") | |
51 | + , DATETIME(Date.class, "") | |
52 | + , TIMESTAMP(Timestamp.class, "") | |
53 | + , ENTER(Character.class,'\n'); | |
54 | + | |
55 | + /** | |
56 | + * enum(열거형데이터)의 생성자 | |
57 | + * 1. 상수에 나열된 parameter와 형태가 똑같이 만들어줘야함. | |
58 | + * 2. 접근제한자는 private로만 다른 접근제한자는 허용하지 않음 | |
59 | + */ | |
60 | + private DataType (Class<?> javaType, Object iniValue) { | |
61 | + this.javaType = javaType; | |
62 | + this.initValue = iniValue; | |
63 | + } | |
64 | + | |
65 | + /** | |
66 | + * java데이터타입 | |
67 | + */ | |
68 | + final private Class<?> javaType; | |
69 | + | |
70 | + /** | |
71 | + * 초기값 | |
72 | + */ | |
73 | + final private Object initValue; | |
74 | + | |
75 | + public Class<?> getJavaType() { | |
76 | + return javaType; | |
77 | + } | |
78 | + public Object getInitValue() { | |
79 | + return initValue; | |
80 | + } | |
81 | + | |
82 | + | |
83 | + /** | |
84 | + * 데이터 타입 검사, DataType 조회 | |
85 | + */ | |
86 | + public static Map<DataType, String> getDataTypeList () { | |
87 | + Map<DataType, String> info = new LinkedHashMap<DataType, String>(); | |
88 | + info.put(STRING, "문자열"); | |
89 | + info.put(LONG, "정수"); | |
90 | + info.put(DOUBLE, "실수"); | |
91 | + info.put(DATE, "날짜"); | |
92 | + info.put(DATETIME,"날짜,시간"); | |
93 | + return info; | |
94 | + } | |
95 | + | |
96 | + | |
97 | + /** | |
98 | + * 데이터 타입 검사, DataType 조회 | |
99 | + */ | |
100 | + public static List<DataType> getDataTypeArray () { | |
101 | + List<DataType> info = new ArrayList<DataType>(); | |
102 | + info.add(STRING); | |
103 | + info.add(LONG); | |
104 | + info.add(DOUBLE); | |
105 | + info.add(DATE); | |
106 | + info.add(DATETIME); | |
107 | + info.add(BOOL); | |
108 | + return info; | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * 데이터 타입 검사, DataType 조회 | |
113 | + */ | |
114 | + public static DataType getDataType (String text) { | |
115 | + /* | |
116 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
117 | + * | |
118 | + * | |
119 | + * 전화번호 정규식*/ | |
120 | + String regExp = "^\\d{2,3}-\\d{3,4}-\\d{4}$"; | |
121 | + 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])"; | |
122 | + String regDate = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"; | |
123 | + | |
124 | + if(StringUtil.isEmpty(text)) { | |
125 | + return NULL; | |
126 | + } else if(CommonUtil.isLong(text)) { | |
127 | + /* | |
128 | + * 숫자로 변환 가능 하지만 앞에 '0'이 붙어 있으면 문자열로 봄 | |
129 | + * ex) 0102 -> String, 1102 -> Long | |
130 | + */ | |
131 | + if (text.length() > 1 && text.indexOf("0") == 0) { | |
132 | + return STRING; | |
133 | + } else { | |
134 | + return LONG; | |
135 | + } | |
136 | + }else if(CommonUtil.isDouble(text)) { | |
137 | + | |
138 | + return DOUBLE; | |
139 | + | |
140 | + } else if (CommonUtil.isDate(text)) { | |
141 | + /* | |
142 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
143 | + * | |
144 | + * | |
145 | + * 전화번호 정규식*/ | |
146 | + boolean expResult = Pattern.matches(regExp, text); | |
147 | + boolean dateTimeResult = Pattern.matches(regDateTime, text); | |
148 | + boolean dateResult = Pattern.matches(regDate, text); | |
149 | + | |
150 | + if(expResult) { | |
151 | + return STRING; | |
152 | + }else if(dateResult) { | |
153 | + return DATE; | |
154 | + }else { | |
155 | + return DATETIME; | |
156 | + } | |
157 | + | |
158 | + } else { | |
159 | + return STRING; | |
160 | + } | |
161 | + } | |
162 | + | |
163 | + /** | |
164 | + * 데이터 타입 검사, dbDataType 조회 | |
165 | + */ | |
166 | + public static String convertDbDataType (DataType datatype, Integer size) { | |
167 | + if (datatype == STRING) { | |
168 | + if (size == null || size <= MAX_VARCHAR_SIZE) { | |
169 | + return "varchar"; | |
170 | + } else { | |
171 | + return "text"; | |
172 | + } | |
173 | + } else if (datatype == DATE) { | |
174 | + return "date"; | |
175 | + } else if (datatype == DATETIME){ | |
176 | + return "datetime"; | |
177 | + } else if (datatype == LONG) { | |
178 | + return "bigint"; | |
179 | + } else if (datatype == DOUBLE) { | |
180 | + return "double"; | |
181 | + } else { | |
182 | + return "varchar"; | |
183 | + } | |
184 | + } | |
185 | + | |
186 | + /** | |
187 | + * 데이터 타입 검사, dbDataType -> javaType 조회 | |
188 | + */ | |
189 | + public static DataType convertDataTypeDbtoJava (DataType datatype, Integer size) { | |
190 | + | |
191 | + | |
192 | + return null; | |
193 | + } | |
194 | + | |
195 | + | |
196 | + /** | |
197 | + * 데이터 타입 형태로 값 변경 | |
198 | + */ | |
199 | + public static Object parse(DataType dataType, Object value) { | |
200 | + if (CommonUtil.isNull(value) == true) { | |
201 | + return null; | |
202 | + } | |
203 | + | |
204 | + Class<?> javaType = dataType.getJavaType(); | |
205 | + try { | |
206 | + if (javaType.getSimpleName().equals("Byte")) { | |
207 | + return Byte.parseByte(value.toString()); | |
208 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
209 | + return Boolean.parseBoolean(value.toString()); | |
210 | + } else if (javaType.getSimpleName().equals("Character")) { | |
211 | + return value.toString().toCharArray(); | |
212 | + } else if (javaType.getSimpleName().equals("String")) { | |
213 | + return value.toString(); | |
214 | + } else if (javaType.getSimpleName().equals("Short")) { | |
215 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
216 | + return Short.parseShort(value.toString()); | |
217 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
218 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
219 | + return Integer.parseInt(value.toString()); | |
220 | + } else if (javaType.getSimpleName().equals("Long")) { | |
221 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
222 | + return Long.parseLong(value.toString()); | |
223 | + } else if (javaType.getSimpleName().equals("Float")) { | |
224 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
225 | + return Float.parseFloat(value.toString()); | |
226 | + } else if (javaType.getSimpleName().equals("Double")) { | |
227 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
228 | + return Double.parseDouble(value.toString()); | |
229 | + } else { | |
230 | + return value; | |
231 | + } | |
232 | + } catch (Exception e) { | |
233 | + e.printStackTrace(); | |
234 | + return dataType.getInitValue(); | |
235 | + } | |
236 | + } | |
237 | + | |
238 | + /** | |
239 | + * 데이터 타입 형태로 값 변경 | |
240 | + */ | |
241 | + public static boolean parseCheck (DataType dataType, Object value) { | |
242 | + if (CommonUtil.isNull(value) == true) { | |
243 | + return false; | |
244 | + } | |
245 | + | |
246 | + Class<?> javaType = dataType.getJavaType(); | |
247 | + try { | |
248 | + if (javaType.getSimpleName().equals("Byte")) { | |
249 | + Byte.parseByte(value.toString()); | |
250 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
251 | + Boolean.parseBoolean(value.toString()); | |
252 | + } else if (javaType.getSimpleName().equals("Character")) { | |
253 | + value.toString().toCharArray(); | |
254 | + } else if (javaType.getSimpleName().equals("String")) { | |
255 | + value.toString(); | |
256 | + } else if (javaType.getSimpleName().equals("Short")) { | |
257 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
258 | + Short.parseShort(value.toString()); | |
259 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
260 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
261 | + Integer.parseInt(value.toString()); | |
262 | + } else if (javaType.getSimpleName().equals("Long")) { | |
263 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
264 | + Long.parseLong(value.toString()); | |
265 | + } else if (javaType.getSimpleName().equals("Float")) { | |
266 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
267 | + Float.parseFloat(value.toString()); | |
268 | + } else if (javaType.getSimpleName().equals("Double")) { | |
269 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
270 | + Double.parseDouble(value.toString()); | |
271 | + } | |
272 | + | |
273 | + return true; | |
274 | + } catch (Exception e) { | |
275 | + //e.printStackTrace(); | |
276 | + return false; | |
277 | + } | |
278 | + } | |
279 | + | |
280 | + } | |
281 | + | |
282 | + /** | |
283 | + * @author 최정우 | |
284 | + * @since 2019.11.20 | |
285 | + * | |
286 | + * 데이터 베이스 타입별 상수를 정의 | |
287 | + */ | |
288 | + public enum DatabaseType { | |
289 | + MYSQL("MySql", "com.mysql.jdbc.Driver", "jdbc:mysql://", "3306", "allowMultiQueries=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC") | |
290 | + , MARIADB("MariaDB", "org.mariadb.jdbc.Driver", "jdbc:mariadb://", "3306", "") | |
291 | + , ORACLE("Oracle", "oracle.jdbc.OracleDriver", "jdbc:oracle:thin:@", "1521", "") | |
292 | + , MSSQL("MS-SQL", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://", "1433", "") | |
293 | + , TIBERO("Tibero", "com.tmax.tibero.jdbc.TbDriver", "jdbc:tibero:thin:@", "8629", "") | |
294 | + , POSTGRESQL("PostgreSql", "org.postgresql.Driver", "jdbc:postgresql://", "5432", ""); | |
295 | + | |
296 | + private DatabaseType(String value, String driverClassName, String baseUrl, String defalutPort, String option) { | |
297 | + this.value = value; | |
298 | + this.driverClassName = driverClassName; | |
299 | + this.baseUrl = baseUrl; | |
300 | + this.defalutPort = defalutPort; | |
301 | + this.option = option; | |
302 | + } | |
303 | + | |
304 | + /** | |
305 | + * 한글값 | |
306 | + */ | |
307 | + final private String value; | |
308 | + | |
309 | + /** | |
310 | + * 드라이버 클래스 | |
311 | + */ | |
312 | + final private String driverClassName; | |
313 | + | |
314 | + /** | |
315 | + * 접속 URL | |
316 | + */ | |
317 | + final private String baseUrl; | |
318 | + | |
319 | + /** | |
320 | + * 기본 포트 | |
321 | + */ | |
322 | + final private String defalutPort; | |
323 | + | |
324 | + /** | |
325 | + * 접속 옵션 | |
326 | + */ | |
327 | + final private String option; | |
328 | + | |
329 | + | |
330 | + /** | |
331 | + * 한글값 조회 | |
332 | + */ | |
333 | + public String getValue () { | |
334 | + return value; | |
335 | + } | |
336 | + | |
337 | + /** | |
338 | + * 드라이버 클래스 조회 | |
339 | + */ | |
340 | + public String getDriverClassName () { | |
341 | + return driverClassName; | |
342 | + } | |
343 | + | |
344 | + /** | |
345 | + * 접속 URL 조회 | |
346 | + */ | |
347 | + public String getBaseUrl () { | |
348 | + return baseUrl; | |
349 | + } | |
350 | + | |
351 | + /** | |
352 | + * 기본 포트 조회 | |
353 | + */ | |
354 | + public String getDefaultPort () { | |
355 | + return defalutPort; | |
356 | + } | |
357 | + | |
358 | + /** | |
359 | + * 접속 옵션 조회 | |
360 | + */ | |
361 | + public String getOption () { | |
362 | + return option; | |
363 | + } | |
364 | + | |
365 | + /** | |
366 | + * 접속 URL 조회 | |
367 | + */ | |
368 | + public String getUrl (ConnectionDB connectionDB) { | |
369 | + StringBuilder builder = new StringBuilder(); | |
370 | + if ((this == ORACLE || this == TIBERO ) && connectionDB.isGroupDatabase() == false) { | |
371 | + builder.append(this.baseUrl); | |
372 | + builder.append(connectionDB.getConectIp()); | |
373 | + builder.append(":"); | |
374 | + builder.append(connectionDB.getConectPort()); | |
375 | + builder.append(":"); | |
376 | + builder.append(connectionDB.getDatabaseNm()); | |
377 | + } else { | |
378 | + builder.append(this.baseUrl); | |
379 | + builder.append(connectionDB.getConectIp()); | |
380 | + builder.append(":"); | |
381 | + builder.append(connectionDB.getConectPort()); | |
382 | + if(this == MSSQL) { | |
383 | + builder.append(";databaseName="); | |
384 | + | |
385 | + }else { | |
386 | + builder.append("/"); | |
387 | + } | |
388 | + builder.append(connectionDB.getDatabaseNm()); | |
389 | + if (this == MYSQL) { | |
390 | + builder.append("?"); | |
391 | + builder.append(this.option.replaceAll("&", "&")); | |
392 | + }else if(this == POSTGRESQL) { | |
393 | + builder.append("?"); | |
394 | + builder.append("currentSchema="+connectionDB.getSchemaNm()); | |
395 | + } | |
396 | + } | |
397 | + | |
398 | + return builder.toString(); | |
399 | + } | |
400 | + | |
401 | + /** | |
402 | + * 접속 URL 조회 | |
403 | + */ | |
404 | + public String getUrl (String ip, String port, String databaseName, boolean isGroupDatabase, String option) { | |
405 | + StringBuilder builder = new StringBuilder(); | |
406 | + if ((this == ORACLE || this == TIBERO ) && isGroupDatabase == false) { | |
407 | + builder.append(this.baseUrl); | |
408 | + builder.append(ip); | |
409 | + builder.append(":"); | |
410 | + builder.append(port); | |
411 | + builder.append(":"); | |
412 | + builder.append(databaseName); | |
413 | + } else { | |
414 | + builder.append(this.baseUrl); | |
415 | + builder.append(ip); | |
416 | + builder.append(":"); | |
417 | + builder.append(port); | |
418 | + builder.append("/"); | |
419 | + builder.append(databaseName); | |
420 | + } | |
421 | + | |
422 | + if (StringUtil.isEmpty(option) == false) { | |
423 | + builder.append("?"); | |
424 | + option.replaceAll("&", "&"); | |
425 | + builder.append(option); | |
426 | + } | |
427 | + | |
428 | + | |
429 | + return builder.toString(); | |
430 | + } | |
431 | + | |
432 | + /** | |
433 | + * 데이터 베이스 타입별 상수 목록 조회 | |
434 | + */ | |
435 | + public static Map<DatabaseType, String> getDatabaseTypeList () { | |
436 | + Map<DatabaseType, String> info = new LinkedHashMap<DatabaseType, String>(); | |
437 | + DatabaseType[] array = DatabaseType.values(); | |
438 | + for (int i = 0; i < array.length; i++) { | |
439 | + info.put(array[i], array[i].getValue()); | |
440 | + } | |
441 | + return info; | |
442 | + } | |
443 | + | |
444 | + /** | |
445 | + * 데이터 베이스 타입별 상수 목록 조회 | |
446 | + */ | |
447 | + public static Map<DatabaseType, Map<String, String>> getDatabaseTypeInfoList () { | |
448 | + Map<DatabaseType, Map<String, String>> info = new LinkedHashMap<DatabaseType, Map<String, String>>(); | |
449 | + DatabaseType[] array = DatabaseType.values(); | |
450 | + for (int i = 0; i < array.length; i++) { | |
451 | + Map<String, String> detailInfo = new HashMap<String, String>(); | |
452 | + detailInfo.put("key", array[i].toString()); | |
453 | + detailInfo.put("value", array[i].getValue()); | |
454 | + detailInfo.put("driverClassName", array[i].getDriverClassName()); | |
455 | + detailInfo.put("baseUrl", array[i].getBaseUrl()); | |
456 | + detailInfo.put("defalutPort", array[i].getDefaultPort()); | |
457 | + detailInfo.put("option", array[i].getOption()); | |
458 | + info.put(array[i], detailInfo); | |
459 | + } | |
460 | + return info; | |
461 | + } | |
462 | + | |
463 | + } | |
464 | + | |
465 | + | |
466 | + /** | |
467 | + * @author 최정우 | |
468 | + * @since 2019.11.13 | |
469 | + * | |
470 | + * SPMiner에서 등록되는 파일 타입과, 해당 파일 타입의 등록가능한 확장자를 정의한 상수 Class 입니다. | |
471 | + * 첨부파일, 이미지파일, 데이터 셋 파일 순서입니다. | |
472 | + */ | |
473 | + public enum FileType { | |
474 | + 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")) | |
475 | + , IMG_FILE(Arrays.asList("bmp","jpg","gif","png","jpeg")) | |
476 | + , DATASET_FILE(Arrays.asList("xls","xlsx","csv")); | |
477 | + | |
478 | + private FileType(List<String> extensions) { | |
479 | + this.extensions = extensions; | |
480 | + } | |
481 | + | |
482 | + /** | |
483 | + * 확장자 목록 | |
484 | + */ | |
485 | + final private List<String> extensions; | |
486 | + | |
487 | + /** | |
488 | + * 확장자 목록 조회 | |
489 | + */ | |
490 | + public List<String> getExtensions () { | |
491 | + return extensions; | |
492 | + } | |
493 | + } | |
494 | + | |
495 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/ScedulerService.java
... | ... | @@ -0,0 +1,28 @@ |
1 | +package com.takensoft.taken_bi_manager.controller; | |
2 | + | |
3 | +import org.springframework.beans.factory.InitializingBean; | |
4 | +import org.springframework.beans.factory.annotation.Autowired; | |
5 | +import org.springframework.stereotype.Component; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
8 | +import com.takensoft.taken_bi_manager.user.member.servie.MemberService; | |
9 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
10 | + | |
11 | +@Component | |
12 | +public class ScedulerService implements InitializingBean { | |
13 | + | |
14 | + @Autowired | |
15 | + private MemberService memberService; | |
16 | + | |
17 | + @Override | |
18 | + public void afterPropertiesSet() throws Exception { | |
19 | + // TODO Auto-generated method stub | |
20 | + /* Member member = new Member(); | |
21 | + member.setUserId("admin"); | |
22 | + member.setUserPassword("qwer1234!"); | |
23 | + CustomeResultMap map = memberService.userLogin(member); | |
24 | + System.out.print(map.getCheckMessage().getMessage()); | |
25 | + */ | |
26 | + } | |
27 | + | |
28 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/data/util/DataTableConvert.java
... | ... | @@ -0,0 +1,99 @@ |
1 | +package com.takensoft.taken_bi_manager.data.util; | |
2 | + | |
3 | + | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.List; | |
6 | +import java.util.Map; | |
7 | + | |
8 | +import com.takensoft.taken_bi_manager.common.file.vo.FileInfo; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
10 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
12 | + | |
13 | +/** | |
14 | + * @author 김성원 | |
15 | + * @since 2024.01.09 | |
16 | + * | |
17 | + * 파일, DB, API, Dataset 간의 변환을 위한 클래스 | |
18 | + */ | |
19 | +public class DataTableConvert { | |
20 | + | |
21 | + | |
22 | + /** | |
23 | + * @author 김성원 | |
24 | + * @since 2024.01.12 | |
25 | + * | |
26 | + * 파일 -> 데이터셋 변환(엑셀, CSV, TEXT, JSON, XML) | |
27 | + */ | |
28 | + public static Dataset filetoDataset(FileInfo fileInfo) { | |
29 | + | |
30 | + // 데이터 확장자 | |
31 | + String dataType = fileInfo.getFileFom(); | |
32 | + | |
33 | + | |
34 | + | |
35 | + | |
36 | + return null; | |
37 | + } | |
38 | + | |
39 | + | |
40 | + /** | |
41 | + * @author 김성원 | |
42 | + * @since 2024.01.12 | |
43 | + * | |
44 | + * List<Map<Object, String>> -> Dataset | |
45 | + */ | |
46 | + public static DataTable listMaptoDataset(List<Map<String, Object>> mapData) { | |
47 | + | |
48 | + // 데이터 테이블 생성 | |
49 | + DataTable dataTable = new DataTable(); | |
50 | + | |
51 | + // 헤더정보 리스트 | |
52 | + List<String> header = new ArrayList<>(); | |
53 | + | |
54 | + // 컬럼 데이터 리스트 | |
55 | + List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
56 | + | |
57 | + int manxSize = 0; | |
58 | + | |
59 | + // 제일큰 ROW의 헤더값 가져오기 | |
60 | + for(Map<String, Object> mapItm : mapData) { | |
61 | + if(manxSize < mapItm.entrySet().size()) { | |
62 | + manxSize = mapItm.entrySet().size(); | |
63 | + header.clear(); | |
64 | + for (Map.Entry<String, Object> elem : mapItm.entrySet()) { | |
65 | + header.add(elem.getKey()); | |
66 | + } | |
67 | + } | |
68 | + } | |
69 | + | |
70 | + // row 데이터 생성 | |
71 | + for (Map<String, Object> temp : mapData) { | |
72 | + List<Object> listTemp = new ArrayList(); | |
73 | + for(String head : header) { | |
74 | + if(temp.get(head) == null) { | |
75 | + listTemp.add(null); | |
76 | + }else { | |
77 | + listTemp.add(temp.get(head)); | |
78 | + } | |
79 | + } | |
80 | + dataTable.getRowData().add(listTemp); | |
81 | + } | |
82 | + | |
83 | + // 컬럼명 세팅 | |
84 | + for(String head : header) { | |
85 | + ColumnData columnData = new ColumnData(); | |
86 | + // 헤더명 (컬럼명) | |
87 | + columnData.setColumnNm(head); | |
88 | + columnData.setOrginlColumnNm(head); | |
89 | + columnData.setDisplyColumnNm(head); | |
90 | + columnDatas.add(columnData); | |
91 | + } | |
92 | + | |
93 | + // DataTable의 컬럼정보 세팅 | |
94 | + dataTable.setColumnDatas(columnDatas); | |
95 | + | |
96 | + return dataTable; | |
97 | + } | |
98 | + | |
99 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/Column.java
... | ... | @@ -0,0 +1,84 @@ |
1 | +package com.takensoft.taken_bi_manager.data.vo; | |
2 | + | |
3 | +import java.io.Serializable; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType; | |
6 | + | |
7 | +import lombok.Getter; | |
8 | +import lombok.Setter; | |
9 | + | |
10 | +/** | |
11 | + * @author 김성원 | |
12 | + * @since 2024.01.02 | |
13 | + * | |
14 | + * Columns Domain 입니다. | |
15 | + */ | |
16 | +@Getter | |
17 | +@Setter | |
18 | +public class Column implements Serializable { | |
19 | + | |
20 | + /** | |
21 | + * 시리얼 버전 | |
22 | + */ | |
23 | + private static final long serialVersionUID = 1L; | |
24 | + | |
25 | + | |
26 | + // 컬럼 ID | |
27 | + private String columnId; | |
28 | + | |
29 | + // 컬럼명 | |
30 | + private String columnNm; | |
31 | + | |
32 | + // 표츌 컬럼명 | |
33 | + private String displyColumnNm; | |
34 | + | |
35 | + // 원본데이터 컬럼명 | |
36 | + private String orginlColumnNm; | |
37 | + | |
38 | + // dataset id(fk) | |
39 | + private String datasetId; | |
40 | + | |
41 | + // 데이터 타입 | |
42 | + private DataType dataTy; | |
43 | + | |
44 | + // 데이터 길이 | |
45 | + private long dataSize; | |
46 | + | |
47 | + // 컬럼순서 | |
48 | + private int ordr; | |
49 | + | |
50 | + // pk여부 | |
51 | + private boolean pkAt; | |
52 | + | |
53 | + // 고유값 여부 | |
54 | + private boolean uniqeAt; | |
55 | + | |
56 | + // 자동증가 여부 | |
57 | + private boolean autoIncrementAt; | |
58 | + | |
59 | + // 컬럼명 표준화 여부 | |
60 | + private boolean columnStdizAt; | |
61 | + | |
62 | + // 도메인 표준화 여부 | |
63 | + private boolean domnStdizAt; | |
64 | + | |
65 | + // 도메인 코드 | |
66 | + private String domnCode; | |
67 | + | |
68 | + // 사용여부 | |
69 | + private boolean useAt; | |
70 | + | |
71 | + | |
72 | + | |
73 | + | |
74 | + | |
75 | + | |
76 | + | |
77 | + | |
78 | + | |
79 | + | |
80 | + | |
81 | + | |
82 | + | |
83 | + | |
84 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnData.java
... | ... | @@ -0,0 +1,154 @@ |
1 | +package com.takensoft.taken_bi_manager.data.vo; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.Serializable; | |
6 | +import java.sql.Timestamp; | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.Date; | |
9 | +import java.util.List; | |
10 | + | |
11 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType; | |
12 | +import com.takensoft.taken_bi_manager.meta.term.vo.StandardTermSearch; | |
13 | + | |
14 | +import lombok.Getter; | |
15 | +import lombok.Setter; | |
16 | + | |
17 | + | |
18 | +/** | |
19 | + * @author 김성원 | |
20 | + * @since 2024.01.04 | |
21 | + * | |
22 | + * 열(Column) 데이터의 정보를 담는 Class 입니다. | |
23 | + */ | |
24 | +@Getter | |
25 | +@Setter | |
26 | +public class ColumnData extends Column implements Serializable { | |
27 | + | |
28 | + public ColumnData () {} | |
29 | + | |
30 | + public ColumnData (String originColumnName) { | |
31 | + super.setOrginlColumnNm(originColumnName); | |
32 | + } | |
33 | + | |
34 | + public ColumnData (String originColumnName, String displayColumnName, DataType dataType) { | |
35 | + super.setOrginlColumnNm(originColumnName); | |
36 | + super.setDisplyColumnNm(originColumnName); | |
37 | + super.setDataTy(dataType); | |
38 | + } | |
39 | + | |
40 | + public ColumnData (String originColumnName, String displayColumnName, DataType dataType, boolean isPrimary) { | |
41 | + super.setOrginlColumnNm(originColumnName); | |
42 | + super.setDisplyColumnNm(originColumnName); | |
43 | + super.setDataTy(dataType); | |
44 | + super.setPkAt(isPrimary); | |
45 | + } | |
46 | + | |
47 | + public ColumnData (String originColumnName, String displayColumnName, String columnName, DataType dataType) { | |
48 | + super.setOrginlColumnNm(originColumnName); | |
49 | + super.setDisplyColumnNm(displayColumnName); | |
50 | + super.setColumnNm(columnName); | |
51 | + super.setDataTy(dataType); | |
52 | + } | |
53 | + | |
54 | + /** | |
55 | + * 시리얼 버전 | |
56 | + */ | |
57 | + private static final long serialVersionUID = 1L; | |
58 | + | |
59 | + | |
60 | + /** | |
61 | + * 테이블 명 | |
62 | + */ | |
63 | + private String databaseNm; | |
64 | + | |
65 | + | |
66 | + /** | |
67 | + * 테이블 명 | |
68 | + */ | |
69 | + private String tableNm; | |
70 | + | |
71 | + /** | |
72 | + * 데이터 베이스에 생성될 데이터 타입 | |
73 | + */ | |
74 | + private String dbDataType; | |
75 | + | |
76 | + /** | |
77 | + * 표준 용어 검색 Box Display 여부 (client단에서만 사용) | |
78 | + */ | |
79 | + private boolean isSearching; | |
80 | + | |
81 | + /** | |
82 | + * 표준 용어 검색된 목록 Display 여부 (client단에서만 사용) | |
83 | + */ | |
84 | + private boolean isSearchListView; | |
85 | + | |
86 | + /** | |
87 | + * 컬럼 유니크 옵션 | |
88 | + */ | |
89 | + private boolean isUniq; | |
90 | + | |
91 | + /** | |
92 | + * 해당 컬럼의 표준용어 검색 목록 중 사용하기 위해 선택 중인 표중용어 정보 (client단에서만 사용) | |
93 | + */ | |
94 | + private StandardTermSearch selectingStandardTerm; | |
95 | + | |
96 | + /** | |
97 | + * 해당 컬럼의 표준용어 검색 목록 (client단에서만 사용) | |
98 | + */ | |
99 | + private List<StandardTermSearch> standardTermSearchList = new ArrayList<StandardTermSearch>(); | |
100 | + | |
101 | + /** | |
102 | + * 컬럼 유니크 옵션 | |
103 | + */ | |
104 | + private boolean isView; | |
105 | + | |
106 | + | |
107 | + public void cellValuesClear() { | |
108 | + // this.columnValues.clear(); | |
109 | + } | |
110 | + | |
111 | + public void dataTyDefine(Object data) { | |
112 | + if(data == null ) { | |
113 | + this.setDataTy(DataType.NULL); | |
114 | + }else if(data instanceof Boolean) { | |
115 | + this.setDataTy(DataType.BOOL); | |
116 | + }else if(data instanceof Character) { | |
117 | + this.setDataTy(DataType.CHAR); | |
118 | + }else if(data instanceof Short) { | |
119 | + this.setDataTy(DataType.SHORT); | |
120 | + }else if(data instanceof Integer) { | |
121 | + this.setDataTy(DataType.INT); | |
122 | + }else if(data instanceof Long) { | |
123 | + this.setDataTy(DataType.LONG); | |
124 | + }else if(data instanceof Float) { | |
125 | + this.setDataTy(DataType.FLOAT); | |
126 | + }else if(data instanceof Double) { | |
127 | + this.setDataTy(DataType.DOUBLE); | |
128 | + }else if(data instanceof Timestamp) { | |
129 | + this.setDataTy(DataType.TIMESTAMP); | |
130 | + }else if(data instanceof Date) { | |
131 | + this.setDataTy(DataType.DATETIME); | |
132 | + }else if(data instanceof Character) { | |
133 | + this.setDataTy(DataType.ENTER); | |
134 | + } | |
135 | + } | |
136 | + | |
137 | + /******************************************************************* 추가 *******************************************************************/ | |
138 | + | |
139 | + /** | |
140 | + * 열의 합계 | |
141 | + */ | |
142 | + private Object sum; | |
143 | + | |
144 | + public Object getSum() { | |
145 | + return sum; | |
146 | + } | |
147 | + | |
148 | + public void setSum(Object sum) { | |
149 | + this.sum = sum; | |
150 | + } | |
151 | + | |
152 | + /******************************************************************* 추가 *******************************************************************/ | |
153 | + | |
154 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnValue.java
... | ... | @@ -0,0 +1,107 @@ |
1 | +package com.takensoft.taken_bi_manager.data.vo; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.Serializable; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType; | |
8 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
9 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
10 | + | |
11 | + | |
12 | +/** | |
13 | + * @author 최정우 | |
14 | + * @since 2019.11.13 | |
15 | + * | |
16 | + * 열(Column) 데이터(데이터목록)를 담는 Class 입니다. | |
17 | + */ | |
18 | +public class ColumnValue implements Serializable , Comparable<ColumnValue> { | |
19 | + | |
20 | + /** | |
21 | + * 시리얼 버전 | |
22 | + */ | |
23 | + private static final long serialVersionUID = 1L; | |
24 | + | |
25 | + /** | |
26 | + * 컬럼의 값 | |
27 | + */ | |
28 | + private Object value; | |
29 | + | |
30 | + /** | |
31 | + * 해당 열 데이터의 데이터 타입 | |
32 | + */ | |
33 | + private DataType dataType; | |
34 | + | |
35 | + /** | |
36 | + * 중복제거 시, 중복되는 갯수 | |
37 | + */ | |
38 | + private int count; | |
39 | + | |
40 | + public ColumnValue() { | |
41 | + | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * 초기화 | |
46 | + */ | |
47 | + public ColumnValue(Object value,DataType dataType) { | |
48 | + this.value = value; | |
49 | + this.dataType = dataType; | |
50 | + } | |
51 | + | |
52 | + | |
53 | + public ColumnValue(Object value,DataType dataType, int count ) { | |
54 | + this.value = value; | |
55 | + this.dataType = dataType; | |
56 | + this.count = count; | |
57 | + } | |
58 | + | |
59 | + public Object getValue() { | |
60 | + return value; | |
61 | + } | |
62 | + | |
63 | + public void setValue(Object value) { | |
64 | + this.value = value; | |
65 | + } | |
66 | + | |
67 | + public DataType getDataType() { | |
68 | + return dataType; | |
69 | + } | |
70 | + | |
71 | + public void setDataType(DataType dataType) { | |
72 | + this.dataType = dataType; | |
73 | + } | |
74 | + | |
75 | + public int getCount() { | |
76 | + return count; | |
77 | + } | |
78 | + | |
79 | + public void setCount(int count) { | |
80 | + this.count = count; | |
81 | + } | |
82 | + | |
83 | + @Override | |
84 | + public int compareTo(ColumnValue columnValue) { | |
85 | + | |
86 | + int result = 0; | |
87 | + if (this.value == null && columnValue.getValue() != null) { | |
88 | + result = -1; | |
89 | + } else if (this.value != null && columnValue.getValue() == null) { | |
90 | + result = 1; | |
91 | + } else if (this.value != null && columnValue.getValue() != null) { | |
92 | + if(this.dataType.equals(DataType.STRING)) { | |
93 | + result = StringUtil.toString(this.value).compareTo(StringUtil.toString(columnValue.getValue())); | |
94 | + } else if(this.dataType.equals(DataType.DOUBLE)) { | |
95 | + result = Double.compare(CommonUtil.parseDouble(this.value), CommonUtil.parseDouble(columnValue.getValue())); | |
96 | + }else if(this.dataType.equals(DataType.LONG)) { | |
97 | + result = Double.compare(CommonUtil.parseDouble(this.value), CommonUtil.parseDouble(columnValue.getValue())); | |
98 | + //result = Long.compare(Long.parseLong(this.value.toString()), Long.parseLong(columnValue.getValue().toString())); | |
99 | + } | |
100 | + } else {//둘다 null | |
101 | + result = 0; | |
102 | + } | |
103 | + | |
104 | + return result; | |
105 | + } | |
106 | + | |
107 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/DataTable.java
... | ... | @@ -0,0 +1,170 @@ |
1 | +package com.takensoft.taken_bi_manager.data.vo; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.LinkedHashMap; | |
5 | +import java.util.List; | |
6 | +import java.util.Map; | |
7 | + | |
8 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
9 | + | |
10 | +import lombok.Getter; | |
11 | +import lombok.Setter; | |
12 | + | |
13 | +@Getter | |
14 | +@Setter | |
15 | +public class DataTable extends Dataset{ | |
16 | + | |
17 | + /** | |
18 | + * 시리얼 버전 | |
19 | + */ | |
20 | + private static final long serialVersionUID = 1L; | |
21 | + | |
22 | + public DataTable () {}; | |
23 | + | |
24 | + public DataTable (Dataset parents) { | |
25 | + super.setDatasetId(parents.getDatasetId()); | |
26 | + super.setDatasetSj(parents.getDatasetSj()); | |
27 | + super.setDbConectId(parents.getDbConectId()); | |
28 | + super.setTableNm(parents.getTableNm()); | |
29 | + super.setTableNmKr(parents.getTableNmKr()); | |
30 | + super.setCreatTableAt(parents.isCreatTableAt()); | |
31 | + super.setCreatDt(parents.getCreatDt()); | |
32 | + super.setUpdtDt(parents.getUpdtDt()); | |
33 | + super.setDatasetPostId(parents.getDatasetPostId()); | |
34 | + super.setStdizColumnAt(parents.isStdizColumnAt()); | |
35 | + super.setStdizDomnAt(parents.isStdizDomnAt()); | |
36 | + super.setStdizTableNm(parents.isStdizTableNm()); | |
37 | + super.setQuery(parents.getQuery()); | |
38 | + }; | |
39 | + | |
40 | + | |
41 | + /** | |
42 | + * 열 기준 데이터 정보 (헤더 정보 + 열별 데이터 목록) | |
43 | + */ | |
44 | + private List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
45 | + | |
46 | + /** | |
47 | + * 데이터(행,열) | |
48 | + */ | |
49 | + private List<List<Object>> rowData = new ArrayList<List<Object>>(); | |
50 | + | |
51 | + /** | |
52 | + * 열 기준 데이터 정보 (헤더 정보 + 열별 데이터 목록) | |
53 | + */ | |
54 | + private List<ColumnData> changeColumnDatas = null; | |
55 | + | |
56 | + /** | |
57 | + * primary key 존재 여부 | |
58 | + */ | |
59 | + private boolean isExistPrimary = false; | |
60 | + | |
61 | + /** | |
62 | + * 헤더(컬럼)데이터를 현재 생성된 rowData 인스턴스에 0번째Index에 추가했는지에 대한 여부 | |
63 | + */ | |
64 | + private boolean isRowDataHeaderAdd = false; | |
65 | + | |
66 | + /** | |
67 | + * 헤더(컬럼)데이터의 columnName이 메모리상에서 변경된는 지에 대한 여부 | |
68 | + */ | |
69 | + private boolean isColumnNameChange = false; | |
70 | + | |
71 | + /** | |
72 | + * 데이터(행,열)의 컬럼인 Row의 Index | |
73 | + */ | |
74 | + private int rowDataColumnIndex; | |
75 | + | |
76 | + /** | |
77 | + * 데이터(행,열)의 Row 시작 Index | |
78 | + */ | |
79 | + private int startRowIndex; | |
80 | + | |
81 | + /** | |
82 | + * 데이터(행,열)의 Cell 시작 Index | |
83 | + */ | |
84 | + private int startCellIndex; | |
85 | + | |
86 | + /** | |
87 | + * 총 개시물 수 | |
88 | + */ | |
89 | + private int totalRows; | |
90 | + | |
91 | + /** | |
92 | + * 데이터 편집 결과 메세지(화면에서만 쓰임) | |
93 | + */ | |
94 | + private List<Map<String, String>> editResultList = new ArrayList<Map<String, String>>(); | |
95 | + | |
96 | + /** | |
97 | + * DataTable 생성 관련 메세지 | |
98 | + */ | |
99 | + private CheckMessage checkMessage = new CheckMessage(); | |
100 | + | |
101 | + | |
102 | + public void cellValuesClear() { | |
103 | + for (int i = 0; i < columnDatas.size(); i++) { | |
104 | + columnDatas.get(i).cellValuesClear(); | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + /** | |
109 | + * 컬럼 데이터 값 저장 | |
110 | + */ | |
111 | + /* | |
112 | + public void setColumnValues(List<LinkedHashMap<String,Object>> datas) { | |
113 | + this.setTotalRows(datas.size()); | |
114 | + for(LinkedHashMap<String,Object> temp : datas) { | |
115 | + for(ColumnData columnData : this.columnDatas) { | |
116 | + columnData.getColumnValues().add(new ColumnValue(temp.get(columnData.getColumnNm()),columnData.getDataTy())); | |
117 | + } | |
118 | + } | |
119 | + } | |
120 | + */ | |
121 | + | |
122 | + /** | |
123 | + * 쿼리 생성(DB포함) | |
124 | + */ | |
125 | + public void setQuery() { | |
126 | + StringBuilder builder = new StringBuilder(); | |
127 | + builder.append("SELECT \n"); | |
128 | + for (int i = 0; i < this.getColumnDatas().size(); i++) { | |
129 | + builder.append("\t"); | |
130 | + if (i > 0) { | |
131 | + builder.append(", "); | |
132 | + } | |
133 | + builder.append(this.getColumnDatas().get(i).getColumnNm()); | |
134 | + builder.append("\n"); | |
135 | + } | |
136 | + builder.append("FROM \n\t"); | |
137 | + builder.append(this.getDatabaseNm()); | |
138 | + builder.append("."); | |
139 | + builder.append(this.getTableNm()); | |
140 | + builder.append("\n"); | |
141 | + | |
142 | + this.setQuery(builder.toString()); | |
143 | + } | |
144 | + | |
145 | + /** | |
146 | + * 쿼리생성 | |
147 | + */ | |
148 | + public String makeQuery() { | |
149 | + StringBuilder builder = new StringBuilder(); | |
150 | + builder.append("SELECT \n"); | |
151 | + for (int i = 0; i < this.getColumnDatas().size(); i++) { | |
152 | + builder.append("\t"); | |
153 | + if (i > 0) { | |
154 | + builder.append(", "); | |
155 | + } | |
156 | + builder.append(this.getColumnDatas().get(i).getColumnNm()); | |
157 | + builder.append("\n"); | |
158 | + } | |
159 | + builder.append("FROM \n\t"); | |
160 | + builder.append(this.getTableNm()); | |
161 | + builder.append("\n"); | |
162 | + | |
163 | + this.setQuery(builder.toString()); | |
164 | + | |
165 | + return builder.toString(); | |
166 | + | |
167 | + } | |
168 | + | |
169 | + | |
170 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/Dataset.java
... | ... | @@ -0,0 +1,79 @@ |
1 | +package com.takensoft.taken_bi_manager.data.vo; | |
2 | + | |
3 | +import java.io.Serializable; | |
4 | +import java.sql.Timestamp; | |
5 | + | |
6 | +import com.takensoft.taken_bi_manager.common.vo.CommonVO; | |
7 | + | |
8 | +import lombok.Getter; | |
9 | +import lombok.Setter; | |
10 | + | |
11 | +@Getter | |
12 | +@Setter | |
13 | +/** | |
14 | + * @author 김성원 | |
15 | + * @since 2024.01.03 | |
16 | + * | |
17 | + * Dataset Domain 입니다. | |
18 | + */ | |
19 | +public class Dataset extends CommonVO implements Serializable { | |
20 | + | |
21 | + /** | |
22 | + * 시리얼 버전 | |
23 | + */ | |
24 | + private static final long serialVersionUID = 1L; | |
25 | + | |
26 | + | |
27 | + // 데이터셋 아이디 | |
28 | + private String datasetId; | |
29 | + | |
30 | + // 데이터셋 명 | |
31 | + private String datasetSj; | |
32 | + | |
33 | + // 테이블 명 | |
34 | + private String tableNm; | |
35 | + | |
36 | + // 한글 테이블 명 | |
37 | + private String tableNmKr; | |
38 | + | |
39 | + // 테이블 생성여부 | |
40 | + private boolean creatTableAt; | |
41 | + | |
42 | + // 테이블명 표준화 여부 | |
43 | + private boolean stdizTableNm; | |
44 | + | |
45 | + // 컬럼명 표준화 여부 | |
46 | + private boolean stdizColumnAt; | |
47 | + | |
48 | + // 도메인 표준화 여부 | |
49 | + private boolean stdizDomnAt; | |
50 | + | |
51 | + // 데이터 게시물 ID(FK) | |
52 | + private String datasetPostId; | |
53 | + | |
54 | + // 생성일 | |
55 | + private Timestamp creatDt; | |
56 | + | |
57 | + // 생성자ID | |
58 | + private String creatId; | |
59 | + | |
60 | + // 수정일 | |
61 | + private Timestamp updtDt; | |
62 | + | |
63 | + // 수정자 ID | |
64 | + private String updtId; | |
65 | + | |
66 | + // 커넥션 ID | |
67 | + private String dbConectId; | |
68 | + | |
69 | + // 사용쿼리 | |
70 | + private String query; | |
71 | + | |
72 | + // 데이터베이스명 | |
73 | + private String databaseNm; | |
74 | + | |
75 | + | |
76 | + | |
77 | + | |
78 | + | |
79 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/term/vo/StandardTerm.java
... | ... | @@ -0,0 +1,264 @@ |
1 | +package com.takensoft.taken_bi_manager.meta.term.vo; | |
2 | + | |
3 | + | |
4 | +import java.io.Serializable; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.List; | |
7 | + | |
8 | +import com.takensoft.taken_bi_manager.data.vo.Column; | |
9 | + | |
10 | + | |
11 | + | |
12 | +/** | |
13 | + * @author 최정우 | |
14 | + * @since 2019.11.13 | |
15 | + * | |
16 | + * StandardTerm(표준용어) Domain 입니다. | |
17 | + */ | |
18 | +public class StandardTerm implements Serializable { | |
19 | + | |
20 | + | |
21 | + /** | |
22 | + * 시리얼 버전 | |
23 | + */ | |
24 | + private static final long serialVersionUID = 1L; | |
25 | + | |
26 | + /**************************** Domain 원본 ****************************/ | |
27 | + | |
28 | + /** | |
29 | + * 표준용어 SEQ | |
30 | + */ | |
31 | + private long termSeq; | |
32 | + | |
33 | + /** | |
34 | + * 표준용어 ID (SEQ여러개 포함) | |
35 | + */ | |
36 | + private String termId; | |
37 | + | |
38 | + /** | |
39 | + * 표준용어 한글 | |
40 | + */ | |
41 | + private String korean; | |
42 | + | |
43 | + /** | |
44 | + * 표준용어 영어 | |
45 | + */ | |
46 | + private String english; | |
47 | + | |
48 | + /** | |
49 | + * 표준용어 영어 약어 | |
50 | + */ | |
51 | + private String englishAbbr; | |
52 | + | |
53 | + /** | |
54 | + * 용어 설명 | |
55 | + */ | |
56 | + private String termDc; | |
57 | + | |
58 | + /** | |
59 | + * 표준용어 사용 시스템 | |
60 | + */ | |
61 | + private String usingSystem; | |
62 | + | |
63 | + /** | |
64 | + * 생성일 | |
65 | + */ | |
66 | + private String createDate; | |
67 | + | |
68 | + /** | |
69 | + * 생성자 | |
70 | + */ | |
71 | + private String createId; | |
72 | + | |
73 | + /** | |
74 | + * 수정일 | |
75 | + */ | |
76 | + private String updateDate; | |
77 | + | |
78 | + /** | |
79 | + * 수정자 | |
80 | + */ | |
81 | + private String updateId; | |
82 | + | |
83 | + /** | |
84 | + * 사용여부 | |
85 | + */ | |
86 | + private boolean isUse; | |
87 | + | |
88 | + /** | |
89 | + * 표준 여부 | |
90 | + */ | |
91 | + private boolean isStandard; | |
92 | + | |
93 | + /** | |
94 | + * 행안부 표준 여부 | |
95 | + */ | |
96 | + private boolean isMinistryStandard; | |
97 | + | |
98 | + /** | |
99 | + * 한 용어에 대한 순서 (히스토리 Index) | |
100 | + */ | |
101 | + private int orders; | |
102 | + | |
103 | + /** | |
104 | + * 한 용어에 대한 검색 횟수 | |
105 | + */ | |
106 | + private long searchCount = 0; | |
107 | + | |
108 | + public long getTermSeq() { | |
109 | + return termSeq; | |
110 | + } | |
111 | + | |
112 | + public void setTermSeq(long termSeq) { | |
113 | + this.termSeq = termSeq; | |
114 | + } | |
115 | + | |
116 | + public String getTermId() { | |
117 | + return termId; | |
118 | + } | |
119 | + | |
120 | + public void setTermId(String termId) { | |
121 | + this.termId = termId; | |
122 | + } | |
123 | + | |
124 | + public String getKorean() { | |
125 | + return korean; | |
126 | + } | |
127 | + | |
128 | + public void setKorean(String korean) { | |
129 | + this.korean = korean; | |
130 | + } | |
131 | + | |
132 | + public String getEnglish() { | |
133 | + return english; | |
134 | + } | |
135 | + | |
136 | + public void setEnglish(String english) { | |
137 | + this.english = english; | |
138 | + } | |
139 | + | |
140 | + public String getEnglishAbbr() { | |
141 | + return englishAbbr; | |
142 | + } | |
143 | + | |
144 | + public void setEnglishAbbr(String englishAbbr) { | |
145 | + this.englishAbbr = englishAbbr; | |
146 | + } | |
147 | + | |
148 | + public String getTermDc() { | |
149 | + return termDc; | |
150 | + } | |
151 | + | |
152 | + public void setTermDc(String termDc) { | |
153 | + this.termDc = termDc; | |
154 | + } | |
155 | + | |
156 | + public String getUsingSystem() { | |
157 | + return usingSystem; | |
158 | + } | |
159 | + | |
160 | + public void setUsingSystem(String usingSystem) { | |
161 | + this.usingSystem = usingSystem; | |
162 | + } | |
163 | + | |
164 | + public String getCreateDate() { | |
165 | + return createDate; | |
166 | + } | |
167 | + | |
168 | + public void setCreateDate(String createDate) { | |
169 | + this.createDate = createDate; | |
170 | + } | |
171 | + | |
172 | + public String getCreateId() { | |
173 | + return createId; | |
174 | + } | |
175 | + | |
176 | + public void setCreateId(String createId) { | |
177 | + this.createId = createId; | |
178 | + } | |
179 | + | |
180 | + public String getUpdateDate() { | |
181 | + return updateDate; | |
182 | + } | |
183 | + | |
184 | + public void setUpdateDate(String updateDate) { | |
185 | + this.updateDate = updateDate; | |
186 | + } | |
187 | + | |
188 | + public String getUpdateId() { | |
189 | + return updateId; | |
190 | + } | |
191 | + | |
192 | + public void setUpdateId(String updateId) { | |
193 | + this.updateId = updateId; | |
194 | + } | |
195 | + | |
196 | + public boolean getIsUse() { | |
197 | + return isUse; | |
198 | + } | |
199 | + | |
200 | + public void setIsUse(boolean isUse) { | |
201 | + this.isUse = isUse; | |
202 | + } | |
203 | + | |
204 | + public boolean getIsStandard() { | |
205 | + return isStandard; | |
206 | + } | |
207 | + | |
208 | + public void setIsStandard(boolean isStandard) { | |
209 | + this.isStandard = isStandard; | |
210 | + } | |
211 | + | |
212 | + public boolean getIsMinistryStandard() { | |
213 | + return isMinistryStandard; | |
214 | + } | |
215 | + | |
216 | + public void setIsMinistryStandard(boolean isMinistryStandard) { | |
217 | + this.isMinistryStandard = isMinistryStandard; | |
218 | + } | |
219 | + | |
220 | + public int getOrders() { | |
221 | + return orders; | |
222 | + } | |
223 | + | |
224 | + public void setOrders(int orders) { | |
225 | + this.orders = orders; | |
226 | + } | |
227 | + | |
228 | + public long getSearchCount() { | |
229 | + return searchCount; | |
230 | + } | |
231 | + | |
232 | + public void setSearchCount(long searchCount) { | |
233 | + this.searchCount = searchCount; | |
234 | + } | |
235 | + | |
236 | + /**************************** Domain 원본 ****************************/ | |
237 | + | |
238 | + /** | |
239 | + * 컬럼 ID | |
240 | + */ | |
241 | + private String columnId; | |
242 | + | |
243 | + /** | |
244 | + * 해당 용어와 연결된 컬럼 목록입니다. | |
245 | + */ | |
246 | + private List<Column> columns = new ArrayList<Column>(); | |
247 | + | |
248 | + public List<Column> getColumns() { | |
249 | + return columns; | |
250 | + } | |
251 | + | |
252 | + public void setColumns(List<Column> columns) { | |
253 | + this.columns = columns; | |
254 | + } | |
255 | + | |
256 | + public String getColumnId() { | |
257 | + return columnId; | |
258 | + } | |
259 | + | |
260 | + public void setColumnId(String columnId) { | |
261 | + this.columnId = columnId; | |
262 | + } | |
263 | + | |
264 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/term/vo/StandardTermSearch.java
... | ... | @@ -0,0 +1,102 @@ |
1 | +package com.takensoft.taken_bi_manager.meta.term.vo; | |
2 | + | |
3 | +import java.io.Serializable; | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.List; | |
6 | + | |
7 | + | |
8 | +/** | |
9 | + * @author 최정우 | |
10 | + * @since 2019.11.13 | |
11 | + * | |
12 | + * 표준용어 검색 결과 VO 입니다. | |
13 | + */ | |
14 | +public class StandardTermSearch implements Serializable { | |
15 | + | |
16 | + public StandardTermSearch() {} | |
17 | + | |
18 | + public StandardTermSearch(StandardTerm term) { | |
19 | + this.termSeqs = Long.toString(term.getTermSeq()); | |
20 | + this.korean = term.getKorean(); | |
21 | + this.english = term.getEnglish(); | |
22 | + this.englishAbbr = term.getEnglishAbbr(); | |
23 | + this.standardTermList.add(term); | |
24 | + } | |
25 | + | |
26 | + public StandardTermSearch(String termSeqs, String korean, String english, String englishAbbr, List<StandardTerm> standardTermList) { | |
27 | + this.termSeqs = termSeqs; | |
28 | + this.korean = korean; | |
29 | + this.english = english; | |
30 | + this.englishAbbr = englishAbbr; | |
31 | + this.standardTermList = standardTermList; | |
32 | + } | |
33 | + | |
34 | + /** | |
35 | + * 시리얼 버전 | |
36 | + */ | |
37 | + private static final long serialVersionUID = 1L; | |
38 | + | |
39 | + private String termSeqs; | |
40 | + | |
41 | + /** | |
42 | + * 표준용어 한글 | |
43 | + */ | |
44 | + private String korean; | |
45 | + | |
46 | + /** | |
47 | + * 표준용어 영어 | |
48 | + */ | |
49 | + private String english; | |
50 | + | |
51 | + /** | |
52 | + * 표준용어 영어 약어 | |
53 | + */ | |
54 | + private String englishAbbr; | |
55 | + | |
56 | + /** | |
57 | + * 표준용어 목록 | |
58 | + */ | |
59 | + private List<StandardTerm> standardTermList = new ArrayList<StandardTerm>(); | |
60 | + | |
61 | + | |
62 | + public String getTermSeqs() { | |
63 | + return termSeqs; | |
64 | + } | |
65 | + | |
66 | + public void setTermSeqs(String termSeqs) { | |
67 | + this.termSeqs = termSeqs; | |
68 | + } | |
69 | + | |
70 | + public String getKorean() { | |
71 | + return korean; | |
72 | + } | |
73 | + | |
74 | + public void setKorean(String korean) { | |
75 | + this.korean = korean; | |
76 | + } | |
77 | + | |
78 | + public String getEnglish() { | |
79 | + return english; | |
80 | + } | |
81 | + | |
82 | + public void setEnglish(String english) { | |
83 | + this.english = english; | |
84 | + } | |
85 | + | |
86 | + public String getEnglishAbbr() { | |
87 | + return englishAbbr; | |
88 | + } | |
89 | + | |
90 | + public void setEnglishAbbr(String englishAbbr) { | |
91 | + this.englishAbbr = englishAbbr; | |
92 | + } | |
93 | + | |
94 | + public List<StandardTerm> getStandardTermList() { | |
95 | + return standardTermList; | |
96 | + } | |
97 | + | |
98 | + public void setStandardTermList(List<StandardTerm> standardTermList) { | |
99 | + this.standardTermList = standardTermList; | |
100 | + } | |
101 | + | |
102 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/test/dao/TestDAO.java
... | ... | @@ -0,0 +1,12 @@ |
1 | +package com.takensoft.taken_bi_manager.test.dao; | |
2 | + | |
3 | +import org.apache.ibatis.annotations.Mapper; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.test.vo.TestVO; | |
6 | + | |
7 | + | |
8 | +@Mapper | |
9 | +public interface TestDAO { | |
10 | + | |
11 | + public TestVO testSelectOne() throws Exception; | |
12 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/test/service/TestService.java
... | ... | @@ -0,0 +1,16 @@ |
1 | +package com.takensoft.taken_bi_manager.test.service; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.test.vo.TestVO; | |
4 | + | |
5 | +/** | |
6 | + * 테스트 중인 서비스 | |
7 | + * | |
8 | + * @author 김성원 | |
9 | + * @since 2023.12.28 | |
10 | + */ | |
11 | +public interface TestService { | |
12 | + | |
13 | + | |
14 | + public TestVO testSelectOne() throws Exception; | |
15 | + | |
16 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/test/service/impl/TestServiceImpl.java
... | ... | @@ -0,0 +1,21 @@ |
1 | +package com.takensoft.taken_bi_manager.test.service.impl; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.test.dao.TestDAO; | |
4 | +import com.takensoft.taken_bi_manager.test.service.TestService; | |
5 | +import com.takensoft.taken_bi_manager.test.vo.TestVO; | |
6 | + | |
7 | +import org.springframework.beans.factory.annotation.Autowired; | |
8 | +import org.springframework.stereotype.Service; | |
9 | + | |
10 | +@Service | |
11 | +public class TestServiceImpl implements TestService { | |
12 | + | |
13 | + // @Autowired | |
14 | + // private TestDAO testDAO; | |
15 | + | |
16 | + @Override | |
17 | + public TestVO testSelectOne() throws Exception { | |
18 | + return null; | |
19 | + } | |
20 | + | |
21 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/test/vo/TestVO.java
... | ... | @@ -0,0 +1,11 @@ |
1 | +package com.takensoft.taken_bi_manager.test.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +@Getter | |
7 | +@Setter | |
8 | +public class TestVO { | |
9 | + | |
10 | + private String testId; | |
11 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/test/web/TestController.java
... | ... | @@ -0,0 +1,39 @@ |
1 | +package com.takensoft.taken_bi_manager.test.web; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
4 | +import com.takensoft.taken_bi_manager.test.service.TestService; | |
5 | +import com.takensoft.taken_bi_manager.user.member.servie.LoginService; | |
6 | +import com.takensoft.taken_bi_manager.user.member.servie.MemberService; | |
7 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
8 | + | |
9 | +import org.springframework.beans.factory.annotation.Autowired; | |
10 | +import org.springframework.ui.Model; | |
11 | +import org.springframework.web.bind.annotation.*; | |
12 | + | |
13 | +import java.util.HashMap; | |
14 | + | |
15 | +@RestController | |
16 | +@RequestMapping("/test") | |
17 | +public class TestController { | |
18 | + | |
19 | + @Autowired | |
20 | + private MemberService memberService; | |
21 | + | |
22 | + @Autowired | |
23 | + private LoginService loginService; | |
24 | + | |
25 | + @Autowired | |
26 | + TestService testService; | |
27 | + | |
28 | + @GetMapping(path = "/test1") | |
29 | + public CustomeResultMap TestRestApi(@ModelAttribute("member") Member member) throws Exception { | |
30 | + | |
31 | + //Member member = new Member(); | |
32 | + //member.setUserId("admin"); | |
33 | + //member.setUserPassword("qwer1234"); | |
34 | + CustomeResultMap map = loginService.userLogin(member); | |
35 | + System.out.print(map.getCheckMessage().getMessage()); | |
36 | + | |
37 | + return map; | |
38 | + } | |
39 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/LoginDAO.java
... | ... | @@ -0,0 +1,32 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.dao; | |
2 | + | |
3 | +import org.apache.ibatis.annotations.Mapper; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
6 | + | |
7 | +/** | |
8 | + * @author 김성원 | |
9 | + * @since 2021.01.10 | |
10 | + * | |
11 | + * 로그인 처리 관련 DAO 클래스 | |
12 | + */ | |
13 | +@Mapper | |
14 | +public interface LoginDAO { | |
15 | + | |
16 | + /** | |
17 | + * @author 김성원 | |
18 | + * @since 2021.01.10 | |
19 | + * | |
20 | + * 로그인 성공시 로직(비밀번호 카운트, 잠김 해재) | |
21 | + */ | |
22 | + public int loginSuccess(Member member) throws Exception; | |
23 | + | |
24 | + /** | |
25 | + * @author 김성원 | |
26 | + * @since 2021.01.10 | |
27 | + * | |
28 | + * 회원가입(패스워드 카운트 업 및 잠김 처리) | |
29 | + */ | |
30 | + public int passowrdFail(Member member) throws Exception; | |
31 | + | |
32 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/MemberDAO.java
... | ... | @@ -0,0 +1,24 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.dao; | |
2 | + | |
3 | +import org.apache.ibatis.annotations.Mapper; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
6 | + | |
7 | +/** | |
8 | + * @author 김성원 | |
9 | + * @since 2023-12-28 | |
10 | + * | |
11 | + * 회원(개인) 관련된 SQL문에 접근하는 DAO Class | |
12 | + */ | |
13 | +@Mapper | |
14 | +public interface MemberDAO { | |
15 | + | |
16 | + /** | |
17 | + * @author 김성원 | |
18 | + * @since 2021.12.29 | |
19 | + * | |
20 | + * 회원정보 가져오기 | |
21 | + */ | |
22 | + public Member getMemnberById(String userId) throws Exception; | |
23 | + | |
24 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/LoginService.java
... | ... | @@ -0,0 +1,24 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.servie; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
4 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
5 | + | |
6 | +public interface LoginService { | |
7 | + | |
8 | + /** | |
9 | + * @author 김성원 | |
10 | + * @since 2024.01.09 | |
11 | + * | |
12 | + * 유저로그인 처리(userId, userPassword) | |
13 | + */ | |
14 | + public CustomeResultMap userLogin(Member member) throws Exception; | |
15 | + | |
16 | + /** | |
17 | + * @author 김성원 | |
18 | + * @since 2024.01.10 | |
19 | + * | |
20 | + * 세션 무효화 (로그아웃 처리) | |
21 | + */ | |
22 | + public boolean userLogout() throws Exception; | |
23 | + | |
24 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/MemberService.java
... | ... | @@ -0,0 +1,80 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.servie; | |
2 | + | |
3 | +import java.util.HashMap; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
7 | +import com.takensoft.taken_bi_manager.common.vo.CommonVO; | |
8 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
9 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
10 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
11 | + | |
12 | +public interface MemberService { | |
13 | + | |
14 | + /** | |
15 | + * @author 김성원 | |
16 | + * @since 2024.01.09 | |
17 | + * | |
18 | + * 아이디로 멤버조회(userId) | |
19 | + */ | |
20 | + public Member getMemnberById(String userId) throws Exception; | |
21 | + | |
22 | + /** | |
23 | + * @author 김성원 | |
24 | + * @since 2024.01.09 | |
25 | + * | |
26 | + * 회원가입(userId) | |
27 | + */ | |
28 | + public Member insertMember(Member member) throws Exception; | |
29 | + | |
30 | + /** | |
31 | + * @author 김성원 | |
32 | + * @since 2024.01.10 | |
33 | + * | |
34 | + * 회원정보 업데이트(Member) | |
35 | + */ | |
36 | + public Member updateMember(Member member) throws Exception; | |
37 | + | |
38 | + /** | |
39 | + * @author 김성원 | |
40 | + * @since 2024.01.10 | |
41 | + * | |
42 | + * 회원삭제(Member) | |
43 | + */ | |
44 | + public Member deleteMember(Member member) throws Exception; | |
45 | + | |
46 | + /** | |
47 | + * @author 김성원 | |
48 | + * @since 2024.01.09 | |
49 | + * | |
50 | + * 회원가입(userId) | |
51 | + */ | |
52 | + public List<Member> selectMemberList(SearchVO searchVO) throws Exception; | |
53 | + | |
54 | + /** | |
55 | + * @author 김성원 | |
56 | + * @since 2024.01.09 | |
57 | + * | |
58 | + * 회원가입(userId) | |
59 | + */ | |
60 | + public long selectMemberListCount(SearchVO searchVO) throws Exception; | |
61 | + | |
62 | + /** | |
63 | + * @author 김성원 | |
64 | + * @since 2024.01.10 | |
65 | + * | |
66 | + * 회원권한 부여(Member) | |
67 | + */ | |
68 | + public Member insertMemberAuth(Member member) throws Exception; | |
69 | + | |
70 | + /** | |
71 | + * @author 김성원 | |
72 | + * @since 2024.01.10 | |
73 | + * | |
74 | + * 회원권한 삭제(Member) | |
75 | + */ | |
76 | + public Member deleteMemberAuth(Member member) throws Exception; | |
77 | + | |
78 | + | |
79 | + | |
80 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/LoginServiceImpl.java
... | ... | @@ -0,0 +1,154 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.servie.impl; | |
2 | + | |
3 | +import java.util.HashMap; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import org.springframework.beans.factory.annotation.Autowired; | |
7 | +import org.springframework.stereotype.Service; | |
8 | + | |
9 | +import com.takensoft.taken_bi_manager.common.util.AuthUtil; | |
10 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
11 | +import com.takensoft.taken_bi_manager.common.util.CryptoUtil; | |
12 | +import com.takensoft.taken_bi_manager.common.util.SesssionEventListener; | |
13 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
14 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
15 | +import com.takensoft.taken_bi_manager.user.member.dao.LoginDAO; | |
16 | +import com.takensoft.taken_bi_manager.user.member.dao.MemberDAO; | |
17 | +import com.takensoft.taken_bi_manager.user.member.servie.LoginService; | |
18 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
19 | + | |
20 | +import jakarta.servlet.http.HttpServletRequest; | |
21 | +import jakarta.servlet.http.HttpSession; | |
22 | + | |
23 | + | |
24 | +/** | |
25 | + * @author 김성원 | |
26 | + * @since 2024.01.10 | |
27 | + * | |
28 | + * 로그인 관련 처리 서비스 클래스 | |
29 | + */ | |
30 | +@Service | |
31 | +public class LoginServiceImpl implements LoginService { | |
32 | + | |
33 | + @Autowired | |
34 | + private MemberDAO memberDAO; | |
35 | + | |
36 | + @Autowired | |
37 | + private LoginDAO loginDAO; | |
38 | + | |
39 | + | |
40 | + /** | |
41 | + * @author 김성원 | |
42 | + * @since 2024.01.09 | |
43 | + * | |
44 | + * 유저로그인 처리(userId, userPassword) | |
45 | + */ | |
46 | + @Override | |
47 | + public CustomeResultMap userLogin(Member member) throws Exception { | |
48 | + | |
49 | + // 결과맵 생성 | |
50 | + CustomeResultMap resultMap = new CustomeResultMap(); | |
51 | + | |
52 | + //사용자 정보 조회 | |
53 | + Member memebrInfo = memberDAO.getMemnberById(member.getUserId()); | |
54 | + | |
55 | + // 사용자 정보 있음 | |
56 | + if(memebrInfo != null && !StringUtil.isEmpty(memebrInfo.getUserId())){ | |
57 | + | |
58 | + | |
59 | + // 사용자 정보 복호화 | |
60 | + memebrInfo.dataDecoder(); | |
61 | + | |
62 | + if(memebrInfo.isLockAt()) { | |
63 | + resultMap.getCheckMessage().setError("계정이 잠겨있습니다. 관리자에게 문의하세요"); | |
64 | + return resultMap; | |
65 | + } | |
66 | + | |
67 | + //비밀번호 비교 성공 | |
68 | + if(CryptoUtil.passwordMatch(member.getUserPassword(), memebrInfo.getUserPassword())){ | |
69 | + | |
70 | + /** 로그인 처리이후, 세션처리 (시작) **/ | |
71 | + //세션 무효화 처리 | |
72 | + userLogout(); | |
73 | + | |
74 | + //현재 로그인할 userId와 동일한 로그인 session을 가진 session ID 목록 조회 | |
75 | + List<String> sessionIds = SesssionEventListener.duplicationLoginSessionIdSelectListByUserId(member.getUserId()); | |
76 | + | |
77 | + /** | |
78 | + * 현재 로그인 요청한 userId와 동일한 접속 session이 1명 이상 있고, | |
79 | + * 중복 로그인 가능 유무가 true이면 -> 중복 로그인 처리 진행 | |
80 | + * 중복 로그인 가능 유무가 false이면 -> 기존 로그인 유저를 session에서 제거 | |
81 | + */ | |
82 | + if (sessionIds.size() > 0 && AuthUtil.IS_POSSIBLE_DUPLICATION_LOGIN == false) { | |
83 | + //기존 로그인 유저 session에서 제거 | |
84 | + SesssionEventListener.duplicationLoginSessionDeleteByUserId(member.getUserId()); | |
85 | + } | |
86 | + | |
87 | + //현재 Http Request 객체 가지고 오기 | |
88 | + HttpServletRequest request = CommonUtil.getHttpServletRequest(); | |
89 | + | |
90 | + //기존 session이 존재하더라도 제거하고 새로운 세션 생성 | |
91 | + HttpSession session = request.getSession(true); | |
92 | + | |
93 | + //세션 timeout(30분) | |
94 | + session.setMaxInactiveInterval(60 * 30); | |
95 | + | |
96 | + // session 저장 정보 생성 | |
97 | + HashMap<String, Object> LoginUserInfo = new HashMap<>(); | |
98 | + LoginUserInfo.put("user_id", memebrInfo.getUserId()); //유저아이디 | |
99 | + LoginUserInfo.put("user_name", memebrInfo.getUserNm()); //유저이름 | |
100 | + LoginUserInfo.put("user_auth", memebrInfo.getAuthList()); //권한리스트 | |
101 | + LoginUserInfo.put("dept_name", memebrInfo.getDeptNm()); //부서명 | |
102 | + | |
103 | + // session 생성 | |
104 | + session.setAttribute(AuthUtil.LOGIN_USER_SESSION, LoginUserInfo); | |
105 | + resultMap.getCheckMessage().setMessage( memebrInfo.getUserId() + "님 환영합니다."); | |
106 | + | |
107 | + // 성공로직 아래에 만들기 | |
108 | + loginDAO.loginSuccess(member); | |
109 | + | |
110 | + } | |
111 | + // 실패 | |
112 | + else { | |
113 | + // 로그인 비밀번호 실패카운트 | |
114 | + memebrInfo.setLoginFailrCnt(memebrInfo.getLoginFailrCnt() + 1); | |
115 | + | |
116 | + if(memebrInfo.getLoginFailrCnt() ==5) { | |
117 | + memebrInfo.setLockAt(true); | |
118 | + } | |
119 | + | |
120 | + resultMap.getCheckMessage().setError("비밀번호 불일치 "+memebrInfo.getLoginFailrCnt()+"회, 5회 실패시 계정이 잠깁니다." ); | |
121 | + // 비밀번호 실패 업데이트 로직 | |
122 | + loginDAO.passowrdFail(memebrInfo); | |
123 | + } | |
124 | + | |
125 | + | |
126 | + }else { | |
127 | + resultMap.getCheckMessage().setError("일치하는 정보가 없습니다. \\r\\n사용자 정보를 확인해 주세요"); | |
128 | + } | |
129 | + | |
130 | + return resultMap; | |
131 | + } | |
132 | + | |
133 | + /** | |
134 | + * @author 김성원 | |
135 | + * @since 2024.01.10 | |
136 | + * | |
137 | + * 세션 무효화 (로그아웃 처리) | |
138 | + */ | |
139 | + @Override | |
140 | + public boolean userLogout() throws Exception { | |
141 | + | |
142 | + //현재 Http Request 객체 가지고 오기 | |
143 | + HttpServletRequest request = CommonUtil.getHttpServletRequest(); | |
144 | + //기존 session이 존재하면 session값을 받아오고, 존재하지 않으면 null | |
145 | + HttpSession session = request.getSession(false); | |
146 | + //기존 session이 존재하면 -> session 삭제 | |
147 | + if (session != null) { | |
148 | + //session 삭제 | |
149 | + session.invalidate(); | |
150 | + } | |
151 | + | |
152 | + return false; | |
153 | + } | |
154 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/MemberServiceImpl.java
... | ... | @@ -0,0 +1,82 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.servie.impl; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +import org.springframework.beans.factory.annotation.Autowired; | |
6 | +import org.springframework.stereotype.Service; | |
7 | + | |
8 | +import com.takensoft.taken_bi_manager.common.vo.CommonVO; | |
9 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
10 | +import com.takensoft.taken_bi_manager.user.member.dao.MemberDAO; | |
11 | +import com.takensoft.taken_bi_manager.user.member.servie.MemberService; | |
12 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
13 | + | |
14 | + | |
15 | +/** | |
16 | + * @author 김성원 | |
17 | + * @since 2024.01.10 | |
18 | + * | |
19 | + * member 관련 처리 서비스 로직 | |
20 | + */ | |
21 | +@Service | |
22 | +public class MemberServiceImpl implements MemberService { | |
23 | + | |
24 | + @Autowired | |
25 | + private MemberDAO memberDAO; | |
26 | + | |
27 | + /** | |
28 | + * @author 김성원 | |
29 | + * @since 2024.01.09 | |
30 | + * | |
31 | + * 아이디로 멤버조회(userId) | |
32 | + */ | |
33 | + @Override | |
34 | + public Member getMemnberById(String userId) throws Exception { | |
35 | + Member member = memberDAO.getMemnberById(userId); | |
36 | + member.dataDecoder(); | |
37 | + return member; | |
38 | + } | |
39 | + | |
40 | + @Override | |
41 | + public Member insertMember(Member member) throws Exception { | |
42 | + // TODO Auto-generated method stub | |
43 | + return null; | |
44 | + } | |
45 | + | |
46 | + @Override | |
47 | + public Member updateMember(Member member) throws Exception { | |
48 | + // TODO Auto-generated method stub | |
49 | + return null; | |
50 | + } | |
51 | + | |
52 | + @Override | |
53 | + public Member deleteMember(Member member) throws Exception { | |
54 | + // TODO Auto-generated method stub | |
55 | + return null; | |
56 | + } | |
57 | + | |
58 | + @Override | |
59 | + public List<Member> selectMemberList(SearchVO searchVO) throws Exception { | |
60 | + // TODO Auto-generated method stub | |
61 | + return null; | |
62 | + } | |
63 | + | |
64 | + @Override | |
65 | + public long selectMemberListCount(SearchVO searchVO) throws Exception { | |
66 | + // TODO Auto-generated method stub | |
67 | + return 0; | |
68 | + } | |
69 | + | |
70 | + @Override | |
71 | + public Member insertMemberAuth(Member member) throws Exception { | |
72 | + // TODO Auto-generated method stub | |
73 | + return null; | |
74 | + } | |
75 | + | |
76 | + @Override | |
77 | + public Member deleteMemberAuth(Member member) throws Exception { | |
78 | + // TODO Auto-generated method stub | |
79 | + return null; | |
80 | + } | |
81 | + | |
82 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/Member.java
... | ... | @@ -0,0 +1,122 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.vo; | |
2 | + | |
3 | +import java.sql.Date; | |
4 | +import java.sql.Timestamp; | |
5 | +import java.util.List; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.util.CryptoUtil; | |
8 | + | |
9 | +import lombok.Getter; | |
10 | +import lombok.Setter; | |
11 | + | |
12 | +/** | |
13 | + * @author 김성원 | |
14 | + * @since 2023-12-28 | |
15 | + * | |
16 | + * 회원정보 객체 | |
17 | + */ | |
18 | +@Getter | |
19 | +@Setter | |
20 | +public class Member { | |
21 | + | |
22 | + // 사용자 ID | |
23 | + private String userId; | |
24 | + | |
25 | + // 사용자 비밀번호 | |
26 | + private String userPassword; | |
27 | + | |
28 | + // 사용자 이름 | |
29 | + private String userNm; | |
30 | + | |
31 | + // 사용자 이메일 | |
32 | + private String userEmail; | |
33 | + | |
34 | + // 사용자 전화번호 | |
35 | + private String userTel; | |
36 | + | |
37 | + // 사용자 휴대폰 번호 | |
38 | + private String userPhone; | |
39 | + | |
40 | + // 사용자 우편번호 | |
41 | + private String zipCode; | |
42 | + | |
43 | + // 사용자 주소 | |
44 | + private String adres; | |
45 | + | |
46 | + // 사용자 상세주소 | |
47 | + private String adresDetail; | |
48 | + | |
49 | + // 사용자 성별 | |
50 | + private String gender; | |
51 | + | |
52 | + // 사용자 생년월일 | |
53 | + private Date BirthDt; | |
54 | + | |
55 | + // 생성일 | |
56 | + private Timestamp creatDt; | |
57 | + | |
58 | + // 생성자ID | |
59 | + private String creatId; | |
60 | + | |
61 | + // 수정일 | |
62 | + private Timestamp updtDt; | |
63 | + | |
64 | + // 수정자 ID | |
65 | + private String updtId; | |
66 | + | |
67 | + // 사용자 로그인 잠김 여부 | |
68 | + private boolean lockAt; | |
69 | + | |
70 | + // 사용자 로그인 잠김 일시 | |
71 | + private Timestamp lockDt; | |
72 | + | |
73 | + // 사용자 로그인 실패 카운트 | |
74 | + private int loginFailrCnt; | |
75 | + | |
76 | + // 현재 부서명 | |
77 | + private String deptNm; | |
78 | + | |
79 | + // 권한 리스트 | |
80 | + private List<String> authList; | |
81 | + | |
82 | + | |
83 | + /** | |
84 | + * @author 김성원 | |
85 | + * @since 2024.01.09 | |
86 | + * | |
87 | + * 사용자 비번 암호화 | |
88 | + */ | |
89 | + public void PasswordEncoder() { | |
90 | + this.userPassword = CryptoUtil.PasswordEncoder(this.userPassword); | |
91 | + } | |
92 | + | |
93 | + /** | |
94 | + * @author 김성원 | |
95 | + * @since 2024.01.09 | |
96 | + * | |
97 | + * 사용자 정보 암호화 | |
98 | + */ | |
99 | + public void dataEncoder() { | |
100 | + this.userPhone = CryptoUtil.encryptData(this.userPhone); | |
101 | + this.userTel = CryptoUtil.encryptData(this.userTel); | |
102 | + this.userEmail = CryptoUtil.encryptData(this.userEmail); | |
103 | + this.adres = CryptoUtil.encryptData(this.adres); | |
104 | + this.adresDetail = CryptoUtil.encryptData(this.adresDetail); | |
105 | + } | |
106 | + | |
107 | + /** | |
108 | + * @author 김성원 | |
109 | + * @since 2024.01.09 | |
110 | + * | |
111 | + * 사용자 정보 복호화 | |
112 | + */ | |
113 | + public void dataDecoder() { | |
114 | + this.userPhone = CryptoUtil.decryptData(this.userPhone); | |
115 | + this.userTel = CryptoUtil.decryptData(this.userTel); | |
116 | + this.userEmail = CryptoUtil.decryptData(this.userEmail); | |
117 | + this.adres = CryptoUtil.decryptData(this.adres); | |
118 | + this.adresDetail = CryptoUtil.decryptData(this.adresDetail); | |
119 | + } | |
120 | + | |
121 | + | |
122 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/MemberHistory.java
... | ... | @@ -0,0 +1,40 @@ |
1 | +package com.takensoft.taken_bi_manager.user.member.vo; | |
2 | + | |
3 | +import java.sql.Date; | |
4 | +import java.sql.Timestamp; | |
5 | + | |
6 | +import lombok.Getter; | |
7 | +import lombok.Setter; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2023-12-28 | |
12 | + * | |
13 | + * 회원정보 객체 | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class MemberHistory { | |
18 | + | |
19 | + // 사용자 ID | |
20 | + private String userId; | |
21 | + | |
22 | + // 사용자 이름 | |
23 | + private String userNm; | |
24 | + | |
25 | + // 사용자 이메일 | |
26 | + private String userEmail; | |
27 | + | |
28 | + // 사용자 전화번호 | |
29 | + private String userTel; | |
30 | + | |
31 | + // 사용자 휴대폰 번호 | |
32 | + private String userPhone; | |
33 | + | |
34 | + // 생성일 | |
35 | + private Timestamp creatDt; | |
36 | + | |
37 | + // 부서명 | |
38 | + private String deptCode; | |
39 | + | |
40 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/org/vo/Organization.java
... | ... | @@ -0,0 +1,56 @@ |
1 | +package com.takensoft.taken_bi_manager.user.org.vo; | |
2 | + | |
3 | +import java.sql.Date; | |
4 | +import java.sql.Timestamp; | |
5 | + | |
6 | +import lombok.Getter; | |
7 | +import lombok.Setter; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2023-12-28 | |
12 | + * | |
13 | + * 부서정보 객체 | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class Organization { | |
18 | + | |
19 | + // 부서코드(pk) | |
20 | + private String deptCode; | |
21 | + | |
22 | + // 상위부서 코드 | |
23 | + private String upperDept; | |
24 | + | |
25 | + // 조직 코드(최상위 부서?) | |
26 | + private String orgCode; | |
27 | + | |
28 | + // 부서명 | |
29 | + private String deptNm; | |
30 | + | |
31 | + // 부서명 설명 | |
32 | + private String deptDc; | |
33 | + | |
34 | + // 부서 깊이 | |
35 | + private int deptDp; | |
36 | + | |
37 | + // 부서 정렬 순서 | |
38 | + private int dept_ordr; | |
39 | + | |
40 | + // 사용여부 | |
41 | + private boolean useAt; | |
42 | + | |
43 | + // 생성일 | |
44 | + private Timestamp creatDt; | |
45 | + | |
46 | + // 생성자ID | |
47 | + private String creatId; | |
48 | + | |
49 | + // 수정일 | |
50 | + private Timestamp updtDt; | |
51 | + | |
52 | + // 수정자 ID | |
53 | + private String updtId; | |
54 | + | |
55 | + | |
56 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/user/org/vo/OrganizationHistory.java
... | ... | @@ -0,0 +1,43 @@ |
1 | +package com.takensoft.taken_bi_manager.user.org.vo; | |
2 | + | |
3 | +import java.sql.Date; | |
4 | +import java.sql.Timestamp; | |
5 | + | |
6 | +import lombok.Getter; | |
7 | +import lombok.Setter; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2023-12-28 | |
12 | + * | |
13 | + * 부서변경정보 객체 | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class OrganizationHistory { | |
18 | + | |
19 | + // 부서코드(pk) | |
20 | + private String deptCode; | |
21 | + | |
22 | + // 상위부서 코드 | |
23 | + private String upperDept; | |
24 | + | |
25 | + // 조직 코드(최상위 부서?) | |
26 | + private String orgCode; | |
27 | + | |
28 | + // 이전 부서명 | |
29 | + private String beforDeptNm; | |
30 | + | |
31 | + // 현재 부서설명 | |
32 | + private String deptNm; | |
33 | + | |
34 | + // 부서 깊이 | |
35 | + private int deptDp; | |
36 | + | |
37 | + // 부서 정렬 순서 | |
38 | + private int dept_ordr; | |
39 | + | |
40 | + // 수정일 | |
41 | + private Timestamp updtDt; | |
42 | + | |
43 | +} |
+++ src/main/resources/application.properties
... | ... | @@ -0,0 +1,14 @@ |
1 | +#server default | |
2 | +server.port = 9090 | |
3 | + | |
4 | +#Datasource Configuration | |
5 | +spring.datasource.hikari.maximum-pool-size=4 | |
6 | +spring.datasource.url=jdbc:postgresql://210.180.118.83:5432/bi_manager?currentSchema=bi_manager | |
7 | +spring.datasource.username=takensoft | |
8 | +spring.datasource.password=tts64103165!@ | |
9 | +spring.sql.init.platform=postgres | |
10 | + | |
11 | + | |
12 | +# Mapper Xml Location | |
13 | +mybatis.mapper-locations=classpath:/spring/mapper/**/*-SQL.xml | |
14 | +mybatis.config-location=classpath:/spring/mapper/mybatis-config.xml(No newline at end of file) |
+++ src/main/resources/spring/mapper/mybatis-config.xml
... | ... | @@ -0,0 +1,25 @@ |
1 | +<?xml version="1.0" encoding="UTF-8"?> | |
2 | +<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0/EN" | |
3 | + "http://mybatis.org/dtd/mybatis-3-config.dtd"> | |
4 | +<configuration> | |
5 | + <settings> | |
6 | + <setting name="cacheEnabled" value="true"/> <!-- mapper 캐시 전역 사용여부 --> | |
7 | + <setting name="lazyLoadingEnabled" value="false"/> <!-- mybatis 지연 로딩 사용여부 --> | |
8 | + <setting name="multipleResultSetsEnabled" value="true"/> <!-- 한개의 구문에서 여러개의 ResultSet 허용 여부 --> | |
9 | + <setting name="useColumnLabel" value="true"/> <!-- 컬럼명 대신 컬럼라벨 사용 여부 --> | |
10 | + <setting name="useGeneratedKeys" value="false"/> <!-- 키자동생성 --> | |
11 | + <setting name="defaultExecutorType" value="SIMPLE"/> | |
12 | + <setting name="defaultStatementTimeout" value="25000"/> | |
13 | + <setting name="callSettersOnNulls" value="true"/> | |
14 | + </settings> | |
15 | + | |
16 | + | |
17 | + <typeAliases> | |
18 | + <typeAlias type="com.takensoft.taken_bi_manager.test.vo.TestVO" alias="TestVO"/> | |
19 | + <!-- 검색 객체 --> | |
20 | + <typeAlias type="com.takensoft.taken_bi_manager.common.vo.SearchVO" alias="SearchVO"/> | |
21 | + <!-- 회원정보 객체 --> | |
22 | + <typeAlias type="com.takensoft.taken_bi_manager.user.member.vo.Member" alias="Member"/> | |
23 | + </typeAliases> | |
24 | + | |
25 | +</configuration>(No newline at end of file) |
+++ src/main/resources/spring/mapper/postgres/test-SQL.xml
... | ... | @@ -0,0 +1,11 @@ |
1 | +<?xml version="1.0" encoding="UTF-8" ?> | |
2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
3 | + | |
4 | + | |
5 | +<mapper namespace="com.takensoft.taken_bi_manager.test.dao.TestDAO"> | |
6 | + | |
7 | + <select id="testSelectOne" resultType="testVO"> | |
8 | + SELECT 'testId' as "testId" | |
9 | + </select> | |
10 | + | |
11 | +</mapper>(No newline at end of file) |
+++ src/main/resources/spring/mapper/user/login-SQL.xml
... | ... | @@ -0,0 +1,30 @@ |
1 | +<?xml version="1.0" encoding="UTF-8" ?> | |
2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
3 | + | |
4 | + | |
5 | +<mapper namespace="com.takensoft.taken_bi_manager.user.member.dao.LoginDAO"> | |
6 | + | |
7 | + <!-- 로그인 성공처리 --> | |
8 | + <update id="loginSuccess" parameterType="Member"> | |
9 | + UPDATE user_info | |
10 | + SET | |
11 | + login_failr_cnt = 0 | |
12 | + ,lock_at = '0' | |
13 | + WHERE | |
14 | + user_id = #{userId} | |
15 | + </update> | |
16 | + | |
17 | + <!-- 로그인 실패처리 --> | |
18 | + <update id="passowrdFail" parameterType="Member"> | |
19 | + UPDATE user_info | |
20 | + SET | |
21 | + login_failr_cnt = #{loginFailrCnt} | |
22 | + ,lock_at = #{lockAt} | |
23 | + <if test="loginFailrCnt != null and loginFailrCnt > 4"> | |
24 | + ,lock_dt = current_timestamp | |
25 | + </if> | |
26 | + WHERE | |
27 | + user_id = #{userId} | |
28 | + </update> | |
29 | + | |
30 | +</mapper>(No newline at end of file) |
+++ src/main/resources/spring/mapper/user/member-SQL.xml
... | ... | @@ -0,0 +1,79 @@ |
1 | +<?xml version="1.0" encoding="UTF-8" ?> | |
2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
3 | + | |
4 | + | |
5 | +<mapper namespace="com.takensoft.taken_bi_manager.user.member.dao.MemberDAO"> | |
6 | + | |
7 | + <resultMap id="memberResult" type="Member"> | |
8 | + <result property="userId" column="user_id"/> | |
9 | + <result property="userPassword" column="user_password"/> | |
10 | + <result property="userNm" column="user_nm"/> | |
11 | + <result property="userEmail" column="user_email"/> | |
12 | + <result property="userTel" column="user_tel"/> | |
13 | + <result property="userPhone" column="user_phone"/> | |
14 | + <result property="zipCode" column="zip_code"/> | |
15 | + <result property="adres" column="adres"/> | |
16 | + <result property="adresDetail" column="adres_dtail"/> | |
17 | + <result property="gender" column="gender"/> | |
18 | + <result property="BirthDt" column="birth_dt"/> | |
19 | + <result property="dept_nm" column="deptNm"/> | |
20 | + <result property="creatDt" column="creat_dt"/> | |
21 | + <result property="updtDt" column="updt_dt"/> | |
22 | + <result property="creatId" column="creat_id"/> | |
23 | + <result property="updtId" column="updt_id"/> | |
24 | + <result property="loginFailrCnt" column="login_failr_cnt"/> | |
25 | + <result property="lockAt" column="lock_at"/> | |
26 | + <result property="lockDt" column="lock_dt"/> | |
27 | + <collection property="authList" column="user_id" javaType="java.util.ArrayList" ofType="String" select="getAuthList" /> | |
28 | + </resultMap> | |
29 | + | |
30 | + | |
31 | + <!-- 로그인 아이디로 회원 조회. --> | |
32 | + <select id="getMemnberById" parameterType="String" resultMap="memberResult"> | |
33 | + SELECT | |
34 | + ui.user_id | |
35 | + , user_password | |
36 | + , user_nm | |
37 | + , user_email | |
38 | + , user_tel | |
39 | + , user_phone | |
40 | + , zip_code | |
41 | + , adres | |
42 | + , adres_dtail | |
43 | + , oi.dept_nm | |
44 | + , ui.creat_dt | |
45 | + , ui.updt_dt | |
46 | + , ui.creat_id | |
47 | + , ui.updt_id | |
48 | + , gender | |
49 | + , birth_dt | |
50 | + , login_failr_cnt | |
51 | + , lock_at | |
52 | + , lock_dt | |
53 | + FROM | |
54 | + user_info ui | |
55 | + left join orgnzt_member om on ui.user_id = om.user_id | |
56 | + left join orgnzt_info oi on om.dept_code = oi.dept_code | |
57 | + WHERE | |
58 | + ui.user_id = #{userId} | |
59 | + </select> | |
60 | + | |
61 | + | |
62 | + <!-- 사용자 부서 및 본인 권한 리스트 가져오기 --> | |
63 | + <select id="getAuthList" parameterType="String" resultType="String"> | |
64 | + SELECT | |
65 | + author | |
66 | + FROM | |
67 | + user_author ua | |
68 | + WHERE | |
69 | + ua.user_id = #{user_id} | |
70 | + UNION | |
71 | + SELECT | |
72 | + author | |
73 | + FROM | |
74 | + orgnzt_member om | |
75 | + LEFT JOIN orgnzt_author oa on om.dept_code = oa.dept_code | |
76 | + WHERE om.user_id = #{user_id} | |
77 | + </select> | |
78 | + | |
79 | +</mapper>(No newline at end of file) |
+++ src/main/resources/static/index.html
... | ... | @@ -0,0 +1,10 @@ |
1 | +<!DOCTYPE html> | |
2 | +<html lang="en"> | |
3 | +<head> | |
4 | + <meta charset="UTF-8"> | |
5 | + <title>Title</title> | |
6 | +</head> | |
7 | +<body> | |
8 | + good | |
9 | +</body> | |
10 | +</html>(No newline at end of file) |
+++ src/main/webapp/META-INF/MANIFEST.MF
... | ... | @@ -0,0 +1,3 @@ |
1 | +Manifest-Version: 1.0 | |
2 | +Class-Path: | |
3 | + |
+++ src/test/java/com/takensoft/taken_bi_manager/TakenBiManagerApplicationTests.java
... | ... | @@ -0,0 +1,13 @@ |
1 | +package com.takensoft.taken_bi_manager; | |
2 | + | |
3 | +import org.junit.jupiter.api.Test; | |
4 | +import org.springframework.boot.test.context.SpringBootTest; | |
5 | + | |
6 | +@SpringBootTest | |
7 | +class TakenBiManagerApplicationTests { | |
8 | + | |
9 | + @Test | |
10 | + void contextLoads() { | |
11 | + } | |
12 | + | |
13 | +} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?