Community

๐Ÿ•Š๏ธMongoRepository vs MongoTemplate

MongoDB๋Š” NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ, ๊ทธ ์œ ์—ฐ์„ฑ ๋•๋ถ„์— Spring Boot์™€ ์ž์ฃผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. Spring Boot์—์„œ๋Š” Spring Data MongoDB๋ฅผ ํ†ตํ•ด MongoDB ์—ฐ๋™์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Spring Data MongoDB๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๋ฐฉ์‹์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœย MongoTemplate์™€ย MongoRepository ์ž…๋‹ˆ๋‹ค. ย  ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ด ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ๋น„๊ตํ•˜๊ณ , ์–ด๋–ค ์ƒํ™ฉ์—์„œ ๊ฐ๊ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ย  [MongoRepository] MongoRepository๋Š” ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ ํŒจํ„ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์ธ CRUD ๋ฉ”์„œ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Spring Data JPA์™€ ๋น„์Šทํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋ฉฐ, MongoDB ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ๋งค์šฐ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ย  ์žฅ์  * ๊ธฐ๋ณธ์ ์ธ CRUD ์ž‘์—…์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ * ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๊ฐ„๊ฒฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›€ * ๋ฉ”์„œ๋“œ ์ด๋ฆ„๋งŒ์œผ๋กœ ์ปค์Šคํ…€ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ (ex. findByCategory) ๋‹จ์  * ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์ž‘์—…์—์„œ๋Š” ์ œํ•œ์  * ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ์–ด๋ ต๊ณ  ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ์— ํ•œ๊ณ„๊ฐ€ ์žˆ์Œ ย  [MongoTemplate] MongoTemplate์€ Spring์˜ ํ…œํ”Œ๋ฆฟ ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ MongoDB ์—ฐ๋™ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋” ๋ณต์žกํ•œ MongoDB ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์–ด๋ ค์šด ์ฟผ๋ฆฌ ์ž‘์„ฑ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ย  ์žฅ์  * ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋‚˜ ์ปค์Šคํ…€ ์ž‘์—…์„ ๋” ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ * MongoDB์™€์˜ ๊นŠ์ด ์žˆ๋Š” ์ƒํ˜ธ์ž‘์šฉ์— ์ ํ•ฉ * ๋” ์„ธ๋ฐ€ํ•œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์™€ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅ ๋‹จ์  * ๊ธฐ๋ณธ์ ์ธ CRUD ์ž‘์—…๋„ ์ฝ”๋“œ๋กœ ์ง์ ‘ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ๋‹ค์†Œ ๋ณต์žกํ•ด์ง * ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ ํŒจํ„ด๋ณด๋‹ค ๋‹ค์†Œ ๋น„ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Œ ย  [MongoRepository ์‚ฌ์šฉ ์˜ˆ์‹œ] Product ์—”ํ‹ฐํ‹ฐ @Document(collection = "products") public class Product { @Id private String id; private String name; private String category; } ProductRepository ์ธํ„ฐํŽ˜์ด์Šค public interface ProductRepository extends MongoRepository { List findByCategory(String category); } MongoRepository๋ฅผ ํ™•์žฅํ•œ ProductRepository๋ฅผ ์ •์˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค. CRUD ๋ฉ”์„œ๋“œ๋Š” ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณต๋˜๋ฉฐ, ์ปค์Šคํ…€์œผ๋กœ findByCategory ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ย  CRUD ์ž‘์—… ์‚ฌ์šฉ ์˜ˆ์‹œ @Autowired private ProductRepository productRepository; public void addProduct(Product product) { productRepository.save(product); } public List getProductsByCategory(String category) { return productRepository.findByCategory(category); } ์ด์ฒ˜๋Ÿผ MongoRepository๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•œ CRUD ์ž‘์—…์„ ๋งค์šฐ ์ง๊ด€์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ย  [MongoTemplate ์‚ฌ์šฉ ์˜ˆ์‹œ] ์ด๋ฒˆ์—๋Š” ๊ฐ™์€ Product ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ MongoTemplate์„ ์ด์šฉํ•œ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ย  MongoTemplate์œผ๋กœ ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ @Autowired private MongoTemplate mongoTemplate; public List findProductsByCategory(String category) { Query query = new Query(); query.addCriteria(Criteria.where("category").is(category)); return mongoTemplate.find(query, Product.class); } ์œ„ ์ฝ”๋“œ์—์„œ๋Š” MongoTemplate์„ ์‚ฌ์šฉํ•˜์—ฌ MongoDB ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. Criteria์™€ Query ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด ๋” ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋‚˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ย  CRUD ์ž‘์—… ์ฒ˜๋ฆฌย  public void addProduct(Product product) { mongoTemplate.save(product); } public Product getProductById(String id) { return mongoTemplate.findById(id, Product.class); } MongoTemplate์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜์ง€๋งŒ, ๊ทธ๋งŒํผ ๋” ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ย  [์–ด๋–ค ๊ฒƒ์„ ์„ ํƒํ•ด์•ผ ํ• ๊นŒ?] MongoRepository๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ: * ๊ธฐ๋ณธ์ ์ธ CRUD ์ž‘์—…์„ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๋•Œ * ์ฝ”๋“œ์˜ ๊ฐ„๊ฒฐํ•จ๊ณผ ์œ ์ง€๋ณด์ˆ˜์˜ ์šฉ์ดํ•จ์ด ์ค‘์š”ํ•  ๋•Œ MongoTemplate์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ: * ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋‚˜ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ * ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ๋” ์„ธ๋ฐ€ํ•œ ์ƒํ˜ธ์ž‘์šฉ์ด ํ•„์š”ํ•  ๋•Œ ย  [๊ฒฐ๋ก ] MongoDB์™€ Spring Boot์˜ ์—ฐ๋™์—์„œ MongoRepository์™€ MongoTemplate์€ ๊ฐ๊ฐ ๋‹ค๋ฅธ ์šฉ๋„์— ๋งž์ถฐ ์„ค๊ณ„๋œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์ €๋Š” ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ bulk upsert ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ์ƒํ™ฉ์„ ๊ฒช์—ˆ๋Š”๋ฐ, MongoRepository์—๋Š” ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜์ง€ ์•Š์•„, ๋” ์œ ์—ฐํ•œ MongoTemplate์„ ์‚ฌ์šฉํ•  ์ˆ˜๋ฐ–์— ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  upsert๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ด๋Š” ๋น„ํšจ์œจ์ ์ด๋ฏ€๋กœ MongoTemplate์„ ํ†ตํ•ด ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ย  ๋ฐ˜๋ฉด, ๋‹จ์ˆœํ•œ ์กฐํšŒ ์ž‘์—…์—์„œ๋Š” MongoRepository๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. MongoTemplate๋ณด๋‹ค ์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๊น”๋”ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ๊ฐ€ ์‰ฌ์› ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ MongoRepository๋Š” ๊ธฐ๋ณธ์ ์ธ ์ž‘์—…์— ์ตœ์ ํ™”๋˜์–ด ์žˆ๊ณ , MongoTemplate์€ ๊ณ ๊ธ‰ ์ž‘์—…์—์„œ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ย  ๊ฒฐ๊ตญ ์ค‘์š”ํ•œ ๊ฒƒ์€ ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž์ถฐ ์ด ๋‘ ๋ฐฉ์‹์„ ์ ์ ˆํžˆ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ํ˜ผํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ ๋„๊ตฌ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์žฅ์ ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•ด, ํ”„๋กœ์ ํŠธ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ์†”๋ฃจ์…˜์„ ์ฐพ๋Š” ๊ฒƒ์ด ์„ฑ๊ณต์ ์ธ MongoDB ์—ฐ๋™์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

์•Œ๋ฆผ

์•Œ๋ฆผ์ด ์—†์Šต๋‹ˆ๋‹ค