```diff
--- a/buildSrc/src/main/kotlin/elex-application.gradle.kts +++ b/buildSrc/src/main/kotlin/elex-application.gradle.kts @@ -1,24 +0,0 @@ -/* - * Examples for Java - * - * Copyright (c) 2021. Elex. All Rights Reserved. - * https://www.elex-project.com/ - */ - - -plugins { - id("elex-java") - application -} - -tasks.jar { - manifest { - attributes(mapOf( - "Implementation-Title" to project.name, - "Implementation-Version" to project.version, - "Implementation-Vendor" to "ELEX co.,pte.", - "Main-Class" to application.mainClass, - "Automatic-Module-Name" to "com.elex_project.${project.name}" - )) - } -} --- a/buildSrc/src/main/kotlin/elex-base.gradle.kts +++ b/buildSrc/src/main/kotlin/elex-base.gradle.kts @@ -1,83 +0,0 @@ -/* - * Examples for Java - * - * Copyright (c) 2021. Elex. All Rights Reserved. - * https://www.elex-project.com/ - */ - -plugins { - java -} - -group = "com.elex-project" -version = "1.0-SNAPSHOT" -description = ""//todo - -repositories { - maven { - url = uri(project.findProperty("repo.url") as String) - } -} - -java { - withSourcesJar() - withJavadocJar() - sourceCompatibility = org.gradle.api.JavaVersion.VERSION_11 - targetCompatibility = org.gradle.api.JavaVersion.VERSION_11 -} - -configurations { - compileOnly { - extendsFrom(annotationProcessor.get()) - } - testCompileOnly { - extendsFrom(testAnnotationProcessor.get()) - } -} - -tasks.jar { - manifest { - attributes(mapOf( - "Implementation-Title" to project.name, - "Implementation-Version" to project.version, - "Implementation-Vendor" to "ELEX co.,pte." - )) - } -} - -tasks.compileJava { - options.encoding = "UTF-8" -} - -tasks.compileTestJava { - options.encoding = "UTF-8" -} - -tasks.test { - useJUnitPlatform() -} - -tasks.javadoc { - if (JavaVersion.current().isJava9Compatible) { - (options as StandardJavadocDocletOptions).addBooleanOption("html5", true) - } - (options as StandardJavadocDocletOptions).encoding = "UTF-8" - (options as StandardJavadocDocletOptions).charSet = "UTF-8" - (options as StandardJavadocDocletOptions).docEncoding = "UTF-8" - -} -dependencies { - //implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) - implementation("org.slf4j:slf4j-api:2.0.6") - implementation("org.jetbrains:annotations:24.0.0") - - implementation("com.elex-project:abraxas:4.11.0") - - compileOnly("org.projectlombok:lombok:1.18.26") - annotationProcessor("org.projectlombok:lombok:1.18.26") - testAnnotationProcessor("org.projectlombok:lombok:1.18.26") - - implementation("ch.qos.logback:logback-classic:1.4.5") - testImplementation("org.junit.jupiter:junit-jupiter:5.9.2") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") -} --- a/buildSrc/src/main/kotlin/elex-library.gradle.kts +++ b/buildSrc/src/main/kotlin/elex-library.gradle.kts @@ -1,95 +0,0 @@ -/* - * Examples for Java - * - * Copyright (c) 2021. Elex. All Rights Reserved. - * https://www.elex-project.com/ - */ - -plugins { - id ("elex-java") - `java-library` - `maven-publish` -} - -publishing { - publications { - create<MavenPublication>("mavenJava") { - from(components["java"]) - pom { - // todo - name.set(project.name) - description.set(project.description) - url.set("https://") - inceptionYear.set("2021") - properties.set(mapOf( - "myProp" to "value", - "prop.with.dots" to "anotherValue" - )) - organization { - name.set("Elex co.,Pte.") - url.set("https://www.elex-project.com/") - } - licenses { - license { - // todo - name.set("BSD 3-Clause License") - url.set("licenseUrl") - comments.set("") - } - } - developers { - developer { - id.set("elex") - name.set("Elex") - url.set("https://www.elex.pe.kr/") - email.set("developer@elex-project.com") - organization.set("Elex Co.,Pte.") - organizationUrl.set("https://www.elex-project.com/") - roles.set(arrayListOf("Developer", "CEO")) - timezone.set("Asia/Seoul") - properties.set(mapOf("" to "")) - } - } - contributors { - contributor { - name.set("") - email.set("") - url.set("") - } - } - scm { - // todo - connection.set("scmhttps://github.com/my-library.git") - developerConnection.set("scm
https://github.com/my-library.git") - url.set("https://github.com/my-library/") - } - } - } - } - - repositories { - maven { - name = "mavenElex" - val urlRelease = uri(project.findProperty("repo.release.url") as String) - val urlSnapshot = uri(project.findProperty("repo.snapshot.url") as String) - url = if (version.toString().endsWith("SNAPSHOT")) urlSnapshot else urlRelease - // Repository credential, Must be defined in ~/.gradle/gradle.properties - credentials { - username = project.findProperty("repo.username") as String - password = project.findProperty("repo.password") as String - } - } - maven { //todo - name = "mavenGithub" - url = uri("https://maven.pkg.git.elex-project.com/elex/tmpl-java-library") - credentials { - username = project.findProperty("github.username") as String - password = project.findProperty("github.token") as String - } - } - } -} - -dependencies { - -} --- a/buildSrc/src/main/kotlin/elex-war.gradle.kts +++ b/model-mapper/build.gradle.kts @@ -6,10 +6,9 @@ */ plugins { - id ("elex-java") - war + id("elex-java") } dependencies { - + implementation("org.modelmapper:modelmapper:3.+") } --- /dev/null +++ b/model-mapper/logback.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Examples for Java + ~ + ~ Copyright (c) 2021. Elex. All Rights Reserved. + ~ https://www.elex-project.com/ + --> + +<configuration> + + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + </appender> + + <root level="TRACE"> + <appender-ref ref="CONSOLE" /> + </root> +</configuration> --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,5 +6,4 @@ */ plugins { - id("com.github.ben-manes.versions") version "0.39.0" } --- /dev/null +++ b/model-mapper/src/main/java/kr/pe/elex/examples/User.java @@ -0,0 +1,12 @@ +package kr.pe.elex.examples; + +import lombok.Builder; +import lombok.Data; +@Builder +@Data +public class User { + private long id; + private String name; + private int age; + private Address address; +} --- a/buildSrc/src/main/kotlin/elex-java.gradle.kts +++ b/buildSrc/src/main/kotlin/elex-java.gradle.kts @@ -1,14 +1,75 @@ --/* - * Examples for Java - * - * Copyright (c) 2021. Elex. All Rights Reserved. - * https://www.elex-project.com/ - */ - plugins { - id ("elex-base") + java + //id("com.github.ben-manes.versions") version "0.39.0" +} + +group = "com.elex-project" +version = "1.0-SNAPSHOT" +description = ""//todo + +repositories { + maven { + url = uri(project.findProperty("repo.url") as String) + } +} + +java { + sourceCompatibility = org.gradle.api.JavaVersion.VERSION_17 + targetCompatibility = org.gradle.api.JavaVersion.VERSION_17 +} + +configurations { + compileOnly { + extendsFrom(annotationProcessor.get()) + } + testCompileOnly { + extendsFrom(testAnnotationProcessor.get()) + } +} + +tasks.jar { + manifest { + attributes(mapOf( + "Implementation-Title" to project.name, + "Implementation-Version" to project.version, + "Implementation-Vendor" to "ELEX co.,pte." + )) + } +} + +tasks.compileJava { + options.encoding = "UTF-8" } +tasks.compileTestJava { + options.encoding = "UTF-8" +} + +tasks.test { + useJUnitPlatform() +} + +tasks.javadoc { + if (JavaVersion.current().isJava9Compatible) { + (options as StandardJavadocDocletOptions).addBooleanOption("html5", true) + } + (options as StandardJavadocDocletOptions).encoding = "UTF-8" + (options as StandardJavadocDocletOptions).charSet = "UTF-8" + (options as StandardJavadocDocletOptions).docEncoding = "UTF-8" + +} dependencies { + //implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) + implementation("org.slf4j:slf4j-api:2.0.6") + implementation("org.jetbrains:annotations:24.0.0") + implementation("com.elex-project:abraxas:4.13.0") + + compileOnly("org.projectlombok:lombok:1.18.26") + annotationProcessor("org.projectlombok:lombok:1.18.26") + testAnnotationProcessor("org.projectlombok:lombok:1.18.26") + + implementation("ch.qos.logback:logback-classic:1.4.5") + testImplementation("org.junit.jupiter:junit-jupiter:5.9.2") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") } --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,6 +15,7 @@ "xml", "jackson", "jsoup", "markdown", "network", "httpd", "properties", "serial-io", "mustache", "thymeleaf", "locale", "quartz", "sysinfo", - "imaging", "stream", "sound", "midi", "gson", "security" + "imaging", "stream", "sound", "midi", "gson", "security", + "model-mapper" ) include("feed") --- /dev/null +++ b/model-mapper/src/main/java/kr/pe/elex/examples/Example.java @@ -0,0 +1,24 @@ +package kr.pe.elex.examples; + +import org.modelmapper.ModelMapper; + +public class Example { + public static void main(String... args){ + User alice = User.builder() + .id(100).age(34) + .name("Alice") + .address(Address.builder().city("Emerald City").street("Main Street") + .build()) + .build(); + + ModelMapper modelMapper = new ModelMapper(); + modelMapper.getConfiguration().setSkipNullEnabled(true); + + UserDto userDto =modelMapper.map(alice, UserDto.class); + + System.out.println(userDto.toString()); + + User2Dto user2Dto = modelMapper.map(alice, User2Dto.class); + System.out.println(user2Dto.toString()); + } +} --- /dev/null +++ b/model-mapper/src/main/java/kr/pe/elex/examples/AddressDto.java @@ -0,0 +1,9 @@ +package kr.pe.elex.examples; + +import lombok.Data; + +@Data +public class AddressDto { + private String city; + private String street; +} --- /dev/null +++ b/model-mapper/README.md @@ -0,0 +1,215 @@ +# ModelMapper 소개 + +ModelMapper는 Java 객체 간의 매핑을 쉽게 해주는 라이브러리입니다. 복잡한 객체 변환 코드를 작성할 필요 없이 객체의 속성들을 자동으로 매핑해주어 개발 시간을 단축하고 코드의 가독성을 높여줍니다. + +## ModelMapper의 주요 특징 + +- **타입 안전성**: 컴파일 시점에서 타입 오류를 확인할 수 있습니다. +- **자동 매핑**: 이름과 타입이 일치하는 속성들을 자동으로 매핑합니다. +- **커스텀 매핑**: 복잡한 매핑 로직을 위한 커스텀 컨버터 지원 +- **깊은 매핑**: 중첩된 객체 구조도 쉽게 매핑 가능 +- **설정 유연성**: 다양한 매핑 전략 및 설정 제공 + +## ModelMapper 사용 방법 + +### 1. 의존성 추가 + +Maven을 사용한다면 pom.xml에 다음 의존성을 추가합니다: + +```xml +<dependency> + <groupId>org.modelmapper</groupId> + <artifactId>modelmapper</artifactId> + <version>3.0.0</version> +</dependency> +``` + +Gradle을 사용한다면 build.gradle에 다음을 추가합니다: + +```groovy +implementation 'org.modelmapper:modelmapper:3.0.0' +``` + +### 2. 기본 사용법 + +```java +// ModelMapper 인스턴스 생성 +ModelMapper modelMapper = new ModelMapper();
This commit is contained in:
@@ -6,5 +6,5 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.github.ben-manes.versions") version "0.39.0"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* Examples for Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021. Elex. All Rights Reserved.
|
|
||||||
* https://www.elex-project.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("elex-java")
|
|
||||||
application
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.jar {
|
|
||||||
manifest {
|
|
||||||
attributes(mapOf(
|
|
||||||
"Implementation-Title" to project.name,
|
|
||||||
"Implementation-Version" to project.version,
|
|
||||||
"Implementation-Vendor" to "ELEX co.,pte.",
|
|
||||||
"Main-Class" to application.mainClass,
|
|
||||||
"Automatic-Module-Name" to "com.elex_project.${project.name}"
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Examples for Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021. Elex. All Rights Reserved.
|
|
||||||
* https://www.elex-project.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
java
|
|
||||||
}
|
|
||||||
|
|
||||||
group = "com.elex-project"
|
|
||||||
version = "1.0-SNAPSHOT"
|
|
||||||
description = ""//todo
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
url = uri(project.findProperty("repo.url") as String)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
withSourcesJar()
|
|
||||||
withJavadocJar()
|
|
||||||
sourceCompatibility = org.gradle.api.JavaVersion.VERSION_11
|
|
||||||
targetCompatibility = org.gradle.api.JavaVersion.VERSION_11
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations {
|
|
||||||
compileOnly {
|
|
||||||
extendsFrom(annotationProcessor.get())
|
|
||||||
}
|
|
||||||
testCompileOnly {
|
|
||||||
extendsFrom(testAnnotationProcessor.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.jar {
|
|
||||||
manifest {
|
|
||||||
attributes(mapOf(
|
|
||||||
"Implementation-Title" to project.name,
|
|
||||||
"Implementation-Version" to project.version,
|
|
||||||
"Implementation-Vendor" to "ELEX co.,pte."
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.compileJava {
|
|
||||||
options.encoding = "UTF-8"
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.compileTestJava {
|
|
||||||
options.encoding = "UTF-8"
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.javadoc {
|
|
||||||
if (JavaVersion.current().isJava9Compatible) {
|
|
||||||
(options as StandardJavadocDocletOptions).addBooleanOption("html5", true)
|
|
||||||
}
|
|
||||||
(options as StandardJavadocDocletOptions).encoding = "UTF-8"
|
|
||||||
(options as StandardJavadocDocletOptions).charSet = "UTF-8"
|
|
||||||
(options as StandardJavadocDocletOptions).docEncoding = "UTF-8"
|
|
||||||
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
//implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
|
||||||
implementation("org.slf4j:slf4j-api:2.0.6")
|
|
||||||
implementation("org.jetbrains:annotations:24.0.0")
|
|
||||||
|
|
||||||
implementation("com.elex-project:abraxas:4.11.0")
|
|
||||||
|
|
||||||
compileOnly("org.projectlombok:lombok:1.18.26")
|
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.26")
|
|
||||||
testAnnotationProcessor("org.projectlombok:lombok:1.18.26")
|
|
||||||
|
|
||||||
implementation("ch.qos.logback:logback-classic:1.4.5")
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
|
|
||||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,75 @@
|
|||||||
/*
|
|
||||||
* Examples for Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021. Elex. All Rights Reserved.
|
|
||||||
* https://www.elex-project.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id ("elex-base")
|
java
|
||||||
|
//id("com.github.ben-manes.versions") version "0.39.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group = "com.elex-project"
|
||||||
|
version = "1.0-SNAPSHOT"
|
||||||
|
description = ""//todo
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = uri(project.findProperty("repo.url") as String)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = org.gradle.api.JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = org.gradle.api.JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
compileOnly {
|
||||||
|
extendsFrom(annotationProcessor.get())
|
||||||
|
}
|
||||||
|
testCompileOnly {
|
||||||
|
extendsFrom(testAnnotationProcessor.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.jar {
|
||||||
|
manifest {
|
||||||
|
attributes(mapOf(
|
||||||
|
"Implementation-Title" to project.name,
|
||||||
|
"Implementation-Version" to project.version,
|
||||||
|
"Implementation-Vendor" to "ELEX co.,pte."
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.compileJava {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.compileTestJava {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.javadoc {
|
||||||
|
if (JavaVersion.current().isJava9Compatible) {
|
||||||
|
(options as StandardJavadocDocletOptions).addBooleanOption("html5", true)
|
||||||
|
}
|
||||||
|
(options as StandardJavadocDocletOptions).encoding = "UTF-8"
|
||||||
|
(options as StandardJavadocDocletOptions).charSet = "UTF-8"
|
||||||
|
(options as StandardJavadocDocletOptions).docEncoding = "UTF-8"
|
||||||
|
|
||||||
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
|
//implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
||||||
|
implementation("org.slf4j:slf4j-api:2.0.6")
|
||||||
|
implementation("org.jetbrains:annotations:24.0.0")
|
||||||
|
|
||||||
|
implementation("com.elex-project:abraxas:4.13.0")
|
||||||
|
|
||||||
|
compileOnly("org.projectlombok:lombok:1.18.26")
|
||||||
|
annotationProcessor("org.projectlombok:lombok:1.18.26")
|
||||||
|
testAnnotationProcessor("org.projectlombok:lombok:1.18.26")
|
||||||
|
|
||||||
|
implementation("ch.qos.logback:logback-classic:1.4.5")
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
|
||||||
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* Examples for Java
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021. Elex. All Rights Reserved.
|
|
||||||
* https://www.elex-project.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id ("elex-java")
|
|
||||||
`java-library`
|
|
||||||
`maven-publish`
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
create<MavenPublication>("mavenJava") {
|
|
||||||
from(components["java"])
|
|
||||||
pom {
|
|
||||||
// todo
|
|
||||||
name.set(project.name)
|
|
||||||
description.set(project.description)
|
|
||||||
url.set("https://")
|
|
||||||
inceptionYear.set("2021")
|
|
||||||
properties.set(mapOf(
|
|
||||||
"myProp" to "value",
|
|
||||||
"prop.with.dots" to "anotherValue"
|
|
||||||
))
|
|
||||||
organization {
|
|
||||||
name.set("Elex co.,Pte.")
|
|
||||||
url.set("https://www.elex-project.com/")
|
|
||||||
}
|
|
||||||
licenses {
|
|
||||||
license {
|
|
||||||
// todo
|
|
||||||
name.set("BSD 3-Clause License")
|
|
||||||
url.set("licenseUrl")
|
|
||||||
comments.set("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
developers {
|
|
||||||
developer {
|
|
||||||
id.set("elex")
|
|
||||||
name.set("Elex")
|
|
||||||
url.set("https://www.elex.pe.kr/")
|
|
||||||
email.set("developer@elex-project.com")
|
|
||||||
organization.set("Elex Co.,Pte.")
|
|
||||||
organizationUrl.set("https://www.elex-project.com/")
|
|
||||||
roles.set(arrayListOf("Developer", "CEO"))
|
|
||||||
timezone.set("Asia/Seoul")
|
|
||||||
properties.set(mapOf("" to ""))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
contributors {
|
|
||||||
contributor {
|
|
||||||
name.set("")
|
|
||||||
email.set("")
|
|
||||||
url.set("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scm {
|
|
||||||
// todo
|
|
||||||
connection.set("scm:git:https://github.com/my-library.git")
|
|
||||||
developerConnection.set("scm:git:https://github.com/my-library.git")
|
|
||||||
url.set("https://github.com/my-library/")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name = "mavenElex"
|
|
||||||
val urlRelease = uri(project.findProperty("repo.release.url") as String)
|
|
||||||
val urlSnapshot = uri(project.findProperty("repo.snapshot.url") as String)
|
|
||||||
url = if (version.toString().endsWith("SNAPSHOT")) urlSnapshot else urlRelease
|
|
||||||
// Repository credential, Must be defined in ~/.gradle/gradle.properties
|
|
||||||
credentials {
|
|
||||||
username = project.findProperty("repo.username") as String
|
|
||||||
password = project.findProperty("repo.password") as String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maven { //todo
|
|
||||||
name = "mavenGithub"
|
|
||||||
url = uri("https://maven.pkg.git.elex-project.com/elex/tmpl-java-library")
|
|
||||||
credentials {
|
|
||||||
username = project.findProperty("github.username") as String
|
|
||||||
password = project.findProperty("github.token") as String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
|
|
||||||
}
|
|
||||||
215
model-mapper/README.md
Normal file
215
model-mapper/README.md
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
# ModelMapper 소개
|
||||||
|
|
||||||
|
ModelMapper는 Java 객체 간의 매핑을 쉽게 해주는 라이브러리입니다. 복잡한 객체 변환 코드를 작성할 필요 없이 객체의 속성들을 자동으로 매핑해주어 개발 시간을 단축하고 코드의 가독성을 높여줍니다.
|
||||||
|
|
||||||
|
## ModelMapper의 주요 특징
|
||||||
|
|
||||||
|
- **타입 안전성**: 컴파일 시점에서 타입 오류를 확인할 수 있습니다.
|
||||||
|
- **자동 매핑**: 이름과 타입이 일치하는 속성들을 자동으로 매핑합니다.
|
||||||
|
- **커스텀 매핑**: 복잡한 매핑 로직을 위한 커스텀 컨버터 지원
|
||||||
|
- **깊은 매핑**: 중첩된 객체 구조도 쉽게 매핑 가능
|
||||||
|
- **설정 유연성**: 다양한 매핑 전략 및 설정 제공
|
||||||
|
|
||||||
|
## ModelMapper 사용 방법
|
||||||
|
|
||||||
|
### 1. 의존성 추가
|
||||||
|
|
||||||
|
Maven을 사용한다면 pom.xml에 다음 의존성을 추가합니다:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.modelmapper</groupId>
|
||||||
|
<artifactId>modelmapper</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
Gradle을 사용한다면 build.gradle에 다음을 추가합니다:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
implementation 'org.modelmapper:modelmapper:3.0.0'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 기본 사용법
|
||||||
|
|
||||||
|
```java
|
||||||
|
// ModelMapper 인스턴스 생성
|
||||||
|
ModelMapper modelMapper = new ModelMapper();
|
||||||
|
|
||||||
|
// 소스 객체에서 대상 객체로 매핑
|
||||||
|
DestinationType destination = modelMapper.map(source, DestinationType.class);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 실제 사용 예시
|
||||||
|
|
||||||
|
다음은 사용자 정보를 담은 엔티티와 DTO 간의 변환 예시입니다:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 엔티티 클래스
|
||||||
|
public class User {
|
||||||
|
private Long id;
|
||||||
|
private String email;
|
||||||
|
private String password;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private Address address;
|
||||||
|
|
||||||
|
// 생성자, getter, setter 생략
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Address {
|
||||||
|
private String street;
|
||||||
|
private String city;
|
||||||
|
private String country;
|
||||||
|
private String zipCode;
|
||||||
|
|
||||||
|
// 생성자, getter, setter 생략
|
||||||
|
}
|
||||||
|
|
||||||
|
// DTO 클래스
|
||||||
|
public class UserDTO {
|
||||||
|
private Long id;
|
||||||
|
private String email;
|
||||||
|
private String fullName;
|
||||||
|
private AddressDTO address;
|
||||||
|
|
||||||
|
// 생성자, getter, setter 생략
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddressDTO {
|
||||||
|
private String street;
|
||||||
|
private String city;
|
||||||
|
private String country;
|
||||||
|
private String zipCode;
|
||||||
|
|
||||||
|
// 생성자, getter, setter 생략
|
||||||
|
}
|
||||||
|
|
||||||
|
// 매핑 예시
|
||||||
|
public class UserService {
|
||||||
|
private final ModelMapper modelMapper;
|
||||||
|
|
||||||
|
public UserService() {
|
||||||
|
this.modelMapper = new ModelMapper();
|
||||||
|
|
||||||
|
// firstName과 lastName을 fullName으로 매핑하는 커스텀 설정
|
||||||
|
modelMapper.createTypeMap(User.class, UserDTO.class)
|
||||||
|
.addMappings(mapper -> {
|
||||||
|
mapper.map(src -> src.getFirstName() + " " + src.getLastName(),
|
||||||
|
UserDTO::setFullName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserDTO convertToDTO(User user) {
|
||||||
|
return modelMapper.map(user, UserDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User convertToEntity(UserDTO userDTO) {
|
||||||
|
return modelMapper.map(userDTO, User.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 고급 매핑 기능
|
||||||
|
|
||||||
|
#### 커스텀 매핑 설정
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 속성 이름이 다른 경우 명시적 매핑
|
||||||
|
modelMapper.createTypeMap(Source.class, Destination.class)
|
||||||
|
.addMapping(Source::getSourceProperty, Destination::setTargetProperty);
|
||||||
|
|
||||||
|
// 조건부 매핑
|
||||||
|
modelMapper.getConfiguration().setPropertyCondition(context -> {
|
||||||
|
// 조건에 따라 true/false 반환
|
||||||
|
return context.getSource() != null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 타입 변환 매핑
|
||||||
|
Converter<String, Date> stringToDateConverter =
|
||||||
|
ctx -> ctx.getSource() == null ? null : new SimpleDateFormat("yyyy-MM-dd").parse(ctx.getSource());
|
||||||
|
|
||||||
|
modelMapper.createTypeMap(Source.class, Destination.class)
|
||||||
|
.addMappings(mapper -> mapper.using(stringToDateConverter)
|
||||||
|
.map(Source::getDateAsString, Destination::setDate));
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 매핑 전략 설정
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 필드 매핑 전략 (필드 이름 기준 매핑)
|
||||||
|
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
|
||||||
|
|
||||||
|
// 접근 방식 설정 (필드 직접 접근)
|
||||||
|
modelMapper.getConfiguration().setFieldAccessLevel(AccessLevel.PRIVATE);
|
||||||
|
modelMapper.getConfiguration().setFieldMatchingEnabled(true);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. 컬렉션 매핑
|
||||||
|
|
||||||
|
```java
|
||||||
|
// List 매핑
|
||||||
|
List<UserDTO> userDTOs = users.stream()
|
||||||
|
.map(user -> modelMapper.map(user, UserDTO.class))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Type Token 사용하여 컬렉션 매핑
|
||||||
|
Type listType = new TypeToken<List<UserDTO>>() {}.getType();
|
||||||
|
List<UserDTO> userDTOs = modelMapper.map(users, listType);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 실제 사용 사례
|
||||||
|
|
||||||
|
Spring Boot 애플리케이션에서 ModelMapper를 빈으로 등록하여 사용하는 예시:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Configuration
|
||||||
|
public class ApplicationConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ModelMapper modelMapper() {
|
||||||
|
ModelMapper modelMapper = new ModelMapper();
|
||||||
|
|
||||||
|
// 엄격한 매핑 전략 설정
|
||||||
|
modelMapper.getConfiguration()
|
||||||
|
.setMatchingStrategy(MatchingStrategies.STRICT)
|
||||||
|
.setSkipNullEnabled(true)
|
||||||
|
.setFieldMatchingEnabled(true)
|
||||||
|
.setFieldAccessLevel(AccessLevel.PRIVATE);
|
||||||
|
|
||||||
|
return modelMapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ProductService {
|
||||||
|
|
||||||
|
private final ProductRepository productRepository;
|
||||||
|
private final ModelMapper modelMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ProductService(ProductRepository productRepository, ModelMapper modelMapper) {
|
||||||
|
this.productRepository = productRepository;
|
||||||
|
this.modelMapper = modelMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductDTO getProduct(Long id) {
|
||||||
|
Product product = productRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new EntityNotFoundException("Product not found"));
|
||||||
|
|
||||||
|
return modelMapper.map(product, ProductDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProductDTO> getAllProducts() {
|
||||||
|
List<Product> products = productRepository.findAll();
|
||||||
|
|
||||||
|
return products.stream()
|
||||||
|
.map(product -> modelMapper.map(product, ProductDTO.class))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 결론
|
||||||
|
|
||||||
|
ModelMapper는 Java 애플리케이션에서 객체 간 매핑을 간소화하는 강력한 도구입니다. 자동 매핑 기능으로 반복적인 코드를 줄이고, 커스텀 매핑 설정으로 복잡한 변환 로직도 깔끔하게 처리할 수 있습니다. 특히 엔티티와 DTO 간의 변환이 많은 웹 애플리케이션에서 유용하게 활용할 수 있습니다.
|
||||||
@@ -6,10 +6,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id ("elex-java")
|
id("elex-java")
|
||||||
war
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation("org.modelmapper:modelmapper:3.+")
|
||||||
}
|
}
|
||||||
20
model-mapper/logback.xml
Normal file
20
model-mapper/logback.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Examples for Java
|
||||||
|
~
|
||||||
|
~ Copyright (c) 2021. Elex. All Rights Reserved.
|
||||||
|
~ https://www.elex-project.com/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="TRACE">
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
12
model-mapper/src/main/java/kr/pe/elex/examples/Address.java
Normal file
12
model-mapper/src/main/java/kr/pe/elex/examples/Address.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package kr.pe.elex.examples;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@Data
|
||||||
|
public class Address {
|
||||||
|
private String city;
|
||||||
|
private String street;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package kr.pe.elex.examples;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AddressDto {
|
||||||
|
private String city;
|
||||||
|
private String street;
|
||||||
|
}
|
||||||
24
model-mapper/src/main/java/kr/pe/elex/examples/Example.java
Normal file
24
model-mapper/src/main/java/kr/pe/elex/examples/Example.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package kr.pe.elex.examples;
|
||||||
|
|
||||||
|
import org.modelmapper.ModelMapper;
|
||||||
|
|
||||||
|
public class Example {
|
||||||
|
public static void main(String... args){
|
||||||
|
User alice = User.builder()
|
||||||
|
.id(100).age(34)
|
||||||
|
.name("Alice")
|
||||||
|
.address(Address.builder().city("Emerald City").street("Main Street")
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ModelMapper modelMapper = new ModelMapper();
|
||||||
|
modelMapper.getConfiguration().setSkipNullEnabled(true);
|
||||||
|
|
||||||
|
UserDto userDto =modelMapper.map(alice, UserDto.class);
|
||||||
|
|
||||||
|
System.out.println(userDto.toString());
|
||||||
|
|
||||||
|
User2Dto user2Dto = modelMapper.map(alice, User2Dto.class);
|
||||||
|
System.out.println(user2Dto.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
12
model-mapper/src/main/java/kr/pe/elex/examples/User.java
Normal file
12
model-mapper/src/main/java/kr/pe/elex/examples/User.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package kr.pe.elex.examples;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
@Builder
|
||||||
|
@Data
|
||||||
|
public class User {
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
private int age;
|
||||||
|
private Address address;
|
||||||
|
}
|
||||||
12
model-mapper/src/main/java/kr/pe/elex/examples/User2Dto.java
Normal file
12
model-mapper/src/main/java/kr/pe/elex/examples/User2Dto.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package kr.pe.elex.examples;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class User2Dto {
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
private int age;
|
||||||
|
private String addressCity;
|
||||||
|
private String addressStreet;
|
||||||
|
}
|
||||||
10
model-mapper/src/main/java/kr/pe/elex/examples/UserDto.java
Normal file
10
model-mapper/src/main/java/kr/pe/elex/examples/UserDto.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package kr.pe.elex.examples;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserDto {
|
||||||
|
private String name;
|
||||||
|
private int age;
|
||||||
|
private Address address;
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ include(
|
|||||||
"xml", "jackson", "jsoup", "markdown", "network", "httpd",
|
"xml", "jackson", "jsoup", "markdown", "network", "httpd",
|
||||||
"properties", "serial-io",
|
"properties", "serial-io",
|
||||||
"mustache", "thymeleaf", "locale", "quartz", "sysinfo",
|
"mustache", "thymeleaf", "locale", "quartz", "sysinfo",
|
||||||
"imaging", "stream", "sound", "midi", "gson", "security"
|
"imaging", "stream", "sound", "midi", "gson", "security",
|
||||||
|
"model-mapper"
|
||||||
)
|
)
|
||||||
include("feed")
|
include("feed")
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("elex-war")
|
id("elex-java")
|
||||||
|
war
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
Reference in New Issue
Block a user
