250106 에이콘 아카데미 수업에 기반하여 작성되었음을 알립니다.
MongoDB - Spring Boot (CRUD)
프로젝트 생성
Customer
@Document(collection = "customer") // JPA에서 @Entity와 같은 역할, collection은 table
@Getter
@Setter
public class Customer {
@Id
private String id;
private String name;
private int age;
private String gender;
@Override
public String toString() {
return "Customer{" + "id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender +"}";
}
}
CustomerRepository
public interface CustomerRepository extends MongoRepository<Customer, String> {
Customer findByName(String name);
}
CustomerService
@Service
public class CustomerService {
@Autowired
private CustomerRepository customerRepository;
public void printAllCustomers() { // 전체 자료 읽기
customerRepository.findAll().forEach(customer -> {
System.out.println(customer);
});
}
public void insCustomer(String name, int age, String gender) { // 추가
Customer exCustomer = customerRepository.findByName(name);
if(exCustomer == null) { // 동일한 고객명이 없는 경우만 추가
Customer newCustomer = new Customer();
newCustomer.setName(name);
newCustomer.setAge(age);
newCustomer.setGender(gender);
customerRepository.save(newCustomer);
System.out.println("고객 추가 성공" + newCustomer);
} else {
System.out.println("동일 고객명 존재");
}
}
public void upCustomer(String name) { // 수정
Customer exCustomer = customerRepository.findByName(name);
if(exCustomer != null) { // 나이와 성별 수정
exCustomer.setAge(33);
exCustomer.setGender("여");
customerRepository.save(exCustomer);
System.out.println("고객 수정 성공" + exCustomer);
} else {
System.out.println("고객 찾기 실패");
}
}
public void delCustomer(String name) { // 삭제
Customer exCustomer = customerRepository.findByName(name);
if(exCustomer != null) {
customerRepository.delete(exCustomer);
System.out.println("고객 삭제 성공" + exCustomer);
} else {
System.out.println("고객 찾기 실패");
}
}
}
MainController
@Controller
public class MainController {
@GetMapping("/")
public String start() {
return "index";
}
}
CustomerController
@RestController
public class CustomerController {
@Autowired
private CustomerService customerService;
@GetMapping("/alldata")
public String alldata() {
customerService.printAllCustomers();
return "전체 자료 출력";
}
@PostMapping("/insdata")
public String insdata(@RequestParam(name="name") String name,
@RequestParam(name="age") int age,
@RequestParam(name="gender") String gender) {
customerService.insCustomer(name, age, gender);
return "고객 추가 성공";
}
@PutMapping("/updata")
public String updata(@RequestParam(name="name") String name) {
customerService.upCustomer(name);
return "고객 수정 성공";
}
@DeleteMapping("/deldata")
public String deldata(@RequestParam(name="name") String name) {
customerService.delCustomer(name);
return "고객 삭제 성공";
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/alldata">전체 자료 읽기</a>
</body>
</html>
MongoDB - Spring Boot (Security 적용)
build.gradle
... 생략
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.mongodb:mongodb-driver-sync:5.2.0' // 따로 입력해서 의존성 설정해줘야함
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
... 생략
application.properties
spring.application.name=aaaaa
# MongoDB 설정
spring.data.mongodb.uri=mongodb://localhost:27017/movieapp
# 활성화된 프로파일
spring.profiles.active=default
logging.level.org.springframework.data.mongodb.core=DEBUG
Movie
@Document(collection = "movies")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
@Id
private String id;
private String title;
private String genre;
private double rating;
}
MovieRepository
@Repository
public interface MovieRepository extends MongoRepository<Movie, String> {
List<Movie> findByGenre(String genre);
}
SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/css/**", "/js/**").permitAll() // 로그인 페이지 허용
.anyRequest().authenticated())
//.requestMatchers("/api/movies/**").authenticated()) // 인증 필요
.formLogin(form -> form
.loginPage("/login").permitAll() // 커스텀 로그인 페이지
.defaultSuccessUrl("/api/movies", true)) // 로그인 성공 후 이동
.logout(logout -> logout.permitAll()) // 로그아웃 허용
.exceptionHandling(ex -> ex
.authenticationEntryPoint((request, response, authException) -> {
response.sendRedirect("/login");
})); // 인증되지 않은 요청에 대해 /login으로 리다이렉트
return http.build();
}
}
UserConfig
@Configuration
public class UserConfig {
@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.builder()
.username("kor")
.password(passwordEncoder.encode("123"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
LoginController
@Controller
public class LoginController {
@GetMapping({"/", "/login"})
public String login() {
return "login";
}
}
MovieController
@RestController
@RequestMapping("/api/movies")
public class MovieController {
private final MovieRepository movieRepository;
public MovieController(MovieRepository movieRepository) {
this.movieRepository = movieRepository;
}
@GetMapping
public List<Movie> getAllMovies() {
return movieRepository.findAll();
}
@PostMapping
public Movie addMovie(@RequestBody Movie movie) {
return movieRepository.save(movie);
}
@GetMapping("/recommend/{genre}")
public List<Movie> recommendMovies(@PathVariable(name="genre") String genre) {
return movieRepository.findByGenre(genre);
}
}
MyErrorController
@Controller
public class MyErrorController implements ErrorController {
@GetMapping("/error")
public String handleError(HttpServletRequest request) {
// 모든 에러를 /login으로 리다이렉트
return "redirect:/login";
}
}
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>로그인</h1>
<form method="post" action="/login">
Username : <input type="text" name="username" required><br>
Password : <input type="password" name="password" required><br><br>
<button type="submit">확인</button>
</form>
</body>
</html>
추가
읽기
MongoDB - 대용량 데이터
🙏 GridFS를 사용해 MongoDB에 대용량 파일을 저장
웹상의 구조가 다른 데이터를 가져오고 저장하는 방법 중 NoSQL인 MongoDB를 활용해보자!
프로젝트 생성
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>aa</groupId>
<artifactId>mongo04_bigdata</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongodb-driver-sync -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>5.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.opencsv/opencsv -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.8</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
</dependency>
</dependencies>
</project>
',' 로 request, response를 구분하고 있다.
MongoDbUpload (저장)
public class MongoDbUpload {
public static void main(String[] args) {
String connString = "mongodb://localhost:27017";
try (MongoClient mongoClient = MongoClients.create(connString)) {
MongoDatabase database = mongoClient.getDatabase("katalkdb");
// GridFSBucket 생성 (분산 저장용)
GridFSBucket gridFSBucket = GridFSBuckets.create(database, "katalkfiles");
// resource 폴더에서 CSV 파일 읽기
ClassLoader classLoader = MongoDbUpload.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("katalkdata.csv");
if(inputStream != null) {
uploadCSVtoMongoDB(inputStream, gridFSBucket);
} else {
System.out.println("CSV 찾기 실패");
}
} catch (Exception e) {
System.out.println("err : " + e);
}
}
private static void uploadCSVtoMongoDB(InputStream inputStream, GridFSBucket gridFSBucket) {
try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
CSVReader csvReader = new CSVReader(reader)) {
List<String[]> records = csvReader.readAll();
for(String[] record : records) {
Document doc = new Document("req", record[0]).append("res", record[1]);
// 대용량 자료를 1MB 크기의 청크(묶음)로 나누어 저장
GridFSUploadOptions options = new GridFSUploadOptions().chunkSizeBytes(1024 * 1024);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(doc.toJson().getBytes());
ObjectId fileId = gridFSBucket.uploadFromStream("katalkdata", byteArrayInputStream, options);
System.out.println("saved id : " + fileId.toHexString());
}
} catch (Exception e) {
System.out.println("uploadCSVtoMongoDB err" + e);
}
}
}
실행 후 저장 확인
MongoDbDownload (읽기)
public class MongoDbDownload {
public static void main(String[] args) {
// GridFS로 저장된 MongoDB 자료 읽기
String connString = "mongodb://localhost:27017";
try (MongoClient mongoClient = MongoClients.create(connString)) {
MongoDatabase database = mongoClient.getDatabase("katalkdb");
GridFSBucket gridFSBucket = GridFSBuckets.create(database, "katalkfiles");
MongoCursor<GridFSFile> cursor = gridFSBucket.find().iterator();
while(cursor.hasNext()) {
GridFSFile gridFSFile = cursor.next();
ObjectId fileId = gridFSFile.getObjectId();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
gridFSBucket.downloadToStream(fileId, byteArrayOutputStream);
String fileContent = new String(byteArrayOutputStream.toByteArray());
//System.out.println("fileContent : " + fileId.toHexString() + ": " + fileContent);
//fileContent : 677b43c868a3cc40025c971d: {"req": "너 좋아하는 차 종류 있어?", "res": "무슨 차? 자동차? 마시는 차?"}
// 배열 형태인 경우
if(fileContent.trim().startsWith("[")) {
JSONArray jsonArray = new JSONArray(fileContent);
for(int i=0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String req = jsonObject.getString("req");
String res = jsonObject.getString("res");
System.out.println("req : " + req + ", res : " + res);
}
} else {
// 단일 JSON 객체인 경우
JSONObject jsonObject = new JSONObject(fileContent);
String req = jsonObject.getString("req");
String res = jsonObject.getString("res");
System.out.println("req : " + req + ", res : " + res);
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
System.out.println("err : " + e);
}
}
}
실행 후 읽기 확인
'Study > Acorn' 카테고리의 다른 글
250107 MongoDB (웹 데이터 저장/읽기) (0) | 2025.01.07 |
---|---|
250103 MongoDB (Java - CRUD, 동적인 칼럼 처리) (0) | 2025.01.03 |
250102 MongoDB (개념, 설치, 기본 CRUD, Java 연동) (0) | 2025.01.02 |
241231 도커 (nodejs 웹서버, 우분투 자바 설치, 도커 허브 푸쉬) (0) | 2024.12.31 |
241230 도커 (설치, 기본명령어) (0) | 2024.12.30 |