목록분류 전체보기 (108)
어리바리 신입 개발자의 얼렁뚱땅 개발 기록 ✨
JPA(Java Persistence API) - 자바의 ORM(Object-Relational Mapping) 표준 스펙을 정의하는 인터페이스의 모음 - ORM : 객체와 관계형 데이터베이스(RDB) 사이의 데이터 변환을 자동화하기 위한 기술 - 즉, 자바의 객체와 RDB를 어떻게 매핑하고 동작해야하는지 정의하고 있는 것이 JPA [ 장점 ] - SQL문을 사용하지 않고 메서드를 통해 DB를 조작하기 때문에 개발자는 비즈니스 로직을 구성하는 것에만 집중할 수 있다. (어떤 쿼리를 실행해야 하는지만 생각하면 된며, 예측도 쉽다.) - 부수적인 코드를 줄이고 객체에 대한 코드를 작성하기 때문에 코드의 가독성을 높일 수 있다. (반복적인 CRUD 쿼리를 처리해준다.) - 객체 지향적인 코드를 작성할 수 있기..

[ 첨부파일의 존재여부를 확인하기 위한 방법 ] 1. 이미 구현해둔 첨부파일 정보 받아오는 쿼리를 그대로 사용한다. (파일과 관련된 모든 정보를 가져오기 때문에 효율적이지 않은 것 같다.) 2. dto와 mapper에 첨부파일의 존재여부를 확인하는 새로운 필드와 쿼리를 생성한다. 3. 기존 게시글 목록 조회 쿼리에 첨부파일의 존재여부를 확인하는 쿼리를 추가한다. - 새로 생성하거나 추가한다면 COUNT와 EXISTS 중 무슨 쿼리를 사용할 것인가? COUNT는 데이터의 수를 EXISTS는 데이터의 존재여부를 확인한다. EXISTS를 사용해 파일의 여부만 체크하기로 함(존재하면 1 존재하지않으면 0 반환) 어차피 파일 여부를 확인하는 쿼리는 게시글 조회시에만 필요할 것 같아서 기존 쿼리에 추가하기로 함 이..

[ DTO VS VO] - DTO (Data Transfer Object) / 가변 객체 데이터를 계층간 교환하기 위해 사용한다. 즉, 로직을 가지지 않는 순수하게 데이터를 담고 전달하는 객체이다. 때문에 getter, setter, toString 정도의 메서드만 갖고 있다. - VO (Value Object) / 불변 객체 Read-Only의 특징을 지닌다. 즉, 데이터를 전달만 할 뿐 setter가 존재하지 않는다. 불변 객체라는 게 무슨 뜻이지...? 값이 바뀌지 않고 오직 Read만 한다고..? 값이 바뀌지 않는다면 그냥 상수를 말하는 거 아닌가? 상수를 쓸거면 굳이 VO를 쓸 이유가 있나? 라는 생각을했는데 VO는 setter가 아니라 반듯이 생성자를 생성해서 사용한다는 점에서 불변 객체라는거..

먼저 이미 첨부되어 있는 파일을 글 수정 과정에서 삭제하기 위해서 html과 자바스크립트를 이용해서 화면과 이벤트 핸들러를 구현해야 한다. [ 현재 상태 ] - 첨부 파일이 있다면 첨부파일 목록이 나타나게만 해둔 상태 [ 첨부파일 ] [ 게시글 수정에서 필요한 로직 ] 1. 게시글 수정 (이미 게시글 수정 구현 과정에서 구현되어있음) 2. 이전에 첨부되어있던 파일 삭제(할 수도 있고 안 할 수도 있다.) - 첨부파일이 존재한다면 옆에 파일 삭제 버튼도 같이 보여야 한다. - 파일 삭제 버튼을 누른다고 해서 바로 삭제되는 것은 아니다. - 파일 삭제 버튼을 누르면 파일 삭제 버튼이 삭제 취소 버튼으로 바뀐다. - 삭제 취소 버튼을 누르면 다시 파일 삭제 버튼으로 바뀐다. - 최종적으로 수정 완료 버튼을 눌..
[ 다운로드를 구현하기 전에 알아둘 것들 ] - HttpSevletRquest 사용자로부터 들어오는 모든 요청 정보를 담고 있다. - HttpSevletResponse 사용자에게 전달할 데이터를 담고 있다. 즉, 사용자에게 전달할 데이터를 원하는 상태로 설정해서 전달 가능하게 한다. - ResponseEntity HTTP 응답의 상태 코드, 헤더, 본문 / RESTful 웹 서비스에서 응답을 보다 세밀하게 제어하기 위해 사용 - HttpSevletResponse VS ResponseEntity 둘 다 HTTP 응답을 처리하기 위해 사용된다. HttpServletResponse가 더 세밀한 응답 조작이 가능하지만, ResponseEntity를 사용하면 높은 수준의 추상화와 간결한 코드를 만들 수 있다. 낮..

파일 크기 제한이 있다보니 파일 크기를 넘어가면 MaxUploadSizeExceededException 오류가 발생한다. 프로퍼티 파일에 다음 코드를 추가해서 체크 시점을 지연시킨 후 # 원래 파일 업로드시 HTTP 요청 데이터가 스프링 MVC의 컨트롤러 메서드로 전달되기 전 # 즉, 요청 파싱 단계에서 파일 크기를 체크해서 에러를 발생시킨다고 한다. # 그래서 해당 파일에 접근하는 시점에 파일을 체크하게 한다. (체크 시점을 지연시키는 것) spring.servlet.multipart.resolve-lazily=true 컨트롤러에 예외 처리를 해줘도 되지만, @ExceptionHandler(MaxUploadSizeExceededException.class) public String handleMaxU..

원래는 게시글 등록할 때 첨부파일 업로드도 같이 구현해줬어햐 하는데... 첨부파일 구현 경험이 없어서 일단 CRUD 부터 다 끝내고 첨부파일 구현 시작! [ MultipartResolver] 클라이언트로부터 데이터를 전송 받을 때 폼 데이터만 전송 받는 경우도 있지만, 폼 데이터와 함께 파일 같은 데이터도 같이 전송 받는 경우가 있다. 이런 다중 부분 데이터를 처리하기 위해 스프링에서 제공하는 인터페이스다. 주로 파일 업로드와 다운로드에 사용된다. 스프링부트에는 이미 기본 빈으로 등록되어 있기 때문에 따로 처리해줄 필요가 없다. 1. CommonsMultipartResolver (Apache Commons FileUpload를 사용) 2. StandardServletMultipartResolver (Se..
[ 문제 ] 1. 첫 번째 줄에는 문자열을 입력 받을 횟수를 받는다. 2. 두 번째 줄에는 문자열을 문자 단위로 반복하는 횟수 + 공백 + 문자열을 받는다. 3. 출력은 문자 단위로 입력 받은 만큼 반복하는 방식으로 수정된 문자열만 출력하되 각 문자열은 개행해서 출력한다. [ 예시 - 입력 형태 ] 2 3 ABC 5 /HTP [ 예시 - 출력 형태 ] AAABBBCCC /////HHHHHTTTTTPPPPP 기본적으로 for문과 charAt를 이용해서 코드를 작성하고 조금씩 다르게 총 4가지로 수정해봤는데 크게 차이는 없는 듯 하다. [ 1. BufferedWriter의 write() 이용해서 바로 담기 ] 속도 : 124 ms BufferedReader br = new BufferedReader (new..
RESTful한 게시판을 만들기 위해서 중요한 것은 CRUD에 맞게 HTTP Method를 작성해주는 것이다. 즉, CRUD 중 UPDATE 와 DELETE는 @PutMapping과 @DeleteMapping을 사용해줘야 한다. 하지만 html에서는 get과 post만 지원해준다. form에 아무리 method를 put / delete로 명시해줘도 사용하지 못한다. 이런 문제를 해결하기 위해 스프링에서 HiddenHttpMethodFilter 라는 클래스를 제공한다. 보통 기본적으로 활성화되어 있다는데 나는 아무리 해도 get이나 post로만 이동해서 따로 application.properties 파일에서 활성화 해줬다. # put / delete 메서도 사용하기 위해서 HiddenHttpMethodFi..

1. MVC 패턴을 사용할 것이기 때문에 controller / service / mapper 패키지를 생성하고 클래스를 생성해준다. 단, BoardMapper는 클래스가 아닌 인터페이스로 생성해준다. 쿼리는 xml 파일에서 구현해줄 것이기 때문이다. 2. Controller 작성 // 해당 클래스가 Controller의 역할을 한다고 명시해주는 어노테이션 // 주의할 점은 컨트롤러든 서비스든 매퍼든 같은 이름의 Bean 등록이 불가능하다는 점이다. // 만약 a 패키지와 b 패키지에 각각 board 클래스에 컨트롤러를 등록할 경우 오류 발생 @Controller // 필드 중 final이 붙은 필드만을 포함하여 생성자를 생성해주는 어노테이션 (의존성 주입) @RequiredArgsConstructor ..

[ 스프링 부트 프로젝트 생성 ] 1. File - New - Spring Starter Project 2. 프로젝트 이름은 board / 빌드 관리 도구는 Gradle / 자바 버전은 17으로 사용할 예정이다. 기본적인 스프링부트 프로젝트 생성 및 설정은 이미 포스팅해놨다. 이전 포스팅과 차이점은 Maven 대신 Gradle을 사용한다는 것 정도? (나는 이미 board라는 이름의 프로젝트를 생성해놔서 경고문이 뜬다.) 3. 사용할 모듈 의존성 주입 Lombok : Getter, Setter, ToString, RequiredArgsConstructor 등 코드를 훨씬 간단하게 줄여준다. MyBatis Framework : 데이터 베이스를 쉽게 관리하기 위한 라이브러리 Spring Data JDBC :..
학원 팀프로젝트에서 제이쿼리를 사용하다 보니 서버와 비동기 통신을 해야 할 때 ajax로만 데이터를 주고 받았다. 하지만 최근에는ajax 대신 fetch와 axios를 많이 쓴다고 한다. - fetch와 axios는 더 간결하고 직관적이다. - Promise 객체로 리턴해주기 때문에 데이터를 다루기 쉽다. - 자바스크립트의 async/await 구문과 잘 작동하여 코드를 더욱 읽기 쉽고 관리하기 쉽게 만든다. [ fetch와 axios의 차이점 ] [ fetch ] 자바스크립트의 기본 api이기 때문에 별도의 설치가 필요없다. 오래된 브라우저에서는 지원하지 않을 수 있다. (현재는 거의 지원한다고 한다.) json 데이터를 자바스크립트 객체로 변환하는 과정이 필요하다. (response.json()) 오..
[ 1. 데이터 베이스 생성 ] - DB 명 : rest_api - 아이디 : restapiid - 비밀번호 : restapipw -- DB 생성 CREATE DATABASE rest_api DEFAULT CHARACTER SET UTF8; -- 사용자 추가 (일반 사용자 계정 생성) CREATE USER 'restapiid'@'%' IDENTIFIED BY 'restapipw'; -- 사용자 권한 설정 GRANT ALL PRIVILEGES ON rest_api.* TO 'restapiid'@'%'; -- 변경된 내용을 메모리에 반영 FLUSH PRIVILEGES; [ 2. 테이블 생성 (게시글) ] CREATE TABLE t_board( board_idx INT(11) NOT NULL AUTO_INC..
1. charAt(인덱스)는 해당 인덱스의 문자를 반환한다. 하지만, 반환하는 데이터는 char형 또는 int형임을 알 수 있다. 그냥 String print = str.charAt(0)으로 하면 오류 발생 int print = str.charAt(0) / char print = str.charAt(0)은 오류 발생하지 않는다. 2. int로 받을 때와 char로 받을 때 값이 다르다. String str = "abcdefg" 에서 0번 인덱스를 출력했을 때 int로 받으면 103 출력 / char로 받으면 a 출력 때문에 int로 받아서 + 수식을 사용하면 97 + 103 으로 계산해서 200을 출력한다. char로 받았을 경우 문자로 출력되는 것을 확인했기 때문에 당연히 a + g가 돼서 ag가 될 ..
[ 배열에 넣어서 찾기 ] [toCharArray] 속도 : 136 / 길이 : 675B [split] 속도 : 124 / 길이 : 673B String str = "abcdefg"; // 1. toCharArray 사용해서 문자로 쪼개서 배열에 넣기 char[] chrArr = str.toCharArray(); System.out.println(chrArr[0]); // a 출력 // 2. split 사용해서 문자열로 쪼개서 배열에 넣기 String[] strArr = str.split(""); System.out.println(strArr[0]); // a 출력 // 두개 차이점 : 배열을 출력하면 ? System.out.println(chrArr); // abcdefg 출력 System.out.pr..