๐Ÿฆ๋ฉ‹์Ÿ์ด์‚ฌ์ž์ฒ˜๋Ÿผ ๋ฐฑ์—”๋“œ ์Šคํ„ฐ๋”” (3)

์œค์ค€์ƒยท2024๋…„ 9์›” 4์ผ
0

๋ฉ‹์Ÿ์ด์‚ฌ์ž์ฒ˜๋Ÿผ

๋ชฉ๋ก ๋ณด๊ธฐ
3/4
post-thumbnail

์ •๋ณด์ฒ˜๋ฆฌ๊ธฐ์‚ฌ ํ•„๊ธฐ๋„ ๋ณด๊ณ , ํ•ด์ปคํ†ค๋„ ํ•˜๊ณ , ์šด๋™๋„ ํ•˜๋ฉด์„œ ๋ฐฉํ•™์„ ๋ณด๋ƒˆ๋‹ค. ๋ญ”๊ฐ€ ์ข€ ๋” ๋ฐ”์˜๊ฒŒ ์‚ด์•˜์–ด์•ผํ–ˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์ง€๋งŒ, ๋‚ด ์ธ์ƒ์—์„œ ํ•™์ƒ๋•Œ์˜ ๋งˆ์ง€๋ง‰ ๋ฐฉํ•™์ด์—ฌ์„œ ๋ญ”๊ฐ€ ์ด์ œ ์ •๋ง ์‹œ์ž‘์ด๊ตฌ๋‚˜ ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ํ•ญ์ƒ ๊ฑฑ์ •์€ ๋งŽ์€ ๊ฒƒ ๊ฐ™๋‹ค. ์ฒซ๋ฒˆ์งธ๋กœ ๊ดœ์ฐฎ์€ ๊ธฐ์—…์— ๋“ค์–ด๊ฐ€์„œ ๋งŽ์ด ๋ฐฐ์šฐ๊ณ  ์„ฑ์žฅํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ์— ๋‚˜๋ฅผ ์ข€ ๋” ์„ฑ์žฅ์‹œ์ผœ์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ๋‚ด ํ•™์ƒ ์ธ์ƒ์˜ ๋งˆ์ง€๋ง‰ ํ•™๊ธฐ๊ฐ€ ์‹œ์ž‘๋œ๋‹ค. ์กธ์—…์š”๊ฑด๋„ ์ƒ๊ฐํ•˜๊ณ  ๋ฌผ๋ก  ๋ฐฐ์šธ์ˆ˜์žˆ๋Š” ์ข‹์€ ํšŒ์‚ฌ์— ๋“ค์–ด๊ฐ€์„œ ์ทจ์—…๊ณ„ ๋‚ด์„œ ์กธ์—…ํ•˜๋ฉด ์ตœ๊ณ Best๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋งˆ์ง€๋ง‰ 4ํ•™๋…„ 2ํ•™๊ธฐ๊ฐ€ ๋๋‚˜๊ณ  ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ๋์„์ง€ ๊ถ๊ธˆํ•˜๋ฉด์„œ ๊ฑฑ์ •๋œ๋‹ค. ์ž˜ ๋์Œ ์ข‹๊ฒ ๋„ค.

๋ฐฑ์—”๋“œ ์Šคํ„ฐ๋”” (3)


์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Spring์—์„œ JPQL(Java Persistence Query Language)๊ณผ Spring Data JPA๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์Šคํ„ฐ๋””ํ•œ ๋‚ด์šฉ์„ ๊ณต์œ ํ•˜๊ณ ์ž ํ•œ๋‹ค. JPQL์€ SQL๊ณผ ์œ ์‚ฌํ•œ ๋ฌธ๋ฒ•์„ ๊ฐ€์ง€๋ฉด์„œ๋„ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ ํ•ฉํ•˜๋‹ค. ๋˜ํ•œ Spring Data JPA๋Š” ๊ฐ„๋‹จํ•œ ์ฟผ๋ฆฌ์—์„œ๋ถ€ํ„ฐ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ๊นŒ์ง€ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

๊ตฌ์กฐ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ

Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฃผ์š” ๊ตฌ์„ฑ๋“ค๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๋Š”๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

  • Controller : ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ HTTP ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

  • Service : ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ €์žฅ์†Œ์™€ ์ƒํ˜ธ์ž‘์šฉํ•œ๋‹ค.

  • Repository : ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋ฉฐ, CRUD ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

  • DTO : ๋ฐ์ดํ„ฐ ์ „์†ก ๊ฐ์ฒด๋กœ, ๊ณ„์ธต ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

ํŒจํ‚ค์ง€ ๊ตฌ์กฐ

๋‹ค์Œ์€ ์ผ๋ฐ˜์ ์ธ Spring ํ”„๋กœ์ ํŠธ์˜ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ๋‹ค.

  • config : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ • ํŒŒ์ผ์ด ์œ„์น˜ํ•˜๋Š” ํŒจํ‚ค์ง€

  • controller : HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ ํด๋ž˜์Šค๊ฐ€ ์œ„์น˜

  • domain : ๋„๋ฉ”์ธ ๊ฐ์ฒด๋“ค์ด ์ •์˜๋œ ๊ณณ

  • repository : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ๋‹ด๋‹นํ•˜๋Š” ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ํด๋ž˜์Šค๊ฐ€ ์œ„์น˜

  • service : ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋‹ด๋‹นํ•˜๋Š” ์„œ๋น„์Šค ํด๋ž˜์Šค๊ฐ€ ์œ„์น˜


JPQL (Java Persistence Query Language)

JPQL์€ ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” Java Persistence API์˜ ์ฟผ๋ฆฌ ์–ธ์–ด์ด๋‹ค. SQL๊ณผ ๋ฌธ๋ฒ•์ด ๋น„์Šทํ•˜์ง€๋งŒ ํ…Œ์ด๋ธ”์ด ์•„๋‹Œ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

JPQL ๊ธฐ๋ณธ ์˜ˆ์‹œ

@PersistenceContext
EntityManager em;

public void main save(Board board) {
	em.persist(board);
}

EntityManager๋ฅผ ํ†ตํ•ด Board ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค€๋‹ค.
JPQL์„ ์‚ฌ์šฉํ•˜๋ฉด SQL๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

JPQL๋กœ ๋ฐ์ดํ„ฐ ์กฐํšŒ

JPQL์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ๋Š” @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

@Query("SELECT c FROM ChatRoom c WHERE c.roomId = :roomId")
ChatRoom findChatRoomByRoomId(@Param("roomId") String roomId);

์œ„ ์ฝ”๋“œ๋Š” ChatRoom ์—”ํ‹ฐํ‹ฐ์—์„œ ํŠน์ • roomId ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” JPQL ์ฟผ๋ฆฌ์ด๋‹ค.


์—ฐ๊ฒฐ

Spring Data JPA์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„ค์ • ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ์ •๋ณด๋ฅผ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค.

dependencies {
	implementation'org.mariadb.jdbc:mariadb-java-client:3.1.2'
    implementation'org.springframework.boot:spring-boot-starter-data-jpa'
}
-----------------------------------------------
spring:
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://localhost:8080/yourdb
    username: ์‚ฌ์šฉ์ž์ด๋ฆ„
    password: ๋น„๋ฐ€๋ฒˆํ˜ธ

Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด MariaDB์™€ ์—ฐ๊ฒฐ๋˜๋„๋ก ์„ค์ •ํ•œ๋‹ค.


JPA ์‹ค์Šต

์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค ์ •์˜

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Gyumin {
    @Id
    @Column(name = "Mccc_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String roomId;
    private String fileName;
    private String code;
    
    // ์ƒ์„ฑ์ž
    public Gyumin(String roomId, String fileName, String code) {
        this.roomId = roomId;
        this.fileName = fileName;
        this.code = code;
    }
}

์œ„ ํด๋ž˜์Šค๋Š” Gyumin ์ด๋ผ๋Š” ์—”ํ‹ฐํ‹ฐ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ๊ณผ ๋งคํ•‘๋œ๋‹ค. ๊ฐ ํ•„๋“œ๋Š” id, roomId, fileName, code์™€ ๊ฐ™์ด ์ •์˜๋˜์—ˆ๊ณ  @Id๋กœ ๊ธฐ๋ณธ ํ‚ค๊ฐ€ ์ง€์ •๋˜์—ˆ๋‹ค.

Repository ์ธํ„ฐํŽ˜์ด์Šค

JPA์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ Repository ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ๋‹ค. SnapshotRespository ์ธํ„ฐํŽ˜์ด์Šค๋Š” MongoDB์™€ JPA๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค€๋‹ค.

public interface SnapshotRepository extends MongoRepository<Snapshot, String> {
    Snapshot findByRoomId(String roomId);
    List<Snapshot> findSnapshotsByRoomId(String roomId);
    Snapshot findByRoomIdAndFileName(String roomId, String fileName);
}

์œ„ ์ฝ”๋“œ๋Š” SnapshotRepository๋ฅผ ํ†ตํ™ฐ roomId๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค€๋‹ค. findByRoomId๋Š” roomId ๊ฐ’์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ findSnapshotsByRoomId๋Š” ๋™์ผํ•œ roomId๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ Snapshot ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

JPQL์„ ์‚ฌ์šฉํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ

JPA์—์„œ๋Š” @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ JPQL ์ฟผ๋ฆฌ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

public interface ManageRepository extends JpaRepository<Manage, Long> {
    
    @Query("select m from Manage m " +
           "where m.team.id = :teamId " +
           "order by m.createDate")
    List<Manage> findManagesByTeamId(@Param("teamId") Long teamId);
}

์œ„ ์ฝ”๋“œ์—์„œ๋Š” @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ง์ ‘ JPQL ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜์˜€๊ณ , teamId ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ team.id์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•œ๋‹ค. @Param ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ”์ธ๋”ฉํ•œ๋‹ค.


๋ฒŒํฌ์„ฑ ์ฟผ๋ฆฌ (Builk Queries)

๋ฒŒํฌ์„ฑ ์ฟผ๋ฆฌ๋Š” ๋‹ค์ˆ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ๋•Œ ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ์œ ๋ฆฌํ•˜๋‹ค.

๋ฒŒํฌ ์—…๋ฐ์ดํŠธ ์˜ˆ์‹œ

@Modifying
@Query("UPDATE Member m SET m.age = m.age + 1 WHERE m.age >= :age")
int bulkUpdateAge(@Param("age") int age);

์œ„ ์ฟผ๋ฆฌ๋Š” age ๊ฐ’์ด ์ผ์ • ์ˆ˜์ค€ ์ด์ƒ์ธ ํšŒ์›๋“ค์˜ ๋‚˜์ด๋ฅผ ์ผ๊ด„์ ์œผ๋กœ 1์”ฉ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๋ฒŒํฌ ์—…๋ฐ์ดํŠธ ์ฟผ๋ฆฌ์ด๋‹ค. @Modifying ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์—…๋ฐ์ดํŠธ ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.


์ด๋ฒˆ์—๋Š” Spring์—์„œ JPQL๊ณผ JPA๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•˜๋‹ค. JPQL์„ ํ†ตํ•ด ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋„ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ฒŒํฌ์„ฑ ์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์•ž์œผ๋กœ ๋” ๋ณต์žกํ•œ JPQL ์ฟผ๋ฆฌ ์ž‘์„ฑ๋ฒ•๊ณผ ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์„ ๋” ์•Œ์•„๋ณด์ž
profile
ํ˜๋Ÿฌ๊ฐ€๋˜ ์›ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ

0๊ฐœ์˜ ๋Œ“๊ธ€