9:19 학원 도착
오늘부터 대학원 개강이다 야호..!! ㅋㅋ
수목은 1시간 일찍 조퇴하는데 내일은 오전수업만 듣고 바로 조퇴하고 볼일볼거 돌아다니고 학생증도 받으러 가고 하려고 일찍 나가야 해서 좀 걱정인데, 목요일날 오전 수업때 열심히 들어야겠다.(그래도 리액트 안놓쳐서 다행이다)
<9:30 1교시>
public의 index.html이 요청이 된 것.
id가 root인 빈 div가 해석된 내용이 응답되었고,
페이지 소스보기를 해보면 index.html이 응답된 것을 알 수 있다.
src 폴더에 있는 내용들을 static/is/bundle.js로 코딩 내용을 해석해서 결과 자바스크립트를 얻어내서 index.html을 띄워준다.
우리는 리액트 환경에서 작업한 어떤 결과 파일을 얻어내서 이걸 컴파일한 걸 스프링 부트에 적용할 떄, 스프링 부트의 static 폴더에 집어넣으면 스프링부트에서 돌아감.
동적으로 개발 스크립트를 얻어내는 환경, 작업이 끝났을 때 해석되어 스크립트를 얻어내는 환경 등을 우리가 배운다.
이 리액트 환경을 create-react-app이라는 프로그램으로 구축해서 여기서 만든 결과물(index.html과 .js들)을 스프링 부트의 static 폴더에 넣으면 그게 실행된다는 거 정도로 이해하면 된다.
아래는 스프링부트의 메인메소드 역할을 하는 index.js이다.
우리는 지금 하나의 챕터에 대해서 App.js를 변경하면서, 하나의 챕터가 끝나면 src 폴더를 보관하는 형태로 바꾸면서 예제 연습을 진행할 것이다.
자바스크립트 입장에서는 마크업과 script가 섞여있는 말도 안되는 구조의 html이다. 이렇게 작성하는 걸 jsx 객체라고 한다. javascript와 xml(html도 xml의 일종이다)을 함께 사용하는 객체이기 때문이다.
xml 형식이기 때문에 마크업을 열었으면 <요소> 반드시 닫아줘야 한다.</요소> (또는 단독 요소면 아예 <요소/>)
지금 배우고 있는 것 : 상태값(UI에 출력되는 데이터)을 관리하는 방법
이것은 데이터의 변경이 바로바로 UI에 반영되게 해준다.
자바스크립트에서 관리되는 어떤 data를 div에 출력을 하는데,
UI를 보이게 하거나 숨기거나 변경할 수 있는데, data가 변경되는것만으로 UI에 자동반영된다는 것이다.
뷰에서는 직접적으로 데이터 변경을 통해 UI 변경을 갱신했다.
리액트에서는 스테이트(상태)가 변경되게 하고 싶으면 useState같은 훅을 사용한다.
(그리고 이게 리액트에서 제일 중요한 훅)
리액트에서는 무언가를 import하면 오브젝트가 리턴되는데 import {useState} from "react"; 라는 코드에서
{useState}가 의미하는 것은 구조분해 할당으로 useState라는 방에 있는 함수를 useState라는 이름의 변수에 담겠다는 의미이다.
{구조} = {구조: useState식, 구조:값, 구조: [배열] 이런식으로 있는} 오브젝트에 있는 내용을 구조분해 한 것과 같다는 얘기.
그래서
import react from "react";
let {useState} = react; (← 같은 표현 → let useState= react.useState;)
jsx 형태의 식 <li>{item}</li>
li는 html의 리스트 아이템을 나타내는 태그 요소, {item}은 자바스크립트 표현식으로 jsx에서 javascript의 값을 삽입하거나 계산된 값을 표현할 때 사용된다.
즉, item이라는 배열 요소를 li 태그 내에 동적으로 삽입하는 jsx 코드이다.
기존 배열의 값을 활용해서 새로운 배열을 만들고 싶을 때 활용하는 함수 map
상태값을 관리할 때는 숫자도 덮어쓰고, 문자열도 덮어쓰고, 배열도 덮어쓰는건데,
새로운 배열로 덮어쓰기 하려니까 스프레드 연산자를 이용해서 기존의 배열 내용을 펼쳐놓아버려서 배열에 아이템이 하나 늘어난 효과를 줌.
상태값 변경하기 되게 중요해요~!!
상태값이 object 인데 object를 변경하려면 새로운 object로 덮어쓰기 해야 한다.
즉, 기존 object를 펼쳐놓고 새로운 object를 넣어주는 것이다.
<10:30 2교시>
키값이 없어서 에러가 난다고 함.
키값을 인덱스로라도 부여하면 오류가 안남.
샘플 데이터여서 키값이 없고 애매하게 인덱스 값을 넣어준건데 완벽한 처리는 아니다. 샘플데이터라 어쩔 수 없다.
데이터베이스에서 가져오면 primary key 값을 넣어주면 된다.
시퀀스 만들어서 하는 방법....인데 오류 뭐야 저거... 무서워... 시퀀스 번거로워서 바꾸기로 함.
Ctrl C 를 누르면 터미널을 끌 수 있고, npm install uuid로 uuid의존성을 설치
필요한 추가 package(라이브러리)는 npm install을 이용해서 설치하고 사용한다.
설치한 uuid 의존성은 package.json의 dependencies 에서 확인 가능
npm start 하고 import {v4 as uuid} from "uuid"라고 입력한다.
이것은 uuid의 v4를 import 해서 uuid라는 이름으로 사용하겠다는 의미이다.
어쨋든 방금의 시도는 샘플데이터에 고유한 키값을 부여하기 위해 사용한 방법으로 index를 키값으로 부여하면 꼼수라 탈이 날 수 있고
여기까지 내용을 Step02 State로 바꾸고, src 폴더 이름을 Step02_State로 바꾸면서 src 기본 구성 폴더를 카피해서 src 폴더로 만들기
이제 이클립스로 넘어간당.
지난시간에 하던거 : JPA (프로젝트 생성할 때 JPA dependency를 추가했었다)
h2Database는 개발 시 테스트 용도로 많이 활용하는 데이터 베이스.
웹브라우저 인덱스 페이지에서 /h2-console을 입력하면 h2 데이터베이스에 접속이 가능하다.
http://localhost:9000/spring11/h2-console
entity
package com.example.spring11.entity;
import com.example.spring11.dto.MemberDto;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity(name="MEMBER_INFO")//MEMBER_INFO라는 이름의 테이블
public class Member {
//@Entity 어노테이션으로 테이블이 만들어지고 아래에 나열한 필드명으로 테이블의 칼럼명이 결정된다.
@Id//primary key 값으로 사용할 필드에 붙인다
@GeneratedValue(strategy=GenerationType.AUTO)//시퀀스가 자동으로 만들어지고 사용되게 해준다
private Integer num;//@Id 부터 여기 num;까지가 한줄
private String name;
private String addr;
//dto 를 entity로 변환하는 static 메소드
public static Member toEntity(MemberDto dto) {
return Member.builder().num(dto.getNum())
.name(dto.getName()).addr(dto.getAddr()).build();
}
}
리포지토리를 아래와 같이 인터페이스에다가 JpaRepository 상속받는 것만으로도 리포지토리 클래스가 자동으로 생성돼서 그걸로 생성된 객체가 bean으로 관리되면서 @Autowired MemberRepository 하게 되면 어디서든 가져다 쓸 수 있고, 이 객체에는 해당 Entity 관련된 기본 메소드가 몇 개 정의되어 있어서 insert, update, delete가 자동으로 가능해진다.(사실 아직도 잘 이해되지 않음.)
<11:30 3교시>
Entity에서 아이디 역할을 하는 필드의 Type은 Integer 아니면 long 아니면 String(?)일 확률이 거의 대부분이다.
package com.example.spring11.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.spring11.entity.Member;
//아래와 같이 선언만 해도 Repository가 자동으로 완성된다.
//extedns JpaRepositroy<Entity Type, Entity에서 아이디 역할을 하는 필드의Type>
public interface MemberRepository extends JpaRepository<Member, Integer> {
}
일단 삭제 기능 만들어보기
int로 작성해야 했나봄. Integer로 썼다가 바꿈.
그래도 계속 에러나서 다시 자세히 보니까..... Spring03이어서 그렇더라..... 나는 멍청이... 트윗트윗...
어째 내가 만든 수정기능은 자꾸 추가로 되어버려서 보니까 매개변수를 전달 안해서 그런가보다 싶다.
MemberServiceImpl도 아래처럼 작성해야 함. 나는 save를 쓴게 새로운 사람 추가하는거랑 똑같은 방식으로 추가했으니까 당연히 수정을 누르는데 새로운 사람이 추가되는거였음.
웹페이지에서 전달되는 형태는 Dto여야 하는데, 서버에 저장할 때는 Entity 형태여야 한다. 오늘에서야 이해한듯.
만약에 번호를 내림차순으로 정렬하고 싶다면, MemberRepository 인터페이스에다가 메소드만 추가하면 된다.
메소드는 카멜케이스로 이름을 작성하고, findAllByOrder아이디칼럼이름내림차순또는오름차순 순서로 작성하면된다.
즉,
findAllByOrderBy칼럼명Desc();
findAllByOrderBy칼럼명Asc();
칼럼명은 Camel 케이스로 작성하기
<12:30 4교시>
때론 직접 select 문을 구성해서 원하는 값만 가져오고 싶을 수도 있을 때 작성하는 규칙
1.@Query라는 어노테이션 붙이기
2. @Query() 소괄호 안에 value = "셀렉트문" 작성하기
3. 셀렉트문 작성 규칙 "select 원하는칼럼 from 엔티티개체이름 앤티티개체별칭필수 order by 엔티티.num desc"
4. 함수로 얻어내는 결과 타입은 List<엔티티이름>으로 작성
위에처럼 하면 오류나서 다시 정리해주신 내용.
오전 내용 정리해보고 오후에는 익숙한 emp, dept 데이터를 이용해서 JPA 연습해보기.
'자바풀스택 과정 > 자바 풀 스택 : 수업내용정리' 카테고리의 다른 글
자바 풀 스택 3/5 오전 기록 067(오후 수업 조퇴 - 개인업무, 대학원 방문) (0) | 2025.03.05 |
---|---|
자바 풀 스택 3/4 오후 기록 066-2 (0) | 2025.03.04 |
자바 풀 스택 2/28 오후 기록 065-2 (0) | 2025.02.28 |
자바 풀 스택 2/28 오전 기록 065-1 (0) | 2025.02.28 |
자바 풀 스택 2/27 오후 기록 064-2 (0) | 2025.02.27 |