Spring Data MongoDB๋ ๋ณต์กํ ๋๋ผ์ด๋ฒ ์ฝ๋๋ฅผ ์์ฑํ์ง ์์๋ ์ฒ๋ฆฌํ ์ ์๋ ์ถ์ํ๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ ๊ฐ๋ฐ์์๊ฒ ํธ๋ฆฌํจ์ ์ค๋ค. ํ์ง๋ง ์๋น์ค๊ฐ ์ฑ์ฅํ๊ณ ํธ๋ํฝ์ด ๋ชฐ๋ฆฌ๊ธฐ ์์ํ๊ฑฐ๋, ํน์ ์์ญ๋ง ๊ฑด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์น๋ก ์ฒ๋ฆฌํด์ผ ํ๋ ๊ฒฝ์ฐ ์ด๋ฌํ ํธ๋ฆฌํจ์ ์ฑ๋ฅ์ ์ธ ๋ณ๋ชฉ์ ๊ฐ์ ธ์ค๊ธฐ๋ ํ๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ ๋๋์ Bulk Insert์์ bson4jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ RawBsonDocument๋ฅผ ํ์ฉํ์ฌ ์ฑ๋ฅ์ ๋์ด์ฌ๋ฆฌ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ ๋ฆฌํ๊ณ ์ ํ๋ค.
Spring Data MongoDB ๋ฐ์ดํฐ ๋ณํ ๋ฐฉ์
ํํ๋ค Spring Data MongoDB๊ฐ Java ๊ฐ์ฒด๋ฅผ JSON ๋ฌธ์์ด๋ก ๋ณํํ ๋ค์ DB์ ๋ฃ๋๋ค๊ณ ์คํดํ๊ณค ํ๋ค. ๋๋ ์ผ๋ง์ ๊น์ง๊ทธ๋ ๊ฒ ์๊ฐํ๊ณ ์์๋ค. ํ์ง๋ง ํฉํธ๋ ๋ค์๊ณผ ๊ฐ๋ค.
Spring Data์ MappingMongoConverter๋ ๋ค์๊ณผ ๊ฐ์ ๊ณผ์ ์ ๊ฑฐ์น๋ค.
- Java POJO (DTO ๊ฐ์ฒด)
- Document (java Map ๊ตฌ์กฐ์ org.bson.Document)
- BSON (Binary JSON, Driver๊ฐ ์ธ์ฝ๋ฉ ํ๋ค.)
ํ
์คํธ ๊ธฐ๋ฐ์ JSON ๋ณํ์ ์์ง๋ง Document๋ผ๋ ์ค๊ฐ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ ์กด์ฌํ๋ค. ๋ฌธ์ ๋ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋ ์ด ์ค๊ฐ ๊ฐ์ฒด ์์ฑ ๋น์ฉ๊ณผ GC ๋ถํ๊ฐ ์๊ฐ๋ณด๋ค ์์ฒญ๋๋ค๋ ์ ์ด๋ค.
Document ํ๋๋ฅผ ์ ์ฅํ ๋ ์์ฑ๋๋ ๊ฐ์ฒด๋ฅผ ๊ฐ๋จํ ๊ณ์ฐํด ๋ณด์.
- Document ๊ฐ์ฒด 1๊ฐ
- Map ๋ด๋ถ ํ๋ ๊ฐ์ฒด๋ค (ํ๋ ์๋งํผ N๊ฐ)
- Key ๊ฐ์ฒด: ํ๋๋ช “name”, “price” … ๊ณผ ๊ฐ์ String ๊ฐ์ฒด (N๊ฐ)
- Value ๊ฐ์ฒด: ๊ฐ “product-1”, 100.0 .. ๊ฐ๊ฐ ๊ฐ์ฒด (N๊ฐ)
Document ํ๋๋น ์ต์ 2N + 1๊ฐ ์ด์์ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค. (ex. ํ๋๊ฐ 10๊ฐ๋ฉด 20 ~30๊ฐ์ ์์ํ ๊ฐ์ฒด ์์ฑ)
Value ๊ฐ์ฒด์ ๊ฐ์ด ๋จ์ผ ๊ฐ์ด ์๋ ํด๋์ค๋ผ๊ณ ํ๋ฉด ๋ ๋ง์ด ๋์ด๋ ๊ฒ์ด๋ค.
์ด๋ฌํ Document๋ฅผ 10๋ง๊ฐ bulk๋ก ์ ์ฅํ๋ค๊ณ ์๊ฐํด๋ณด์. ์์ฑ๋๋ ๊ฐ์ฒด์ ์๊ฐ ์ฐ๋ฆฌ๊ฐ ์๊ฐํ๋ ๊ฒ ์ด์์ผ๋ก ์๋นํ ๋ง์ด ์์ฑ๋๊ณ GC๊ฐ ์ผ์ด๋ ๋ ๊ทธ๋งํผ ๋ถํ๋ ๋ฐ์ํ ๊ฒ์ด๋ค. ์ด๋ ๊ณง ์ฑ๋ฅ ์ ํ๋ก ์ด์ด์ง๋ค.
๋ณ๋ชฉ์ ์์ธ: ๋ฌด๊ฑฐ์ด ์ค๊ฐ ๋ค๋ฆฌ
์ผ๋ฐ์ ์ธ ํธ๋ํฝ์์๋ ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง ์์์ ์ดํด๋ณธ ๋ฐ์ ๊ฐ์ด 10๋ง๊ฑด, 100๋ง๊ฑด์ Bulk Insert ํ๋ ์ํฉ์ด๋ผ๋ฉด ์๊ธฐ๊ฐ ๋ฌ๋ผ์ง๋ค.
- DOM ๋ฐฉ์์ ํ๊ณ: Spring Data์ ๋ฐฉ์์ XML์ DOM ํ์์ฒ๋ผ ์ ์ฒด ๊ฐ์ฒด ๊ตฌ์กฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ Map ํํ๋ก ํผ์ณ ๋๋๋ค.
- CPU & ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น: ๋จ์ํ ๋ฐ์ดํฐ๋ฅผ DB๋ก ์ฎ๊ธฐ๊ณ ์ถ์๋ฐ ์ค๊ฐ์ ๊ฑฐ๋ํ ๊ฐ์ฒด๋ค์ ํ ๋ฉ๋ชจ๋ฆฌ์ ๋ง๋ค์๋ค ๋ถ์๋ ์์ ์ ๋ฐ๋ณตํ๋ค.
์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฒ์ POJO๋ฅผ ๋ฐ๋ก ๋ฐ์ด๋๋ฆฌ(BSON)์ผ๋ก ์ง๋ ฌํํ์ฌ DB์ ๋ฃ๋ ๊ฒ์ด๋ค.
ํด๊ฒฐ์ฑ : Jackson๊ณผ RawBsonDocument์ ๋ง๋จ (ft. bson4jackson)
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์คํธ๋ฆฌ๋ฐ ์ง๋ ฌํ์ MongoDB ๋๋ผ์ด๋ฒ์ RawBsonDocument๋ฅผ ์กฐํฉํ๋ ์ ๋ต์ ์ฌ์ฉํ์ฌ ์ค๊ฐ์ Document๋ก ๋ณํ ํ๋ ๊ณผ์ ์ ์๋ตํ ์ ์๋ค.
- Spring Data Converter ์ฐํ: ๋ฌด๊ฑฐ์ด Spring Converter ๋์ bson4jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ๊ป ์๋๊ฐ ๋น ๋ฅธ Jackson์ ์ฌ์ฉํ๋ค.
- RawBsonDocument: ์ด๋ฏธ ๋ฐ์ดํธ๋ก ๋ณํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ธ๋ ๋ํผ ํด๋์ค๋ค. ๋๋ผ์ด๋ฒ๋ ์ด ๊ฐ์ฒด๋ฅผ ๋ฐ์ผ๋ฉด ์ฌํด์(Parsing) ์์ด ๊ทธ๋๋ก ์ ์กํ๋ค.
์ฐ๋ฆฌ๊ฐ ์ ์ฅํ๊ณ ์ ํ๋ POJO ๊ฐ์ฒด RawBsonDocument๋ก ๋ณํํ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
public RawBsonDocument toRawBsonDocument( Product product ) throws IOException {
ObjectMapper bsonObjectMapper = new ObjectMapper( new BsonFactory() );
byte[] bytes = bsonObjectMapper.writeValueAsBytes( product );
return new RawBsonDocument( bytes );
}JavaObjectMapper ์์ฑ์์ BsonFactory ์ธ์คํด์ค๋ฅผ ์ ๋ฌํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ผ๋ฐ์ ์ธ ํ ์คํธ ๊ธฐ๋ฐ์ JSON์ด ์๋ BSON(Binary JSON) ํ์์ผ๋ก ์ง๋ ฌํ/์ญ์ง๋ ฌํ ํ๋ค. Jackson์ ์ถ์ํ๊ฐ ์ ๋์ด ์์ด์ ๋ด๋ถ์ JsonFactory๋ฅผ ๊ต์ฒดํ๋ ๊ฒ๋ง์ผ๋ก ๋ฐ์ดํฐ ํฌ๋ฉง์ ๋ณ๊ฒฝํ ์ ์๋ค. BsonFactory๋ฅผ ์ฃผ์ ํจ์ผ๋ก์จ ์ด Mapper๋ ์ด์ ํ ์คํธ๊ฐ ์๋ BSON ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๊ณ ์ฝ์ด๋ค์ด๊ฒ ๋๋ ๊ฒ์ด๋ค.
์ ์ฝ๋๋ Product POJO ๊ฐ์ฒด๋ฅผ BSON bytes๋ก ์ง๋ ฌํํ์ฌ ๋ฐ๋ก RawBsonDocument์ ์ ์ฅํ๋ ๊ฒ์ด๋ค.
์ด๋ฐ ๋ฐฉ์์ผ๋ก native ํ๊ฒ ๋ณํ์ ์ํํ๋ฉด Spring Data MongoDB ์ฒ๋ฆฌ ํ๋ก์ฐ๊ฐ ์ค๊ฐ์์ Document๋ก ๋ณํํ๋ ์ฒ๋ฆฌ ์์ด ๋ฐ๋ก bson ๋ฐ์ดํฐ๋ก ์ง๋ ฌํํ ์ ์๋ค.
BsonFactory ํด๋์ค๋ ๋ค์์ ์์กด์ฑ์ด ํ์ํ๋ค.
implementation 'de.undercouch:bson4jackson:2.18.0'Groovybson4jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ณ ํฌ์คํ
์ ์์ฑํ๊ณ ์๋ ํ์ฌ ์์ ์ ์ต์ ๋ฒ์ ์ 2.18.0์ด๋ค.
Bulk๋ก ๋๋์ POJO ๊ฐ์ฒด๋ฅผ ํ๋ฒ์ insertํ ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
public void bulkInsert( List<Product> products ) {
ObjectMapper bsonObjectMapper = new ObjectMapper( new BsonFactory() );
// POJO -> RawBsonDocument ๋ณํ
List<RawBsonDocument> rawDocs = products.stream()
.map( product -> {
byte[] bytes;
try {
bytes = bsonObjectMapper.writeValueAsBytes( product );
}
catch ( JsonProcessingException e ) {
throw new RuntimeException( e );
}
return new RawBsonDocument( bytes );
} )
.toList();
// Native Collection ๊บผ๋ด์ InsertMany
MongoCollection<RawBsonDocument> mongoCollection =
mongoTemplate.getCollection( mongoTemplate.getCollectionName( Product.class ) )
.withDocumentClass( RawBsonDocument.class );
mongoCollection.insertMany( rawDocs );
}JavaSpring Data MongoDB์ Repository์๋ Custom Repository๋ฅผ ์ ์ํ์ฌ ์ฌ์ฉํ ์ ์๋ค.
public interface ProductRepositoryCustom {
void bulkInsert( List<Product> products );
}Java@RequiredArgsConstructor
public class ProductRepositoryCustomImpl implements ProductRepositoryCustom {
private final MongoTemplate mongoTemplate;
// configuration ํด๋์ค์์ ObjectMapper bsonObjectMapper = new ObjectMapper(new BsonFactory())
// ๋ก ์์ฑ๋ Bean ์ด๋ค.
private final ObjectMapper bsonObjectMapper;
@Override
public void bulkInsert( List<Product> products ) {
// POJO -> RawBsonDocument ๋ณํ
List<RawBsonDocument> rawDocs = products.stream()
.map( product -> {
byte[] bytes;
try {
bytes = bsonObjectMapper.writeValueAsBytes( product );
}
catch ( JsonProcessingException e ) {
throw new RuntimeException( e );
}
return new RawBsonDocument( bytes );
} )
.toList();
// Native Collection ๊บผ๋ด์ InsertMany
MongoCollection<RawBsonDocument> mongoCollection =
mongoTemplate.getCollection( mongoTemplate.getCollectionName( Product.class ) )
.withDocumentClass( RawBsonDocument.class );
mongoCollection.insertMany( rawDocs );
}
}Java// productRepository.bulkInsert(...) ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
public interface ProductRepository extends MongoRepository<Product, String>, ProductRepositoryCustom {
}Java์ฑ๋ฅ ๋น๊ต
bson4jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ RawBsonDocument๋ฅผ ์ฌ์ฉํ์ฌ ์ค๊ฐ ๋ณํ ๊ณผ์ ์์ด ๋ฐ๋ก BSON์ผ๋ก ๋ณํํ๋ ๊ฒ์ ์ฑ๋ฅ์ ์ธ ์ด์ ๋ ์์ง๋ง ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ, GC ๋ถํ ๊ฐ์์ ๊ฐ์ ํจ๊ณผ๋ค์ด ์๋ค.
์ ๋ง๋ก ์ฑ๋ฅ์ ์ธ ์ด์ ์ด ์๋์ง 10๋ง๊ฑด์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ 4๊ฐ์ง ์ผ์ด์ค์ ํ
์คํธ ์ฝ๋๋ฅผ ํตํด์ ํ์ธํด ๋ณด์.
- 10๋ง๋ฒ Looping ํ๋ฉด์ Repository save ํธ์ถ
- Repository saveAll ํธ์ถ (Spring Data ๊ธฐ๋ณธ Bulk ์ ์ฅ ๋ชจ๋)
- MongoTemplate์ bulkOps ํธ์ถ (Spring Data ์ต์ ํ ๊ธฐ๋ฅ)
- bson4jackson + RawBsonDocument ์กฐํฉ (Native ํธ์ถ)
MongoDB๋ฅผ ํ
์คํธ ์ฝ๋์ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ณ๋๋ก mongodb๋ฅผ ์ค์นํ ํ์ ์์ด Spring Boot Docker Compose Support๋ฅผ ์ฌ์ฉํ๋ฉด ํธ๋ฆฌํ๊ฒ ํ๊ฒฝ์ ๊ตฌ์ฑํ ์ ์๋ค. ์๋ ํฌ์คํ
์ ์ฐธ๊ณ ํ๋ฉด ๋์์ด ๋ ๊ฒ ๊ฐ๋ค.
spring boot docker compose support ๋ก์ปฌ์์ ์ธํ๋ผ ์ฌ๋ ค์ ํ
์คํธ ํ๊ธฐ (spring boot 3.1)
ํ ์คํธ์ ์ฌ์ฉํ ์ํฐํฐ ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ๋ค.
@Document( collection = "products" )
@NoArgsConstructor
@Getter
@Setter
public class Product {
@Id
private String id;
private String name;
private String category;
private double price;
private Map<String, String> attributes;
private LocalDateTime createdAt;
// ์์ฑ์, Getter, Setter ์๋ต (Lombok @Data ์ฌ์ฉ ๊ถ์ฅ)
public Product(String name, double price) {
this.name = name;
this.price = price;
this.category = "Test-Category";
this.attributes = Map.of("color", "red", "size", "L");
this.createdAt = LocalDateTime.now();
}
}Javaํ ์คํธ ์ํ์ ์ ์คํ๋๋ ์ด๊ธฐํ ์ฒ๋ฆฌ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
private List<Product> testData;
private static final int DATA_SIZE = 100_000;
@BeforeEach
void setup() {
// DB ์ด๊ธฐํ
mongoTemplate.dropCollection( Product.class );
// ํ
์คํธ ๋ฐ์ดํฐ ์์ฑ (๋ฉ๋ชจ๋ฆฌ์ ๋ฏธ๋ฆฌ ์์ฑํ์ฌ ์ธก์ ์ค์ฐจ ์ ๊ฑฐ)
System.out.println( "Generating " + DATA_SIZE + " objects..." );
testData = IntStream.range( 0, DATA_SIZE )
.mapToObj( i -> new Product( "Product-" + i, i * 1.5 ) )
.collect( Collectors.toList() );
}Java๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ ์ฝ๋๋ค.
private void printResult( String method, long millis ) {
System.out.printf( "--> [%-25s] : %5d ms (%.2f seconds)%n", method, millis, millis / 1000.0 );
}Java10๋ง๋ฒ Looping ํ๋ฉด์ Repository save ํธ์ถ
@Test
@DisplayName( "1. [Worst] Loop Save: ๋ฐ๋ณต๋ฌธ์ผ๋ก ํ๋์ฉ ์ ์ฅ" )
void testLoopSave() {
StopWatch sw = new StopWatch();
sw.start();
for ( Product product : testData ) {
repository.save( product );
}
sw.stop();
printResult( "Loop Save", sw.getTotalTimeMillis() );
}Java๊ฒฐ๊ณผ (์ฝ 48์ด)
--> [Loop Save ] : 47959 ms (47.96 seconds)Plaintext์ฌ์ค repository.save()๋ฅผ 10๋ง๋ฒ ๋ฐ๋ณต ํธ์ถํ๋ ๊ฒ์ ๋ฐ์ดํฐ ๋ณํ๋ ์๊ฒ ์ง๋ง mongodb ์๋ฒ์์ ํต์ ์๊ฐ๋ 10๋ง๋ฒ์ ์ํํ๋๊น ๊ทธ ์๊ฐ์ ๋น์ค์ด ์๋นํ ๊ฒ์ด๋ผ๊ณ ๋ณด์ฌ์ง๋ค.
Repository saveAll ํธ์ถ (Spring Data ๊ธฐ๋ณธ Bulk ์ ์ฅ ๋ชจ๋)
@Test
@DisplayName( "2. [Normal] Repository SaveAll: Spring Data ๊ธฐ๋ณธ Bulk" )
void testRepositorySaveAll() {
StopWatch sw = new StopWatch();
sw.start();
repository.saveAll( testData );
sw.stop();
printResult( "Repository.saveAll()", sw.getTotalTimeMillis() );
}Java๊ฒฐ๊ณผ
--> [Repository.saveAll() ] : 1602 ms (1.60 seconds)PlaintextMongoTemplate์ bulkOps ํธ์ถ (Spring Data ์ต์ ํ ๊ธฐ๋ฅ)
@Test
@DisplayName( "3. [Better] BulkOperations: Spring Data ์ต์ ํ ๊ธฐ๋ฅ" )
void testBulkOperations() {
StopWatch sw = new StopWatch();
sw.start();
mongoTemplate.bulkOps( BulkOperations.BulkMode.UNORDERED, Product.class )
.insert( testData )
.execute();
sw.stop();
printResult( "BulkOperations", sw.getTotalTimeMillis() );
}Java๊ฒฐ๊ณผ
--> [BulkOperations ] : 1600 ms (1.60 seconds)PlaintextRepository.saveAll() ๊ณผ ๋น๊ตํ์ ๋ ๊ฑฐ์ ์ฐจ์ด๊ฐ ์๋ค.
bson4jackson + RawBsonDocument ์กฐํฉ (Native ํธ์ถ)
@Test
@DisplayName( "4. [Best] RawBsonDocument: Jackson ์ง๋ ฌํ + Native Driver" )
void testRawBsonDocument() throws Exception {
StopWatch sw = new StopWatch();
sw.start();
// 1. Jackson์ ์ด์ฉํด POJO -> RawBsonDocument ๋ณํ (๋ณ๋ ฌ ์ฒ๋ฆฌ ๊ฐ๋ฅ)
List<RawBsonDocument> rawDocs = new ArrayList<>( DATA_SIZE );
for ( Product product : testData ) {
// ID ์๋ ์์ฑ ๋ก์ง์ด ์์ผ๋ฏ๋ก ํ์ํ๋ค๋ฉด ์ฌ๊ธฐ์ ํ ๋นํ๊ฑฐ๋ DB์ ๋งก๊น
// ์ฌ๊ธฐ์๋ ์ฑ๋ฅ ์ธก์ ์ ์ํด ์์ ๋ณํ ๋น์ฉ๋ง ํฌํจ
byte[] bytes = bsonObjectMapper.writeValueAsBytes( product );
rawDocs.add( new RawBsonDocument( bytes ) );
}
// 2. Native Collection ๊บผ๋ด๊ธฐ (RawBsonDocument ํ์
์ผ๋ก)
MongoCollection<RawBsonDocument> collection =
mongoTemplate.getCollection( mongoTemplate.getCollectionName( Product.class ) )
.withDocumentClass( RawBsonDocument.class );
// 3. Driver ๋ ๋ฒจ insertMany ์คํ
collection.insertMany( rawDocs );
sw.stop();
printResult( "RawBsonDocument + Jackson", sw.getTotalTimeMillis() );
}Java๊ฒฐ๊ณผ
--> [RawBsonDocument + Jackson] : 702 ms (0.70 seconds)PlaintextsaveAll๊ณผ bulkOps ํธ์ถ๊ณผ ๋น๊ตํ์ ๋ 2๋ฐฐ ์ ๋ ์ฐจ์ด๊ฐ ๋๋ค. 700ms ์๊ฐ์ ์ผ์์์๋ ์ฐฐ๋์ ์๊ฐ์ด๊ฒ ์ง๋ง ์ปดํจํ ์ธ๊ณ์์๋ ์์ฒญ๋ ์๊ฐ์ด๋ค. ์ํฐํฐ ๊ตฌ์ฑ์ด ๋ณต์กํ๋ฉด ๋ณต์กํ ์๋ก ์ด ์๊ฐ์ ์ฐจ์ด๋ ๋ ๋ฒ์ด์ง ๊ฒ์ด๋ค. ๊ฒ๋ค๊ฐ ์์ฑ๋๋ ๊ฐ์ฒด์ ์๊ฐ ํจ์ฌ ์ ์ด์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฉด์์, GC ์ธก๋ฉด์์๋ ํจ์ฌ ์ ๋ฆฌํ๋ค.
๋ชจ๋ ์ฝ๋๋ฅผ bson4jackson๊ณผ RawBsonDocument๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ก ๋ฐ๊ฟ ํ์๋ ์๋ค. ์ํฉ์ ๋ง์ถฐ ์ ์ ํ ๋ฐฉ์์ ์ ํํ๋ ๊ฒ์ด ์ค์ํ๋ค.
- ์ผ๋ฐ์ ์ธ ๋น์ฆ๋์ค ๋ก์ง (๋จ๊ฑด / ์๋)
- ์์ฐ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ๋ ์ค์ํ ๋งํผ ๊ทธ๋ฅ Repository๋ฅผ ์ฐ๋๊ฒ ํธํ๋ค.
- Spring Data๊ฐ ์ ๊ณตํ๋ ์ข์ ๊ธฐ๋ฅ์ ํฌ๊ธฐํ ์ด์ ๊ฐ ์๋ค.
- ์ ๋นํ ๋ฐฐ์น ์์
- MongoTemplate์ bulkOps๋ Repository์ saveAll์ ์จ๋ ๊ด์ฐฎ์ ๊ฒ ๊ฐ๋ค.
- ๊ทนํ์ ๋์ฉ๋ ์ฒ๋ฆฌ / ๋ก๊ทธ ์์ง / ์ด๋ํ ๋ฐฐ์น
- ์ด ๋ RawBsonDocument๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์.
- Spring Data ์ถ์ํ ๋์ ์ nativeํ๊ฒ ๊ฐ์ผํ ๋๋ค.
์ฐธ๊ณ ๊ธ
https://www.baeldung.com/java-jackson-mongodb-pojo-mapping
