Light Blue Pointer
본문 바로가기

Journal16

웹소켓 Subscribe시에 Interceptor에서 채팅방 권한을 조회하도록 함 지난번에 이렇게 해서 웹소켓 연결을 했는데  Spring과 STOMP를 이용해서 웹소켓 연결하기Gradle에 필요한 설정 import // WebSocket implementation("org.springframework.boot:spring-boot-starter-websocket") implementation("com.fasterxml.jackson.core:jackson-databind") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implegreedydeveloper.tistory.com연결해두고 보니 아무나 특정 채팅방이나 서버를 Subscribe할 수 있는 구조라 보안 이슈가 있을 것 같았다 그래서 Intercep.. 2024. 11. 5.
Spring과 STOMP를 이용해서 웹소켓 연결하기 Gradle에 필요한 설정 import // WebSocket implementation("org.springframework.boot:spring-boot-starter-websocket") implementation("com.fasterxml.jackson.core:jackson-databind") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") // Web Security implementation("org.spr.. 2024. 9. 26.
Spring에서 MongoDB 이용할때의 Pagination : MongoTemplate 으로 List<Model> , Page<Model> 리턴 Pageable pageable = new PageRequests(page, size);Query query = new Query().with(pageable);List list = mongoTemplate.find(query, XXX.class);return PageableExecutionUtils.getPage( list, pageable, () -> mongoTemplate.count(Query.of(query).limit(-1).skip(-1), XXX.class));이렇게 하면 mongoTemplate이 Page를 지원하지 않는다고 해도 PageableExecutionUtils을.. 2024. 9. 22.
QueryDSL로 검색 기능 구현 + 쿼리 빌드 단계적으로 하기 + LocalDateTime을 Controller의 Parameter로 받을 때 주의할 점 QueryDSL 설정법은 여기로 QueryDSL 설정일단 gradle에 관련 설정들을 추가해준다plugins { id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'}configurations { compileOnly { extendsFrom annotationProcessor }}repositories { mavenCentral()}dependencies { implementation 'org.springfrgreedydeveloper.tistory.com 오늘 여러 조건에 따라서 검색을 해야하는 쿼리를 작성해야 했는데검색할때 쿼리가 null인 경우를 모두 메서드로 분리해서 하지 않고 null이거나 비어있으면 제외하고 쿼리를 빌드하는 코드를 작성해 보았다 .. 2024. 9. 5.
@EnableJpaAuditing 이 한 곳에서만 정의되어야 하는 이유 습관처럼 QueryDsl을 사용하기 위해 JPAConfig를 만들려고 했다@Configuration@EnableJpaAuditingpublic class JPAConfig { @PersistenceContext private EntityManager entityManager; @Bean public JPAQueryFactory queryFactory() { return new JPAQueryFactory(entityManager); }}  그랬더니 다른 곳에서 이미 JPAAuditoing이 되고 있어서 안 된다는 에러가 떴다 overriding = true로 바꾸라는 제안도 있었지만 위험할 것 같아서 하지 않았다 찾아보니 동일한 모듈에 이게 있었다@Configura.. 2024. 9. 5.
QueryDSL 설정 일단 gradle에 관련 설정들을 추가해준다plugins { id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'}configurations { compileOnly { extendsFrom annotationProcessor }}repositories { mavenCentral()}dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.mysql:mysql-connector-j' implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' .. 2024. 9. 5.
Spatial Index 전환기 프로젝트에서 거리순 정렬이 필요했는데 기존에는 그냥 QueryDSL로 Order By 유클리드 거리를 하고 있었다.너무 비효율적이라는 생각이 들어서 더 좋은 방법이 없나 찾아보다가 공간 인덱스를 발견했다.https://www.baeldung.com/hibernate-spatial 결론부터 말하자면 적용 후 성능이 151ms 에서 63ms 으로 58.28% 개선되었다Hibernate-Spatial 개념 정리 → 링크 나에게 필요한 것은 특정한 좌표들을 비교하는 일이니까 Point를 선택해서 썼다우선 관련된 설정을 해준다 latitude와 longitude를 Point로 바꿔줬다⚠️주의⚠️경도 longitude → x위도 latitude → y    @Column private Double lati.. 2024. 8. 1.
한 시간 후 만료되는 초대 링크 개발기 : DB 구성에 대한 고민 디스코드 클론코딩 서비스를 개발하면서채팅방 입장 링크를 발급해준 후 한시간 후 만료시키고만료되지 않은 코드라면 참여가 가능하게 해야하는 기능을 개발해야했다 Key:Value 형태로 간단하게 저장할 수 있을 것 같고 만료되는 기능도 TTL로 하기 쉬운 Redis를 쓰기로 했는데, 코드 발급 시에는 채팅방id, userId -> 코드 이렇게 접근해야 했고코드로 참여 시에는 코드 -> 채팅방 id 이렇게 접근해야 했다 그러나 Redis는 Key로 Value를 찾는 것은 효율적인 반면, Value로 Key를 찾는 것은 효율적이지 않아서처음에는 채팅방id, userId -> 코드, 코드 -> 채팅방 id 이렇게 DB를 두개로 나눠서 저장했다  @Serviceclass ChatRoomService( private.. 2024. 6. 20.
Service에서 다른 Service 를 의존하게 하기 채팅방 기능을 개발할 때 ChatRoomService에서 좀 동떨어진 Invitation 관련 기능들을 많이 이용하게 되었는데그게 ChatRoomService에 있으면 좀 의미가 맞지 않는 것 같아서 모두 InvitationRepository로 분리해서 코드를 구축했다@Serviceclass ChatRoomService( private val chatRoomRepository: ChatRoomRepository, private val invitationRepository: InvitationRepository,) {fun getChatRoomInvitation( chatRoomId: String, userId: String, ): InvitationResponse { verifyCh.. 2024. 6. 20.