HCD 랩스 11월 3주차 - 스프링

우영·2025년 11월 17일

HDC 랩스 풀스택 1기

목록 보기
13/20

11/17 월 - 스프링 시작, DL, DI(XML, 자바파일, 어노테이션 3가지 방법)

assignment

  • 모던 웹 책 p20 의존성 주입 책 읽기 및 개념정리

review


  • 아키텍트 : 프로젝트명

  • VS code 에서 자동완성 할 수 있게 해주는 거 설치

  • 한국어 안깨지게 설정

  • 단축키
    shift + tab : 범위지정하고 앞으로 이동


오늘 배운거 복습

  • 스프링 : 자바 개발을 더 쉽고 빠르게 안전하게 해주는 프레임워크(프레임워크 : 기본 구조 + 규착 + 자동기능을 제공해주는 개발 툴)
    • 객체관리
    • DB연결
    • 트랜잭션 관리
    • 서버 요청 관리(MVC)
    • 보안, 로그, 스케쥴러 등등

스프링의 핵심 개념
1. Ioc

  • 원래 개발자가 하던 객체 생성 & 객체 연결을 스프링이 대신 해준다. 즉 제어권이 개발자에서 스프링으로 넘어감
개발자
MemberDAO dao = new MemberDAO();
Insa insa = new Insa(dao);

스프링은 만들어서 대신 연결해줌, 개발자는 그냥 가져다 씀 
  1. DI (Dependency injection) - 의존성 주입
    IoC가 만들어준다면, DI는 객체들을 서로 연결해주는 작업

  2. IoC 컨테이너 = IoC가 실제로 적용되는 공간
    1) 필요한 객체를 대신 new 해줌
    2) 객체보관
    3) 객체끼리 연결(DI)
    4) 객체 생명주기 관리

  3. IoC 컨테이너가 만든 객체 = 스프링 빈(Bean)

  • 스프링이 관리하는 객체 : 빈
  • 스프링이 관리하려면 반드시 IoC 컨테이너 안에 등록해야 함.

등록방식
1. XML
2. 자바 클래스

  1. 어노테이션

예제
1. package com.iot.springdi.app1;
=> DI을 도입해야 하는 이유 결합도가 높고 의존성이 높은 클래스, 클래스 바뀔 따마다 모든 코드를 고쳐야 함.
2. package com.iot.springdi.app2;
=> 인터페이스를 도입해서 다형성 적용해서 결합도를 낮춤, 그래도 new를 직접 하기 때문에 아직 결합도가 남아있음.
3. package com.iot.springdi.app3;
=> main에서 바뀜

스프링 IoC 컨테이너 생성

ApplicationContext factory = 
    new GenericXmlApplicationContext("test.xml");
  • ApplicationContext = 스프링의 IoC 컨테이너(객체 공장)
  • GenericXmlApplicationContext("test.xml") = 스프링이 어던 객체를 만들지에 대한 정보가 담겨 있는데 이 XML에 적혀 있는대로 객체 만들어서 관리

스프링 IoC 컨테이너 생성

MyBeanStyle obj = (MyBeanStyle) factory.getBean("mybean");

내부에 보관된 걸 getBean 호출하면 그 객체를 꺼내서 개발자에게 줌.

  1. package com.iot.springdi.basic;
    = DAO(DB와 직접 연결해서 CRUD 작업을 하는 객체), DTO(데이터를 옮기는 역할만 하는 객체)
public class MemberDTO {
    private String id;
    private String pass;
    private String name;
}

public class MemberDAO {
    public void add(MemberDTO user){
        System.out.println("db에 insert하기");
    }
    public MemberDTO getUser(String id){
        System.out.println("사용자 정보 가져오기");
        return null;
    }
}
  • DI 의존성 주입 자바 문법 자체 스프링 DI아님
    • 생성자 주입, setter 주입, getter 주입
public InsaImpl(MemberDAO dao) {
    this.dao = dao;
}

public void setDao(MemberDAO dao) {
    this.dao = dao;
}

@Override
public MemberDTO getUser(String id) {
    dao.getUser("id");
    return null;
}
  1. package com.iot.springdi.constructor.test1;
    = Service(InsaImpl)가 DAO(MemberDAO)에 의존하는 구조를 스프링이 생성자 주입으로 자동 연결해주는 예제로, 개발자가 직접 new 하지 않아도 되고 XML 또는 JavaConfig 설정만으로 객체 생성·조립이 이루어져 결합도를 크게 낮춘 스프링 DI의 정석 형태

  2. package com.iot.springdi.constructor.test2;
    = 주사위(Dice)를 의존하는 Player 객체를 스프링이 생성자 주입으로 자동 조립해주는 예제로, 여러 구현체(AbstractDice)를 다형성 구조로 설계하고 XML 또는 JavaConfig 설정만 바꿔도 Player가 사용할 주사위를 자유롭게 변경할 수 있는 스프링 DI·유연설계 실습용 패키지

  3. package com.iot.springdi.exam;
    = 여러 DB 연결 클래스(Oracle/MySQL/Mongo)를 공통 추상 클래스(Connection)로 묶고, 스프링이 XML 설정을 기반으로 원하는 구현체를 자동으로 생성·주입해주는 구조로, 코드 수정 없이 설정만 교체해도 다른 DB 연결 객체로 변경

  4. package com.iot.springdi.exam2;
    = TV 인터페이스(Tv)를 기준으로 LGTV·SamsungTV 구현체를 다형성 구조로 설계하고, TVUser/TVUser2에서 스프링 DI를 활용해 원하는 TV 객체를 자동으로 주입받는 예제로, 코드 변경 없이 설정만 교체해 TV 브랜드를 바꿀 수 있는 스프링

@Configuration
public class MyConfig {
    @Bean
    public MyBeanStyleA mybeana(){
        return new MyBeanStyleA();
    }
  • @Configuration : 스프링설정파일이란 뜻
  • @Bean : 스프링 IoC 컨테이너에 등록하겠다는 뜻

내일 배울거 : 스프링 MVC 구성이랑 포스트맨을 이용, restAPI가 뭔지, 론북을 이용해서

11/18 화 - Spring MVC 컨트롤러

assignment

review

dom, 이벤트, https://blog.naver.com/heaves1/224068149159,

정리 필요!!


  • 어노테이션으로 작업하기

  • 패키지 생성 = annotation.basic

  • app3 에서 스타일, 스타일A, 스타일B 복사

  • 스프링은 어노테이션이 붙어 있으면 Bean으로 등록함.

  • Annotation : 주석이란 의미로, 자바코드에 추가하여 의미를 부여하는 것, 스프링이 클래스나 메서드를 인식하고 특정 역할을 수행하도록 만드는 표시.
    (등록용)

    • @Component : 스프링이 관리하는 객체(빈)로 등록하기 위한 가장 기본적인 어노테이션, 특별한 역할 없이 단순 빈 등록이 필요할 때 사용함. (이 클래스는 스프링이 객체로 만들어서 관리해야 해), 문자열 → HTML 파일 경로
    • @Controller: 웹요청(화면)을 담당, 브라우저에서 들어오는 요청(URL)을 받아서 처리하는 클래스, 요청으로부터 전달된 값(파라미터)을 꺼내와서 자바 변수/DTO에 바인딩 = 값을 변수 또는 DTO에 자동으로 담아줌, 응답(HTML 화면 or JSON)을 반환
    • @Service: 실제 중요한 로직을 처리, 애플리케이션의 핵심 비즈니스 로직(기능)을 수행하는 역할.
    • @GetMapping, @PostMapping, @RequestMapping: 특정 URL 요청을 어떤 메서드가 처리할지 지정하는 어노테이션, Controller안에서 사용됨.
    • @Autowired: 스프링 컨테이너에 등록된 빈 중에서 필요한 객체를 찾아 자동으로 변수에 주입
    • @Repository: DB와 직접적으로 대화하는 DAO(Data Access Object) 클래스에 사용,SQL 실행, CRUD 수행 담당
    • @Configuration : 자바 파일을 스프링 설정 파일로 사용하겠다는 의미, @Bean 메서드들을 포함하며 직접 Bean을 생성하는 방식에서 사용
    • @Bean : @Configuration 클래스 내부에서 스프링이 관리할 객체(Bean)를 직접 생성해 등록하는 메서드
  1. DI 관련 어노테이션(의존성주입)
  • @Autowired : 필요한 객체를 스프링이 자동으로 찾아서 주입(DI)한다
  1. 요청 매핑(HTTP 요청 처리) 관련 어노테이션
  • GetMapping("/url") : HTTP GET 요청을 처리함
  • @PostMapping("/url") : HTTP POST 요청을 처리함
  • @RequestMapping("/url") : 클래스 또는 메서드에 공통 URL을 지정
  • @RequestParam("name") : 요청 파라미터를 특정 변수에 매핑, 파라미터가 반드시 존재해야 할 때 사용
    • 파라미터 : 요청에서 함께 전달되는 데이터
  • @ResponseBody : 메서드의 반환값을 그대로 HTTP 응답으로 사용하게 하는 어노테이션, HTML 화면이 아니라 JSON/문자 그대로 응답. 원래 경로로 인식되는걸 문자열 또는 JSON형식으로 인식하게 해줌
  • @RestController : @Controller + @ResponseBody가 자동 적용된 API 컨트롤러.
    화면(HTML)을 반환하지 않고, 모든 메서드의 반환값을 JSON 또는 문자 데이터 그대로 HTTP 응답 본문(Body)으로 전송한다.

자바객체는 웹이 읽을 수 없어서 JSON형식으로 바꿔야 읽기 가능, 리턴한 값 그대로는 웹이 읽기 가능




  • service랑 repository 차이, 맞게 한거 같은데 오류 뜸 자꾸
  • 오류 해결 : 어노테이션을 설정 했을 때 따로 설정을 안할 시 기본 생성자를 찾음

MVC

  • spring.io - initialize?

  • 오픈하고 설정할것들

  • 버전 맞추기

  • 한글 깨지지 않게 설정

  • 기본으로 인식하는 곳

  • visual code - f1 - 3.4.11 - java - 기본 - 이름 test - 확인 - jar - 17 - jdbc, web, mysql - open (인텔리제이가 얼티밋이 아니어서 자동완성 쓸려고 만듦.)

  • 이 부분에서 자동완성 및 작성 시작

  • 커넥션풀로 관리함. 미리 다 만들어놔야함 DB에 관련된 커넥션 객체를 만들어놔야 하는데 DB에 관한 정보가 없어서 url driver id pass등등이 없어서 오류가 뜸
  • 주석처리하고 다시 빌드 시켜줌
  • 타임리프가 자동으로 인식하는 곳

DispatcherServlet -(컨트롤러 실행요청)- HandlerAdapter -(실행)- 컨트롤러 - ModelAndView
| |
| - HandlerMapping(요청 path를 DispatcherServlet이 넘겨주면 실제로 path로 요청했을때 실행될 | 자바 클래스를 찾아서 DispatcherServlet에 넘겨주는 작업을 수행)
| - view Resolver

view Resolver : 설정정보에 명시되어 있는 viiew를 찾아서 실행할 view의 정보를 만들어서 리턴
기본 /templates/ + 뷰정보 + .html
추가해서 정보를 넘기는 것이 기본 뷰리롤버
ModelAndView : response에 공유할 데이터정보와 response할 view정보를 담고있는 객체


  • postman 설치 : 뷰가 있는 것처럼 요청하기 위한 것

  • 오후에 하는 것

  • lombok 사용하기 위해 plugins -> lombok install

  • buildgrade에 추가되어 있어야함

  • 주석 해제
@Repository
public class DBTestDAO {
    @Autowired
    JdbcTemplate jdbcTemplate;
    //member1테이블의 갯수를 리턴
    public int getCount(){
        return jdbcTemplate.queryForObject("select count(id) from member1", Integer.class); //이렇게 쓰면 동적 sql이 안됨 mybatis를 건너뜀 단점 sql이 문자열로 들어가 있는 것
        // sql를 쓰지 않고 코드를 자동으로 만들어줄 jpa를 나중에 함
    }
}

11/19 수 - Spring CLRUD,JPA

assignment

review

dom, 이벤트, https://blog.naver.com/heaves1/224068149159


  • JDBCTemplate 으로 CLRUD 하기
  • 테스트 코드 작성
  • 새로운 프로젝트 만들기 -yaml, properties 차이가 뭔지 모르겠음 근데 중요한듯


  • 파일 압축 해제

  • 방금 만든거 파일 구조

11/20 목 - JPA 엔티티, 연관관계 (이해 X)

assignment

review

dom, 이벤트, https://blog.naver.com/heaves1/224068149159


  • 워크벤치에서 jpatest,shop DB 생성
  • yaml 파일에서 url 수정
  • yaml 파일에서 ddl create로 바꾸기
  • PublicInfoAntity 클래스 파일 만들기
  • 실행 후 yaml 파일에서 다시 none으로 바꿈
  • 밑에 PersonDAOImplTest 테스트 파일 실행해서 데이터 삽입 확인
  • (공부 필요!)test에 있는 persist가 impl에 있는 거로 들어감
  • 콘솔결과 - 시퀀스 select는 insert는 나중에 실행됨

3가지 공부
어제꺼
1. spring mvc - restcontroller
2.

  1. JPA 원리 엔티티 만들기
  • 영속성 1차 캐시에는 엔티티객체 + 스냅샷(최초객체의 이미지), 메모리쪽은 쓰기지연SQL저장소
  1. insert, delete, update, delete 어떻게 흘러가는지, CLRUD
  2. 연관관계를 JPA에서 어떻게 적용하는지, onetoone, onetomany, ManytoOne
    그다음
    스프링데이터jpa
1. 커넥션풀
    - 스프링부트가 프레임워크에서 필요한 모든 제공되는 spring의 필요한 클래를 빈으로 셋팅해준다.
    - 스프링 부트 어플리케이션이 구동되는 시점에 스프링부트 내부에서 HikariCP객체를 통해 설정정보를 읽고 DBMS와
    커넥션을 10개를 만들어서 기본적으로 제공해준다.
     ---------------------------------
     커넥션풀
    - DataSource는 자바에서 제공하는 커넥션을 관리하는 객체로,
      생성된 커넥션풀로 부터 커넥션객체를 가져올 수 있도록 지원되는 자바의 표준 API - 만들어진 커넥션에서 하나씩 리턴하는 꺼내오는 역할
    - 스프링부트 내부에서 생성된 커넥션풀을 확인하기 위해서 필요

2, DBMS에 접근하기 위한 기술
    - JDBC를 직접 사용하지 않고 JDBC를 편하게 사용할 수 있도록 제공되는 프레임워크를 사용
    - 대표적으로 SQL Mapper와 ORM이 제공된다.
    1) SQL Mapper
        - SQL문을 직접 정의해서 DBMS연동
        - MyBatis와 spring jdbc의 대표 클래스인 jdbcTemplate
        - SQL문과 자바객체를 매핑해준다.
        - 개발자가 SQL문을 이용해서 원하는 데이터를 조회하는 경우 SQL Mapper내부에서 조회결과를 자바의
        객체로 자동으로 변환
        - MyBatis같은 경우 SQL문을 XML에 정의
    2) ORM(Object Relational Mappping)
       - 자바의 객체와 DBMS를 연결해주는 기술
       - SQL문을 만들지 않고 객체를 통해서 SQL문이 자동으로 실행되도록 처리
       - JPA
       - JPA는 객체를 JPA내부 프레임워크에 정의하면 이 객체의 스펙을 확인해서 SQL문을 자동으로 만들어준다.
3. JDBCTemplate
    - 스프링프레임워크 내부에서 제공하는 JDBC의 핵심클래스
    - JDBC를 할 때 발생하는 복잡한 작업이나 반복되는 작업을 내부에서 처리한다.
        * Connection 구하기
        * Statement생성
        * ResultSet을 처리해서 객체로 매핑
        * try - catch -finally안에서 처리
        * 자원 반납
        - insert,delete,updete는 실제 작업할 SQL문에만 집중
        - select는 sql문과 실행결과를 어떤 객체에 mapping할 것인지만 정의하면 된다.
    1) RowMapper를 작성 - select를 쓰기 위함
        - 데이터베이스의 결과값(ResultSet)에 포함된 레코드 하나를 어떤 자바객체로 변환해야 하는지 프레임워크 내부에 알려주는 역할
        - 테이블당 하나씩
        - JDBC코드에서 while문이나 if문 안에 객체와 매핑하는 코드를 정의
        - RowMapper클래스를 상속 받아서 mapRow라는 메소드를 오버라이딩 한 후 작업
        while (rs.next()) { // cursor를 내렸는데 레코드가 있으면 true를 리턴, 없으면 false리턴
        				// 이 부분이 mapRow에  정의되어야 할 부분
        				user = new MemberDTO(rs.getString(1), rs.getString(2), rs.getString(3), rs.getInt(5),
        						rs.getString(6));
        				userlist.add(user);// 객체로 변경된 레코드를 Arraylist로 보관하기

        			}
    2) 주요메소드
      ①update - insert, delete, update문 실행
        [미션]
        delete -> 26번 member를 삭제
        update -> 20번부서의 addr을 제주도로 변경하기

        포스맨으로 테스트 결과 화면과 파일 제출
      ② query
        -> select에서 여러개의 레코드를 반환하는 경우(리스트)

복습할거

11/21 금 - JPA 연관 (단,양 차이)

assignment
11/19일 스프링 MVC, CLRU, 영속성, 연관관계 과제랑 개념

review

dom, 이벤트, https://blog.naver.com/heaves1/224068149159


  • 이해 못함
@Test
    public void selectHistory() {
        //bts3의 경력사항을 조회
        HistoryEntity3 history = entityManager.find(HistoryEntity3.class, 1L);
        System.out.println(history);
        //JPQL 쿼리
        String jpql = "select obj from HistoryEntity3 obj where obj.emp.userId =:userId";
        List<HistoryEntity3> list = entityManager.createQuery(jpql, HistoryEntity3.class)
                .setParameter("userId", "bts3").getResultList();
        for (HistoryEntity3 his : list) {
            System.out.println(his);
        }

  • 공부하기 TOsTRING 다시 공부하기
package com.example.jpatest.mappedby;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

// 기준이 1
@Entity
@Table(name = "mydept")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeptEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long deptNo;
    private String name;
    private String mgr;
    //사원에 대한 정보를 알 수 있도록 처리
    //상대방엔티티(다에 해당하는 엔티티)에 있는 현재엔티티를 참조하는 필드이름을 명시
    @OneToMany(mappedBy = "dept") //어떤 컬럼이 매핑됐는지 부모에 있는 멤버변수명과 동일
    private List<EmpEntity4> emplist = new ArrayList<>();
    public DeptEntity(String name, String mgr) {
        this.name = name;
        this.mgr = mgr;
    }
}

package com.example.jpatest.mappedby;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

// 기준이 다
@Entity
@Table(name = "myemp4")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmpEntity4 {
    @Id
    private String userId;
    private String name;
    private String addr;
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "userPrivateId")
    private PrivateInfoEntity4 infoEntity;
    //부서에 대한 정보를 가질 수 있도록 처리 - fk테이블
    //JoinColumn이 추가된 엔티티가 주테이블이 된다.
    //                           -------
    //                          이엔티티를 기준으로 변경사항이 발생되면 DB에 반영
    @ManyToOne
    @JoinColumn(name = "deptId") // 실제 DB테이블에서 외래키컬럼으로 어떤 것을 줄것인지, 실제 생길 것
    private DeptEntity dept;



}

  • JpaRepository를 상속받은건 알겠는데 CLRUD를 다 해준다? 내가 할게 없다라는게 무슨말이지..

0개의 댓글