DataMorph๋ ๋ค์ํ ๋ฐ์ดํฐ ์์ค(CSV, JSON)๋ฅผ ํ์ฑํ๊ณ ๋ณํํ๋ Java ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ์ง๊ด์ ์ธ Fluent API๋ฅผ ํตํด ๋ฐ์ดํฐ ๋ณํ ์์ ์ ์ฒด์ด๋ํ ์ ์์ผ๋ฉฐ, ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ธ ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ๋ฅผ ์ง์ํฉ๋๋ค.
- ๐ Fluent API: ์ง๊ด์ ์ธ ๋ฉ์๋ ์ฒด์ด๋์ ํตํ ๋ฐ์ดํฐ ๋ณํ
- ๐ Multiple Data Sources: ํ์ผ, ๋ฌธ์์ด, ๊ฐ์ฒด ๋ฆฌ์คํธ, ์คํธ๋ฆผ ์ง์
- ๐ Streaming Processing: ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ์ํ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ฒ๋ฆฌ
- ๐ง POJO Mapping: ๋ฆฌํ๋ ์ ๊ธฐ๋ฐ ์๋ฐฉํฅ ๊ฐ์ฒด ๋ณํ
- ๐ Memory Monitoring: JMX ๊ธฐ๋ฐ ์ค์๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ถ์
- ๐ฏ Zero Dependencies: ์์ Java ๊ตฌํ์ผ๋ก ๊ฐ๋ฒผ์ด ์ฉ๋
| DataMorph | vs. ๊ธฐ์กด ๋ฐฉ์ |
|---|---|
| ํตํฉ๋ ๋จ์ผ API | ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์กฐํฉ ํ์ |
| Zero Dependencies | Multi Dependencies |
| ์ฆ์ ์ฌ์ฉ ๊ฐ๋ฅ | ๋ณต์กํ ์ค์ |
| ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ | ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ์ํ |
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
dependencies {
implementation("com.github.HwangInUng:data-morph:1.0.0")
}repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.HwangInUng:data-morph:1.0.0'
}<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.HwangInUng</groupId>
<artifactId>data-morph</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>// CSV ํ์ผ ์ฝ๊ธฐ ๋ฐ ๋ณํ
DataSource dataSource = DataMorph.from("employees.csv");
List<DataRow> results = dataSource
.filter(row -> row.getInt("age") > 30)
.transform(row -> {
Integer salary = row.getInt("salary");
if (salary != null) {
row.set("salary", (int)(salary * 1.1)); // 10% ์ธ์
}
})
.toList();
// ๊ฒฐ๊ณผ๋ฅผ ํ์ผ๋ก ์ ์ฅ
dataSource.toFile("processed_employees.csv");// JSON ๋ฌธ์์ด ํ์ฑ
String jsonData = "[{\"name\":\"John\",\"age\":30},{\"name\":\"Jane\",\"age\":25}]";
DataSource dataSource = DataMorph.fromString(jsonData, Format.JSON);
List<DataRow> adults = dataSource
.filter(row -> row.getInt("age") >= 18)
.toList();// POJO ๊ฐ์ฒด ๋ฆฌ์คํธ ๋ณํ
List<Employee> employees = Arrays.asList(
new Employee("John", 30, 50000),
new Employee("Jane", 25, 45000)
);
DataSource dataSource = DataMorph.fromObjects(employees);
List<Employee> processedEmployees = dataSource
.transform(Transform.builder()
.rename("emp_name", "name")
.add("bonus", 1000)
.build())
.toList(Employee.class);์์ธํ API ๋ฌธ์๋ API Reference๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ค์ํ ์ฌ์ฉ ์์ ๋ Examples๋ฅผ ์ฐธ์กฐํ์ธ์.
com.datamorph/
โโโ core/ # ํต์ฌ API (DataMorph, DataSource, DataRow)
โโโ parser/ # ํ์ผ ํ์ฑ ์์ง (CSV, JSON)
โโโ writer/ # ํ์ผ ์ถ๋ ฅ ์์ง (CSV, JSON)
โโโ transform/ # ๋ฐ์ดํฐ ๋ณํ ์์ง
โโโ mapper/ # POJO ๋งคํ ์์ง
โโโ streaming/ # ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
โโโ util/ # ์ ํธ๋ฆฌํฐ (ํฌ๋งท ๊ฐ์ง)
โโโ exceptions/ # ์์ธ ์ฒ๋ฆฌ
classDiagram
class DataMorph {
+from(filePath) DataSource
+fromString(content, format) DataSource
+fromObjects(objects) DataSource
+fromStream(stream, format) DataSource
}
class DataSource {
+transform(transformer) DataSource
+transform(transform) DataSource
+filter(predicate) DataSource
+toList() List~DataRow~
+toList(clazz) List~T~
+toFile(path) void
+toString(format) String
}
class DataRow {
+getString(field) String
+getInt(field) Integer
+getDouble(field) Double
+getBoolean(field) Boolean
+set(field, value) void
+has(field) boolean
+remove(field) Object
}
class Transform {
+builder() TransformBuilder
+apply(row) DataRow
}
class ObjectMapper {
+toObject(row, clazz) T
+toDataRow(object) DataRow
}
class MemoryMonitor {
+checkMemoryUsage() void
+getMemoryUsageRatio() double
+isMemoryPressureHigh() boolean
}
DataMorph --> DataSource
DataSource --> DataRow
DataSource --> Transform
DataSource --> ObjectMapper
DataSource --> MemoryMonitor
// ๋์ฉ๋ ํ์ผ ์ฒ๋ฆฌ (๋ฉ๋ชจ๋ฆฌ ํจ์จ์ )
DataSource largeDataSource = DataMorph.fromStreamFile("large_data.csv");
List<DataRow> results = largeDataSource
.filter(row -> row.getInt("score") > 80)
.transform(row -> row.set("grade", "A"))
.toList();MemoryMonitor monitor = new MemoryMonitor();
// ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ํ์ธ
monitor.checkMemoryUsage();
// ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด ์ถ๋ ฅ
System.out.println(monitor.getMemoryInfo());// CSV๋ฅผ JSON์ผ๋ก ๋ณํ
DataMorph.convertFile("input.csv", "output.json");
// ํน์ ํฌ๋งท ์ง์
DataMorph.convertFile("data.txt", "result.txt", Format.CSV, Format.JSON);- ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ: ๋์ฉ๋ ํ์ผ๋ ์ผ์ ํ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ผ๋ก ์ฒ๋ฆฌ
- ์ง์ฐ ํ๊ฐ: ํ์ํ ์์ ์๋ง ๋ฐ์ดํฐ ๋ก๋
- ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง: ์ค์๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ถ์ ๋ฐ ๊ฒฝ๊ณ
์ฑ๋ฅ ํ๊ฐ๋ ํ์ฌ ์งํ ์ค์ ๋๋ค. ๋ค์ ์ ๋ฐ์ดํธ์์ ๊ตฌ์ฒด์ ์ธ ๋ฒค์น๋งํฌ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ ์์ ์ ๋๋ค.
- ์ฒ๋ฆฌ ์๋: ํ์ผ ํฌ๊ธฐ๋ณ ์ฒ๋ฆฌ ์๊ฐ
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋: ์ผ๋ฐ ์ฒ๋ฆฌ vs ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ ๋น๊ต
- ์ฒ๋ฆฌ๋: ์ด๋น ์ฒ๋ฆฌ ๊ฐ๋ฅํ ๋ ์ฝ๋ ์
- ํ์ฅ์ฑ: ๋ค์ํ ๋ฐ์ดํฐ ํฌ๊ธฐ์์์ ์ฑ๋ฅ ๋ณํ
| ํ์ผ ํฌ๊ธฐ | ์์ ์ฒ๋ฆฌ ์๊ฐ | ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ | ์ฒ๋ฆฌ ๋ฐฉ์ |
|---|---|---|---|
| ~10MB | 1-2์ด | ์ ์ | ์ผ๋ฐ ์ฒ๋ฆฌ |
| ~100MB | 5-10์ด | ์ค๊ฐ | ์คํธ๋ฆฌ๋ฐ ๊ถ์ฅ |
| ~1GB+ | 30-60์ด | ์ผ์ | ์คํธ๋ฆฌ๋ฐ ํ์ |
| ํฌ๋งท | ์ฝ๊ธฐ | ์ฐ๊ธฐ | ์คํธ๋ฆฌ๋ฐ |
|---|---|---|---|
| CSV | โ | โ | โ |
| JSON | โ | โ | โ |
# ์ ์ฒด ํ
์คํธ ์คํ
./gradlew test
# ํน์ ํ
์คํธ ์คํ
./gradlew test --tests "DataMorphTest"
# ํตํฉ ํ
์คํธ
./gradlew test --tests "com.datamorph.integration.*"- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Made with โค๏ธ by DataMorph Contributors