plugins {
id 'org.springframework.boot' version '2.3.10.RELEASE'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'batch'
version = '21.04.30.001 batch practice'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-batch'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.batch:spring-batch-test'
}
test {
useJUnitPlatform()
}
MySQL DB에 Spring Batch Metadata Table들을 생성했다.
batch가 동작하는데에 꼭 필요함!
H2DB의 경우 boot시 자동으로 생성해주지만 Oracle, MySQL DB는 schema를 찾아 수동으로 생성해야한다.
schema-mysql.sql
-- Autogenerated: do not edit this file
CREATE TABLE BATCH_JOB_INSTANCE (
JOB_INSTANCE_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT ,
JOB_NAME VARCHAR(100) NOT NULL,
JOB_KEY VARCHAR(32) NOT NULL,
constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)
) ENGINE=InnoDB;
CREATE TABLE BATCH_JOB_EXECUTION (
JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT ,
JOB_INSTANCE_ID BIGINT NOT NULL,
CREATE_TIME DATETIME(6) NOT NULL,
START_TIME DATETIME(6) DEFAULT NULL ,
END_TIME DATETIME(6) DEFAULT NULL ,
STATUS VARCHAR(10) ,
EXIT_CODE VARCHAR(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED DATETIME(6),
JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
JOB_EXECUTION_ID BIGINT NOT NULL ,
TYPE_CD VARCHAR(6) NOT NULL ,
KEY_NAME VARCHAR(100) NOT NULL ,
STRING_VAL VARCHAR(250) ,
DATE_VAL DATETIME(6) DEFAULT NULL ,
LONG_VAL BIGINT ,
DOUBLE_VAL DOUBLE PRECISION ,
IDENTIFYING CHAR(1) NOT NULL ,
constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_STEP_EXECUTION (
STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT NOT NULL,
STEP_NAME VARCHAR(100) NOT NULL,
JOB_EXECUTION_ID BIGINT NOT NULL,
START_TIME DATETIME(6) NOT NULL ,
END_TIME DATETIME(6) DEFAULT NULL ,
STATUS VARCHAR(10) ,
COMMIT_COUNT BIGINT ,
READ_COUNT BIGINT ,
FILTER_COUNT BIGINT ,
WRITE_COUNT BIGINT ,
READ_SKIP_COUNT BIGINT ,
WRITE_SKIP_COUNT BIGINT ,
PROCESS_SKIP_COUNT BIGINT ,
ROLLBACK_COUNT BIGINT ,
EXIT_CODE VARCHAR(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED DATETIME(6),
constraint JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT (
STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT TEXT ,
constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT (
JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT TEXT ,
constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_STEP_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_STEP_EXECUTION_SEQ);
CREATE TABLE BATCH_JOB_EXECUTION_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_JOB_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_EXECUTION_SEQ);
CREATE TABLE BATCH_JOB_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_JOB_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_SEQ);
Run 했을 경우의 error log
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
2021-04-28 16:55:19.464 INFO 19748 --- [ restartedMain] p.SpringBatchExample210428001Application : Starting SpringBatchExample210428001Application using Java 15.0.2 on DESKTOP-C7P9M2O with PID 19748 (--- \springBatchExample210428001\bin\main started by *** in --- \springBatchExample210428001)
2021-04-28 16:55:19.469 INFO 19748 --- [ restartedMain] p.SpringBatchExample210428001Application : No active profile set, falling back to default profiles: default
2021-04-28 16:55:19.550 INFO 19748 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-04-28 16:55:19.550 INFO 19748 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2021-04-28 16:55:20.736 INFO 19748 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-04-28 16:55:20.739 INFO 19748 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2021-04-28 16:55:20.752 INFO 19748 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 JDBC repository interfaces.
2021-04-28 16:55:20.769 INFO 19748 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-04-28 16:55:20.771 INFO 19748 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-04-28 16:55:20.782 INFO 19748 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 JPA repository interfaces.
2021-04-28 16:55:21.584 INFO 19748 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-04-28 16:55:21.600 INFO 19748 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-04-28 16:55:21.601 INFO 19748 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.45]
2021-04-28 16:55:21.810 INFO 19748 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-04-28 16:55:21.811 INFO 19748 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2259 ms
2021-04-28 16:55:21.918 WARN 19748 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inMemoryDatabaseShutdownExecutor' defined in class path resource [org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.class]: Unsatisfied dependency expressed through method 'inMemoryDatabaseShutdownExecutor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.mysql.cj.jdbc.Driver
2021-04-28 16:55:21.922 INFO 19748 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-04-28 16:55:21.942 INFO 19748 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-04-28 16:55:21.978 ERROR 19748 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inMemoryDatabaseShutdownExecutor' defined in class path resource [org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.class]: Unsatisfied dependency expressed through method 'inMemoryDatabaseShutdownExecutor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.mysql.cj.jdbc.Driver
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.6.jar:5.3.6]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.6.jar:5.3.6]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.6.jar:5.3.6]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) ~[spring-boot-2.4.5.jar:2.4.5]
at batch.practice.SpringBatchExample210428001Application.main(SpringBatchExample210428001Application.java:15) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.4.5.jar:2.4.5]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.mysql.cj.jdbc.Driver
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.6.jar:5.3.6]
... 27 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.mysql.cj.jdbc.Driver
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.6.jar:5.3.6]
... 41 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot load driver class: com.mysql.cj.jdbc.Driver
at org.springframework.util.Assert.state(Assert.java:97) ~[spring-core-5.3.6.jar:5.3.6]
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:224) ~[spring-boot-autoconfigure-2.4.5.jar:2.4.5]
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.initializeDataSourceBuilder(DataSourceProperties.java:176) ~[spring-boot-autoconfigure-2.4.5.jar:2.4.5]
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:48) ~[spring-boot-autoconfigure-2.4.5.jar:2.4.5]
at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari.dataSource(DataSourceConfiguration.java:90) ~[spring-boot-autoconfigure-2.4.5.jar:2.4.5]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.6.jar:5.3.6]
... 42 common frames omitted
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inMemoryDatabaseShutdownExecutor' defined in class path resource [org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.class]: Unsatisfied dependency expressed through method 'inMemoryDatabaseShutdownExecutor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.mysql.cj.jdbc.Driver
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.mysql.cj.jdbc.Driver
package batch.practice.job;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j //log 사용을 위한 lombok annotation
@RequiredArgsConstructor //생성자 DI를 위한 lombok annotation
@Configuration //Spring batch의 Job은 @Configuration annotation으로 등록 후 사용
public class SimpleJobConfiguration002 {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job simpleJob1() {
log.info("========== START simpleJob");
return jobBuilderFactory.get("simpleJob1") //Batch Job을 생성하고 builder를 통해 이름 지정
.start(simpleStep1()) //execute 할 step or sequence of steps
.build();
};
@Bean
public Step simpleStep1() {
return stepBuilderFactory.get("simpleStep1") //Batch Step을 생성하고 builder를 통해 이름 지정
.tasklet((contribution, chunkContext) -> { //Step 안에서 수행될 기능을 명시
for(int i = 0; i < 100 ; i ++) { // - Tasklet은 Step 안에서 단일로 수행될 커스텀 기능 선언
log.info(">>>>> "+(i+1)+" <<<<<");
}
return RepeatStatus.FINISHED;
})
.build();
};
};
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
2021-04-27 13:42:11.560 INFO 27484 --- [ restartedMain] b.p.BatchExample210427001Application : Starting BatchExample210427001Application using Java 15.0.2 on DESKTOP-C7P9M2O with PID 27484 (-)
2021-04-27 13:42:11.564 INFO 27484 --- [ restartedMain] b.p.BatchExample210427001Application : No active profile set, falling back to default profiles: default
2021-04-27 13:42:11.642 INFO 27484 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-04-27 13:42:12.367 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : ========== START simpleJob
2021-04-27 13:42:12.583 INFO 27484 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2021-04-27 13:42:12.605 INFO 27484 --- [ restartedMain] b.p.BatchExample210427001Application : Started BatchExample210427001Application in 1.483 seconds (JVM running for 3.024)
2021-04-27 13:42:12.607 INFO 27484 --- [ restartedMain] o.s.b.a.b.JobLauncherApplicationRunner : Running default command line with: []
2021-04-27 13:42:12.608 WARN 27484 --- [ restartedMain] o.s.b.c.c.a.DefaultBatchConfigurer : No datasource was provided...using a Map based JobRepository
2021-04-27 13:42:12.608 WARN 27484 --- [ restartedMain] o.s.b.c.c.a.DefaultBatchConfigurer : No transaction manager was provided, using a ResourcelessTransactionManager
2021-04-27 13:42:12.628 INFO 27484 --- [ restartedMain] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2021-04-27 13:42:12.662 INFO 27484 --- [ restartedMain] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=simpleJob1]] launched with the following parameters: [{}]
2021-04-27 13:42:12.700 INFO 27484 --- [ restartedMain] o.s.batch.core.job.SimpleStepHandler : Executing step: [simpleStep1]
2021-04-27 13:42:12.711 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 1 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 2 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 3 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 4 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 5 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 6 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 7 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 8 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 9 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 10 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 11 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 12 <<<<<
2021-04-27 13:42:12.712 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 13 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 14 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 15 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 16 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 17 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 18 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 19 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 20 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 21 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 22 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 23 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 24 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 25 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 26 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 27 <<<<<
2021-04-27 13:42:12.713 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 28 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 29 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 30 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 31 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 32 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 33 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 34 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 35 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 36 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 37 <<<<<
2021-04-27 13:42:12.714 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 38 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 39 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 40 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 41 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 42 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 43 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 44 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 45 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 46 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 47 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 48 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 49 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 50 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 51 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 52 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 53 <<<<<
2021-04-27 13:42:12.715 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 54 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 55 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 56 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 57 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 58 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 59 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 60 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 61 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 62 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 63 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 64 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 65 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 66 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 67 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 68 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 69 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 70 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 71 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 72 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 73 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 74 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 75 <<<<<
2021-04-27 13:42:12.716 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 76 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 77 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 78 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 79 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 80 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 81 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 82 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 83 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 84 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 85 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 86 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 87 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 88 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 89 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 90 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 91 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 92 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 93 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 94 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 95 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 96 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 97 <<<<<
2021-04-27 13:42:12.717 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 98 <<<<<
2021-04-27 13:42:12.718 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 99 <<<<<
2021-04-27 13:42:12.718 INFO 27484 --- [ restartedMain] b.p.job.SimpleJobConfiguration002 : >>>>> 100 <<<<<
2021-04-27 13:42:12.727 INFO 27484 --- [ restartedMain] o.s.batch.core.step.AbstractStep : Step: [simpleStep1] executed in 27ms
2021-04-27 13:42:12.735 INFO 27484 --- [ restartedMain] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=simpleJob1]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 42ms
사실 1개의 step에서 for문을 이용하여 1~100까지 출력하는 방식이 아니라
job이 작동하면 step을 100개 생성해서 각각 1~100까지 출력하게 만들고 싶었다.
<update id="companyBoardCountUpadate" parameterType="CompanyBoardContent">
<selectKey order="BEFORE" keyProperty="companyCount" resultType="String">
SELECT
c.company_count+1
from
tb_company AS c
where
c.company_code = #{companyCode}
</selectKey>
UPDATE tb_company
SET
company_count= #{companyCount}
WHERE
company_code = #{companyCode}
</update>
쿼리문도 전부 정상이고 오탈자도 없으며,, DTO에 알맞은 getter, setter도 전부 있었는데!!!!!!!!!!!
org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty 'companyCount' in java.lang.String.
이 오류로 인해 진행이 안되는 상황이었다..
조언도 구해봤는데 원인을 전혀 모르겠어서 서브쿼리로 처리했다...
마이바티스!!!!!! 나는 너를 믿었는데!!
그래도 서브쿼리로 바꾼 코드가 더 간결해서 기분이 좋아졌다 ~~ ^^~!!
<update id="companyBoardCountUpadate" parameterType="CompanyBoardContent">
UPDATE tb_company
SET
company_count= (SELECT company_count +1)
WHERE
company_code = #{companyCode}
</update>
<!-- 처리업무 등록 -->
<insert id="unpaidInsert" parameterType="Unpaid">
<!-- unpaidCode -->
<selectKey order="BEFORE" keyProperty="unpaidCode" resultType="String">
select
(case count(*)
when 0 then 'unpaid_1'
else CONCAT('unpaid_',max(cast(substring(unpaid_code,8) as decimal))+1)
end) as unpaidCode
from
tb_unpaid
</selectKey>
<selectKey order="BEFORE" keyProperty="customerCode" resultType="String">
SELECT
c.customer_code
from
tb_customer AS c
where
#{customerName} = c.customer_name
and
#{customerTel} = c.customer_tel
</selectKey>
<selectKey order="BEFORE" keyProperty="unpaidRegStaffCode" resultType="String">
SELECT
sf.staff_code
from
tb_staff as sf
join
tb_member as m
on
sf.member_id = m.member_id
join
tb_store AS sr
on
sf.store_code =sr.store_code
where
#{unpaidRegMemberName} = m.member_name
and
#{unpaidRegStoreName} = sr.store_name
</selectKey>
INSERT INTO tb_unpaid
(unpaid_code
, unpaid_exp_date
, unpaid_part
, unpaid_sub_name
, unpaid_desc
, customer_code
, unpaid_memo
, unpaid_status
, unpaid_reg_date
, unpaid_reg_staff_code)
VALUES
(#{unpaidCode}
, NOW()
, #{unpaidPart}
, #{unpaidSubName}
, #{unpaidDesc}
, #{customerCode}
, #{unpaidMemo}
, #{unpaidStatus}
, NOW()
, #{unpaidRegStaffCode})
</insert>
mapper.xml 에서 <insert></insert> 안에 <selectKey></selectKey>를 여러개 사용하여 여러가지의 조인 값을 가져오고싶었다! 하지만 계속 오류가 발생했다.
알고보니<selectKey></selectKey> 는 한개만 사용할 수 있다고 한다!!
<!-- 처리업무 등록 -->
<insert id="unpaidInsert" parameterType="Unpaid">
<selectKey order="BEFORE" keyProperty="unpaidCode,customerCode,unpaidRegStaffCode" resultType="Map">
select
(case count(*)
when 0 then 'unpaid_1'
else CONCAT('unpaid_',max(cast(substring(unpaid_code,8) as decimal))+1)
end) as unpaidCode
,tc.customer_code as customerCode
,tc.staff_code as unpaidRegStaffCode
from
tb_unpaid AS u ,(
SELECT
c.customer_code,
tf.staff_code
from
tb_customer AS c,
(
SELECT
sf.staff_code
from
tb_staff as sf
join
tb_member as m
on
sf.member_id = m.member_id
join
tb_store AS sr
on
sf.store_code =sr.store_code
where
#{unpaidRegMemberName} = m.member_name
and
#{unpaidRegStoreName} = sr.store_name
)AS tf
where
#{customerName} = c.customer_name
and
#{customerTel} = c.customer_tel
)AS tc
</selectKey>
INSERT INTO tb_unpaid
(unpaid_code
, unpaid_exp_date
, unpaid_part
, unpaid_sub_name
, unpaid_desc
, customer_code
, unpaid_memo
, unpaid_status
, unpaid_reg_date
, unpaid_reg_staff_code)
VALUES
(#{unpaidCode}
, NOW()
, #{unpaidPart}
, #{unpaidSubName}
, #{unpaidDesc}
, #{customerCode}
, #{unpaidMemo}
, #{unpaidStatus}
, NOW()
, #{unpaidRegStaffCode})
</insert>
그래서 서브쿼리를 사용하여 여러개의 컬럼을 한개의 selectKey에 담았다.
insert 쿼리문에서 값을 받을 때 #{paramater}와 selectKey의 select문의 alias가 대응된다~!!
친구랑 대화하다보니 하나의 서비스에서 처리하지 않고 서비스를 나누어서 처리하는 방법도 있을 거라고 깨달았다!!
서비스를 나누어 처리하면 서브쿼리를 쓰지 않고도 처리할 수 있을 것이다.
서비스를 하나로 만들면 서비스를 나눈 것 보다유지보수 측면에서 이득이라고 하니 상황에 따라 골라서 사용해야겠다.
또, 요즘 join이 없도록 작업하는 추세라고 하는데!!
정규화를 막 배운 입장에서는 아직 실제로 사용하기에는 정규화가 마음에 걸린다...
하지만 서브쿼리 안에!! 서브쿼리 안에!! 서브쿼리를 넣다 보니 join이 없는 작업이 더 편리할 것 같다고 느꼈다.
지금 하고있는 프로젝트는 작은 규모이기 때문에 데이터베이스에 데이터가 적어서 체감을 못했지만, join이 많이 일어나면 데이터가 많이 존재할 경우 처리속도가 느려진다고 하니 참고해야겠다!!
개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크
* 퍼시스턴스 프레임워크(Persistence Framework)는데이터의 저장, 조회, 변경, 삭제를 다루는 클래스 및 설정 파일들의 집합이다.퍼시스턴스 프레임워크를 사용하면JDBC프로그래밍의 복잡함이나 번거로움 없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있으며 안정적인 구동도 보장한다.