Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("mysql:mysql-connector-java:8.0.33")

implementation ("org.antlr:antlr4-runtime:4.10.1")


// PostgreSQL + PostGIS
implementation("org.postgresql:postgresql:42.7.3") // 최신 버전 확인
implementation ("org.hibernate.orm:hibernate-spatial:6.2.7.Final") // 최신 Hibernate 6
implementation("org.hibernate.orm:hibernate-core:6.2.7.Final")

// Geometry 관련
implementation ("org.locationtech.jts:jts-core:1.18.2")

compileOnly("org.projectlombok:lombok")
testCompileOnly("org.projectlombok:lombok")
testAnnotationProcessor("org.projectlombok:lombok")
Expand Down
21 changes: 21 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
postgres:
image: postgis/postgis:15-3.3
container_name: log4u_postgres
environment:
POSTGRES_DB: gis_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: 1234
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
- ./docker/init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- log4u-net

volumes:
pgdata:

networks:
log4u-net:
81 changes: 81 additions & 0 deletions src/main/java/com/example/log4u/common/config/MySqlConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.example.log4u.common.config;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
@EnableJpaRepositories(
basePackages = {
"com.example.log4u.common",
"com.example.log4u.domain.comment",
"com.example.log4u.domain.diary",
"com.example.log4u.domain.follow",
"com.example.log4u.domain.like",
"com.example.log4u.domain.media",
"com.example.log4u.domain.reports",
"com.example.log4u.domain.supports",
"com.example.log4u.domain.user"
},
entityManagerFactoryRef = "mysqlEntityManagerFactory",
transactionManagerRef = "mysqlTransactionManager"
)
public class MySqlConfig {

@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource mysqlDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "mysqlEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(mysqlDataSource());
em.setPackagesToScan(
"com.example.log4u.common",
"com.example.log4u.domain.comment",
"com.example.log4u.domain.diary",
"com.example.log4u.domain.follow",
"com.example.log4u.domain.like",
"com.example.log4u.domain.media",
"com.example.log4u.domain.reports",
"com.example.log4u.domain.supports",
"com.example.log4u.domain.user"
);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(true);
vendorAdapter.setGenerateDdl(true);
em.setJpaVendorAdapter(vendorAdapter);

Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
properties.put("hibernate.hbm2ddl.auto", "update");
properties.put("hibernate.format_sql", true);
em.setJpaPropertyMap(properties);

return em;
}

@Bean(name = "mysqlTransactionManager")
@Primary
public PlatformTransactionManager mysqlTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(mysqlEntityManagerFactory().getObject());
return transactionManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.example.log4u.common.config;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
@EnableJpaRepositories(
basePackages = {
"com.example.log4u.domain.map.repository"
},
entityManagerFactoryRef = "postgresqlEntityManagerFactory",
transactionManagerRef = "postgresqlTransactionManager"
)
public class PostgreSqlConfig {

@Bean
@ConfigurationProperties(prefix = "spring.second-datasource")
public DataSource postgresqlDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "postgresqlEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean postgresqlEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(postgresqlDataSource());
em.setPackagesToScan("com.example.log4u.domain.map.entity");

HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(true);
vendorAdapter.setGenerateDdl(true);
em.setJpaVendorAdapter(vendorAdapter);

Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.hbm2ddl.auto", "none");
properties.put("hibernate.format_sql", true);
em.setJpaPropertyMap(properties);

return em;
}

@Bean(name = "postgresqlTransactionManager")
public PlatformTransactionManager postgresqlTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(postgresqlEntityManagerFactory().getObject());
return transactionManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.log4u.common.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import com.querydsl.jpa.impl.JPAQueryFactory;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

@Configuration
public class PostgresQuerydslConfig {

@PersistenceContext(unitName = "postgresqlEntityManagerFactory")
private EntityManager postgresEntityManager;

@Bean(name = "postgresJPAQueryFactory")
public JPAQueryFactory postgresJPAQueryFactory() {
return new JPAQueryFactory(postgresEntityManager);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.querydsl.jpa.impl.JPAQueryFactory;

Expand All @@ -17,6 +18,7 @@ public QueryDslConfig(EntityManager entityManager) {
}

@Bean
@Primary
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
import com.example.log4u.domain.diary.exception.OwnerAccessDeniedException;
import com.example.log4u.domain.diary.repository.DiaryRepository;
import com.example.log4u.domain.follow.repository.FollowRepository;
import com.example.log4u.domain.map.service.MapService;
import com.example.log4u.domain.media.entity.Media;
import com.example.log4u.domain.media.service.MediaService;
import com.example.log4u.domain.user.repository.UserRepository;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -34,9 +34,9 @@
public class DiaryService {

private final DiaryRepository diaryRepository;
private final UserRepository userRepository;
private final FollowRepository followRepository;
private final MediaService mediaService;
private final MapService mapService;

// 다이어리 생성
@Transactional
Expand All @@ -46,6 +46,7 @@ public void saveDiary(Long userId, DiaryRequestDto request) {
DiaryRequestDto.toEntity(userId, request, thumbnailUrl)
);
mediaService.saveMedia(diary.getDiaryId(), request.mediaList());
mapService.increaseRegionDiaryCount(request.latitude(), request.longitude());
}

// 다이어리 검색
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.example.log4u.domain.map.controller;

import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.log4u.domain.map.dto.response.DiaryClusterResponseDto;
import com.example.log4u.domain.map.service.MapService;

import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@Tag(name = "지도 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/maps")
public class MapController {

private final MapService mapService;

@GetMapping("/diaries/cluster")
public ResponseEntity<List<DiaryClusterResponseDto>> getDiaryClusters(
@RequestParam double south,
@RequestParam double north,
@RequestParam double west,
@RequestParam double east,
@RequestParam int zoom
) {
List<DiaryClusterResponseDto> clusters = mapService.getDiaryClusters(south, north, west, east, zoom);
return ResponseEntity.ok(clusters);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.log4u.domain.map.dto.response;

import com.querydsl.core.annotations.QueryProjection;

public record DiaryClusterResponseDto(
String areaName,
Long areaId,
Double lat,
Double lon,
Long diaryCount
) {

@QueryProjection
public DiaryClusterResponseDto {
}

}
35 changes: 35 additions & 0 deletions src/main/java/com/example/log4u/domain/map/entity/SidoAreas.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.log4u.domain.map.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.locationtech.jts.geom.Geometry;

@Entity
@Getter
@NoArgsConstructor
@Table(name = "sido_areas", schema = "public")
public class SidoAreas {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false)
private String code;

@Column(nullable = false)
private String name;

@Column(columnDefinition = "geometry")
private Geometry geom;

@Column(columnDefinition = "geometry")
private Geometry center;

@Column(nullable = false)
private Double lat;

@Column(nullable = false)
private Double lon;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.example.log4u.domain.map.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "sido_areas_diary_count", schema = "public")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class SidoAreasDiaryCount {

@Id
@Column(name = "id")
private Long id;

@Column(name = "diary_count")
private Long diaryCount;


public void incrementCount() {
this.diaryCount++;
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/example/log4u/domain/map/entity/SidoCodeMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.log4u.domain.map.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
@Table(name = "province_code_map", schema = "public")
public class SidoCodeMap {

@Id
@Column(length = 2)
private String code;

@Column(nullable = false)
private String name;
}
Loading