[230925] Spring 설치/maven/pom/IoC/객체 만들고 값 설정 등등

MJ·2023년 10월 10일

수업 TIL🐣💚

목록 보기
53/68

1교시 설치

설치(는 적는 거 생략)

maven

  • 빌드 툴에는 maven, gradle 두 개가 있따. 우리는 maven을 쓴다.
  • 특징: 각종 라이브러리(jar)들을 준비해서 가져다준다. 우린 더이상 jar를 직접 준비하지 않아도 된다. 대신 pom.xml이라는 파일을 준비하면 된다. pom은 태그들로 구성되는데 우리가 직접 쓰는거 아니고 찾아서 복붙하는 방식
  • 프로젝트 만들기
  1. 이름: Spring Legacy Project (STS3에서는 이것만 쓸 것)
  2. Templates: Spring MVC Project로 설정(프로젝트 틀)
  3. top-level package: com.gdu.app0n (n=숫자)
    • 이 패키지 이름은 수정하면 안된다. 잘못만들었으면 삭제하고 다시 만들어라
    • group id(company)와 artifact id(project)로 나뉘는데, 삼성 회사의 갤럭시 개발 프로젝트를 예로 들면 group id는 com.samsung이고 artifact id는 galaxy. 이걸 합치면 com.samsung.galaxy와 같은 형태가 되는 것
    • contextPath = app0n
    • 안에 자동으로 만들어지는 HomeController는 지우고 시작
  4. 프로젝트를 생성하면 maven이 jar 자동으로 다 다운받아주고 이러한 파일들은 C:\Users\사용자명\.m2\repository에서 확인 가능
  5. 만약 sts가 이유없이 안되면 이 .m2 폴더를 지우고 sts 재실행하면 됨. 또 자동으로 다운받아준다.

2교시 pom.xml

상단태그

    <!-- top level package, artifactId는 contextPath가 된다. -->
	<groupId>com.gdu</groupId>
	<artifactId>app01</artifactId>
    <!-- 프로젝트 이름 -->
	<name>01_IoC</name>
    <!-- deploy(배포) file -->
	<packaging>war</packaging>
    <!-- 프로젝트 버전 -->
	<version>1.0.0-BUILD-SNAPSHOT</version>
  1. 프로젝트 생성 시에 입력했던 group id와 artifact id. artifactId는 contextPath
  2. war: 프로젝트를 만들 때 마지막 순서는 프로젝트 전부 모아서 타입 하나로 패키징하는 것. 이때 war이 그 배포할 확장자임. (jar같은 확장자)

<properties>

이 아래에 속성 태그를 적으면 속성의 버전에 따른 디펜던시(jar)를 다운로드 받음.
기존에 적혀있는 것 하고는 버전이 달라서 우리가 수정해야할 부분들이 있음. 다음과 같이 우리가 쓰는 버전으로 수정
1. <java-version> 11
2. <org.springframework-version> 5.3.3
3. <org.aspectj-version> 1.9.6
4. <org.slf4j-version>1.7.30

맞춰준 버전
springframework 버전 : 2021년 01월 버전
org.aspectj, org.slf4j 버전 : springframework 버전과 맞추거나 이전 버전을 사용

작성된 버전 사용방법 : ${}을 이용
${java-version} -> 11으로 변경된다.
${org.springframework-version} -> 5.3.3으로 변경된다.
${org.aspectj-version} -> 1.9.6으로 변경된다.
${org.slf4j-version} -> 1.7.30으로 변경된다.

(properties랑 dependency 바꾸는 건 매번 할 필요없고 이번에 한번 만들어두고 계속 복붙하면 된다. 위에 상단 태그는 프젝마다 다 다르니까 복붙하면 안되는거 주의)

<dependencies>, <dependency>

  • dependencies 안에 dependency들이 모여있는 구조
  • dependency로 필요한 jar 파일을 자동으로 가져올 수 있음
  • jstl, junit 포함 여러 파일들이 자동으로 다운로드되어 있음. 원하는 것을 추가로 다운할 수 있음(maven 레파지토리 사이트에 dependency 형태로 올라가 있다)
  • 주요 자동 삽입 파일들
    • springframework의 spring-context,spring-webmvc(mvc패턴하려면 반드시 써야하는 패턴) 등
    • AspectJ : 나중에 배울 스프링 기능 중에 AoP 배울 때 필요한 jar
    • Loging : systemout 대신 log로 대체할 예정인데 그 때 쓸 것들 (slf4j) * 실무에서는 systemout을 절대 쓰면 안되고 전부 서버에 로그 찍는 방식으로 진행한다
    • inject : 주입, 객체 사용법에 관련된 이야기. 우리가 쓸 건 아닌데 지금 배울려는 내용에 포함된다고 함. 1장 이름이 IoC(inversion of console 제어의 권한을 바꾼다)인데 그동안 new를 사용해 개발자가 객체를 만들었는데 더 이상은 new를 개발자가 하지 않게 된다는 것 (개발자가 객체를 만들지 않는다)
    • Servlet : dynamic web project 할 때 서블릿 버전 4.0이었는데 여기엔 2.5로 적혀있음.(artifactId로 바뀌면서 버전업되면서?? 바뀌었다고) 그래서 바꿔조야함.
      (1) javax.servlet의 artifactId를 servlet-api에서 javax.servlet-api로 바꾸고 버전을 4.0.1로 바꿔줌
      (2) javax.servlet.jsp의 artifactId를 jsp-api에서 javax.servlet.jsp-api로 바꿔주고 버전을 2.3.3으로 바꿔줌
    • junit : 버전을 4.13.2로 바꿔줌

<build>

  • 프로젝트를 배포할 수 있도록 war 파일로 만드는 것. 이 작업에 참여하는 놈들의 버전이 적혀있음. maven도 여기 포함되어 있음
  • artifactId가 maven-compiler-plugin인 것을 보면 source랑 target을 1.6으로 쓰고 있음. 이건 자바 버전을 적어주는 거라서 우리 버전이랑 맞는 11을 사용하기 위해 EL로 ${java-version}을 적어줌 (자바 버전은 상단에서 미리 지정해놨고 그 걸 사용하는 방법이 ${}라고 그랬다)
	<source>1.6</source><source>${java-version}</source>로 수정. target도 마찬가지

추가할 디펜더시

추가 방법 : Maven 레파지토리에서 원하는 것 검색한 후 dependency 째로 복사해와서 dependencies 하위로 붙여넣으면 됨. 추가한 디펜던시는 dependencies 시작하고 바로 아래에 붙여넣어주는 게 쌤의 방법이다

추가할 디펜더시

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.15.2</version>
    </dependency>
  
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.30</version>
      <scope>provided</scope>
    </dependency>
  
    <!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
    <dependency>
      <groupId>com.oracle.database.jdbc</groupId>
      <artifactId>ojdbc8</artifactId>
      <version>23.2.0.0</version>
    </dependency>

더 추가되면 그 수업에다가 적겠음. 롬복도 2교시에 추가된거 아니고 잭슨도 나중가서야 추가된건데 걍 적어봄

Maven 정리

  1. Maven 레파지토리에 각종 jar 파일을 보관하고 있다.
  2. pom.xml 파일에 등록된 <dependency> 태그에 의해서 jar 파일이 자동으로 다운로드 된다.
  3. pom.xml 파일을 수정하면 다운로드로 연결되므로 자주 저장하지 않는 것이 좋다.
  4. 다운로드 받은 jar 파일들은 C:\Users\사용자.m2\repository 디렉터리에 저장된다.
  5. jar 파일에 문제가 발생한 경우
    1) STS를 끈다.
    2) C:\Users\사용자.m2\repository 디렉터리를 지운다.
    3) 다시 STS를 켠다.
    4) 새로 다운로드 될 때까지 기다린다.
    5) 프로젝트 우클릭 - [Maven] - [Update Project]

3교시

프로젝트 구조

  • 상단 3개 (파란색 박스)
    src/main/java : java 정보
    src/main/resources: xml 정보
    src/test/java: junit 정보

  • 하단 src 폴더
    src > main > webapp : 웹 영역
    webapp > resources : 정적파일 (css,js,image)
    webapp > WEB-INF > views : jsp

쌤: 오늘은 webapp 안한다. 상단쪽을 연습하겠다. test는 db가 있을때 하는거고 그거 빼고 나머지 두개한다


IoC(inversion of console)

프로젝트를 제어하는 권리는 원래는 개발자한테 있었음. 파일, 클래스, 객체 등등 원하는거 다 사람이 만들수 있던 걸 생각하면 됨. 스프링에서는 그 제어권을 스프링 프레임워크가 가져감. 가장 대표적인 것이 객체 생성 권한(new 어쩌구)
스프링이 new 해서 객체를 만들면 우리는 그걸 가져다가 쓰면 됨. 스프링도 인공지능은 아니니까 완전 창조하는건 아니고 우리가 써둔 코드를 보고 만들어내는거

jsp 수업할 때 dao로 싱글톤 패턴 만들던 것도 스프링에서는 다른 코드를 적으면 스프링이 자동으로 싱글톤으로 만들어줌
service도 마찬가지. jsp때는 전부 다 new ~~serviceImpl 해줬는데 스프링에서는 서비스 선언만 하면 됨

그래서 우리는 스프링에서 객체 만드는 법을 배우면 된다. 즉 스프링한테 new하라고 시키는 방법.
첫번째 방법은 xml 이용하는 것, 두번째 방법은 java 이용하는 것

xml 이용해서 객체 만들기

xml 파일에서 <bean>이라고 하는 태그로 객체를 만들 수 있다.
getBean으로 가져다 쓸수 있다.

  1. 생성:
  • package src/main/resources에 xml01, src/main/java에 com.gdu.app01.xml01
  • spring Bean Configulation File src/main/resources - xml01에 (xml 파일 이름은 자유지만) app-context.xml로 설정. next 누르면 체크하는게 나오는데 여기서 어떤걸 체크하냐에 따라 사용할 기능들의 차이가 생김. 체크안하고 그냥 생성
  • class 객체를 만들려면 클래스가 필요함. src/main/java - com.gdu.app01.xml01에 Calculator
  1. Calculator.java
    필드랑 생성자 없이 메소드 구현만 해준다. 생성자 new Calculator()를 만들지 않는 대신 그 역할을 수행할 bean 태그를 만들거다 (xml 파일에서)
public class Calculator {
  //no field
  //default constructor
  //method
  public void add(int a, int b) {
    System.out.println(a+"+"+b+"="+(a+b));
  }
  public void sub(int a, int b) {
    System.out.println(a+"-"+b+"="+(a-b));
  }
  public void mul(int a, int b) {
    System.out.println(a+"x"+b+"="+(a*b));
  }
  public void div(int a, int b) {
    System.out.println(a+"/"+b+"="+(a/b));
  }
}
  1. 코드

app-context.xml
<beans> 태그 안에 <bean>태그를 만든다. bean = 객체

<!-- Calculator calc = new Calculator() -->
<bean class="com.gdu.app.xml01.Calculator" id="calc" scope="singleton"/>

class에는 객체로 만들 클래스, id는 객체 이름, scope는 싱글톤 객체인 것 지정
(스코프가 싱글톤인 것은 디폴트 값이기 때문에 생략해도 된다)


MainWrapper에서 app-context.xml 파일 읽기
ex01

  public static void ex01() {
    
    //app-context.xml 파일 읽기 (여기에서 <bean> 태그로 정의해둔 객체가 생성)
    AbstractApplicationContext ctx = new GenericXmlApplicationContext("/xml01/app-context01.xml");
    
    // <bean> 태그로 정의된 객체 가져오기
    Calculator calculator = (Calculator)ctx.getBean("calc");
    //ctx.getBean("calc",Calculator.class)와 동일. bean을 가져와서 캐스팅
    // calc라는 이름의 bean을 가져와라 이런 뜻
    
    // 객체 사용해보기
    calculator.add(1, 2);
    calculator.sub(3, 4);
    calculator.mul(5, 6);
    calculator.div(7, 8);
    
    // app-context.xml 파일 닫기
    ctx.close();
  }

AbstractApplicationContext와 GenericXmlApplicationContext는 springframework 내장 객체다. AbstractApplicationContext가 GenericXmlApplicationContext의 부모라서 같이 쓸 수 있다. (부모, 자식, 클래스 이름 다 하나도 안중요해서 정리 안 한다함. 너무 길어서 안 쓸건데 가져다 쓰는 코드는 달라질 수 있어서 이건 오늘만 연습하면된다고 함)
GenericXmlApplicationContext가 xml을 읽고 (여기까진 확실) bean을 만들어놨다?라고 하신듯


이렇게 써주고 실행할 때는 톰캣 서버로 여는 것이 아니라 java Aplication으로 연다. 자바 main이기 때문에 자바 파일 실행하듯이 컨트롤 f11

출력결과


4교시 스프링에서 setter

STS에 롬복 설치하는 거랑 롬복 jar 디펜던시 등록해주는 건 생략

  1. 생성
    class com.gdu.app01.xml01에 Person (계산기를 들고 다닐 사람 만들거라 함)

  2. 사용
    src/main/java
    com.gdu.app01.xml01 - Person, MainWrapper
    src/main/resources
    xml01 - app-context.xml

Person

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Person {

  private String name;
  private int age;
  private Calculator calculator;
  
}

데이터를 저장하는 객체 bean (=dto)
네트워크에서 돌아다닐 땐
관용적으로 쓰이는 말 vo
여기 머라는지 안들린다 다시
다 같은 말. 얘도 어노테이션으로 dto에 했듯이 다 달아줌

app-context.xml

  <!-- 
    1. 디폴트 생성자 + setter
      Person man = new Person();
      man.setName("뽀로로");
      man.setAge(20);
      man.setCalculator(calc);
   -->
   <bean class="com.gdu.app.xml01.Person" id="man">
    <property name="name" value="뽀로로"/>
    <property name="age" value="20"/>
    <property name="calculator" ref="calc"/>
   </bean>
   
   <!-- 
    2. 필드를 이용한 생성자
      Person woman = new Person("루피", 20, calc);
    -->
    <bean class="com.gdu.app.xml01.Person" id="woman">
      <constructor-arg value="루피"/>
      <constructor-arg value="20"/>
      <constructor-arg ref="calc"/>
    </bean>

주석)

  • java에서 같은 역할하는 코드로 예시를 들어본 것

1번)

  • java의 setter는 bean태그의 property
    실제로 연결되어 있는거라서 setter 안만들고 property하면 오류남. 여기선 아까 @Data로 setter 만든 상태
  • calculator 만들때는 value 대신 ref 쓴 이유 = setCalculator가 전달하는 값은 위에서 만든 bean임 (calc) -> 다른 bean을 재료로 사용할 때는 ref를 씀

2번)

  • constructor-arg는 name 없이 value(or ref)만 전달하기 때문에 순서를 잘 지켜야 함.

MainWrapper ex02

    // app-context.xml 파일 읽어서 <bean> 태그로 정의된 객체 만들기
    AbstractXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/xml01/app-context01.xml");
    
    // 객체 가져오기(man, woman) 두가지 방법
    Person man = (Person)ctx.getBean("man");
    Person woman = ctx.getBean("woman",Person.class);
    
    // 객체 확인
    System.out.println(man.getName()+", "+man.getAge());
    man.getCalculator().add(1,2);
    System.out.println(woman.getName()+", "+woman.getAge());
    woman.getCalculator().add(3,4);
   
    // app-context.xml 파일 닫기
    ctx.close();
  • ClassPathXmlApplicationContext도 GenericXmlApplicationContext랑 동일하게 불러들고오는 기능
  • 객체 가져오는 두가지 방법.
    1. 이름(id) 전달하고 캐스팅 (3교시에도 했던 방법)
    1. 캐스팅 안하고 getBean으로 타입 자체를 전달하는 방법. id 적어주고 타입 적어줌
  • 출력결과

이제 첫번째 xml01 패키지 마무리


5교시 p속성

앞에 리눅스 보충 대해서 설명하는 건 생략.

3,4 교시랑 비슷한 수준인데 xml에 약간 새로운 내용 (이제 인용으로 하는건 다 쌤이 말한거 인용하는거다)

  1. 생성
    package src/main/resources에 xml02, src/main/java에 com.gdu.app01.xml02
    class com.gdu.app01.xml02에 User, Board, MainWrapper
    Spring Bean Configuration File xml02에 app-context.xml > p 체크
    ("p" 옵션 체크로 <property> 태그를 <bean> 태그의 속성으로 넣을 수 있음. 한마디로 약식화)
    /
    package src/main/resources에 xml03, src/main/java에 com.gdu.app01.xml03
    class com.gdu.app01.xml03에 Student, MainWrapper
    Spring Bean Configuration File xml03에 app-context.xml

  2. 사용
    src/main/java
    com.gdu.app01.xml02 - User, Board, MainWrapper
    com.gdu.app01.xml03 - Student, MainWrapper
    src/main/resources
    xml02 - app-context.xml
    xml03 - app-context.xml

User

@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {
  private int userNo;
  private String userId;
}

Board

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Board {
  private String title;
  private User editor;
}

app-context.xml

생성 시 p에 체크해줘서 상단에 p 관련 한 줄 추가됨


참고) 생성 시 체크한 것들 확인 및 수정

하단에 namespace 누르면

처음 생성할 때 체크창 뜸. 여기서 확인하거나 수정할 수 잇음
namespace 없을 때는 context 파일 우클릭 > open with > spring 검색 > spring config editor 클릭 > ok

1.
<bean class="com.gdu.app.xml02.User" id="user">
<property name="userNo" value="1" />
<property name="userId" value="admin" />
</bean>

2.
<bean class="com.gdu.app.xml02.User" id="user" p:userNo="1" p:userId="admin" />

3.
<bean class="com.gdu.app.xml02.Board" id="board" p:title="공지사항" p:editor-ref="user" />

1번과 2번은 같은 코드임. 1번의 property를 p를 사용해서 속성화시킨게 2번.
3번에서는 value 대신 ref가 값으로 사용됐을 때의 코드를 확인할 수 있음. 뒤에 -ref를 붙여주면 됨


MainWrapper
이제 확인해보자

 public static void main(String[] args) {
  
   // app-context.xml 파일 읽고 <bean> 태그에 정의된 객체 생성
   AbstractApplicationContext ctx = new GenericXmlApplicationContext("xml02/app-context.xml");
   
   // 객체 가져오기
   User user = ctx.getBean("user", User.class);
   Board board = ctx.getBean("board",Board.class);
   
   // 확인
   System.out.println(user.getUserNo()+", "+user.getUserId());
   System.out.println(board.getTitle()+", "+board.getEditor());
   
   // app-context.xml 닫기
   ctx.close();
}

확인 부분 보자. editor는 user 타입이라 userNo랑 userId도 포함하고 있어서 체이닝해서 더 들어갈 수도 있음. 예) board.getEditor().getUserNo() (그냥 이렇게 들어갈 수도 잇어서 말하신거)

출력결과

잘됐음

이제 xml02는 끝


xml03 코드

Student

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Student {
  private List<String> subjects;
  private Set<String> contacts;
  private Map<String, String> friends;
}

app-context

  <bean class="com.gdu.app.xml03.Student" id="student">
    <!-- List -->
    <property name="subjects">
      <list>
        <value>국어</value>
        <value>영어</value>
        <value>수학</value>
      </list>
    </property>
  
    <!-- Set -->
    <property name="contacts">
      <set>
        <value>010-0000-0000</value>
        <value>010-0000-0000</value>
        <value>031-9999-9999</value>
      </set>
    </property>
  
    <!-- Map -->
    <property name="friends">
      <map>
        <entry key="동네친구" value="루피"></entry>
        <entry key="학교친구" value="뚜비"></entry>
        <entry key="사회친구" value="포비"></entry>
      </map>
    </property>
  
  </bean>
  • student에서 list,set,map 총 3개의 필드를 만들었으므로 app-context에서 이 세개에 대한 값을 넣어주는 것.
  • list랑 set은 value 사용해서 값 넣어주고 map은 entry(key+value) 사용한다

MainWrapepr
실행해보기

  public static void main(String[] args) {
    
    //app-context.xml에 정의된 <bean> 태그를 객체로 생성
    AbstractApplicationContext ctx = new GenericXmlApplicationContext("xml03/app-context.xml");
    
    //객체 가져오기
    Student s = ctx.getBean("student", Student.class);
    
    // 확인
    for(String subject : s.getSubjects()) {
      System.out.println(subject);
    }
    for(String contact: s.getContacts()) {
      System.out.println(contact);
    }
    for(Entry<String, String> entry : s.getFriends().entrySet()) {
      System.out.println(entry.getKey()+","+entry.getValue());
    }
    
  }

for문 돌릴때 map은 entrySet이 포함되어야 해서 getFriends()뒤에 entrySet() 체이닝해준 것 주의하기
(반환타입이 Entry라서 그런가. 다른 애들은 단순 String이고)

출력결과

list = 국어 영어 수학
set = 010-0000-0000 031-9999-9999 (중복은 제거된 것)
나머지는 map
전부 다 제대로 출력됐음


6교시 02_IoC_ex

  • 앞으로는 pom.xml에 따로 추가작업하는거 아니면 생략 (생략해도 properties 이하로 다 이전꺼 복붙해줘야 jar들 셋팅됨)
  • HomeController랑 나중에 쌤이 알려줄 예정인데 src > main > webapp > WEB-INF > views 에 있는 home.jsp도 삭제해줘야함 (앞으로 쭉 생략할건데 legacy project 만들때마다 알아서 삭제)

문제 내줬는데 이전 교시에 배운 내용들로 property 태그나 constructor-arg 태그 이용해서 데이터 넣기 그런거다. 블로그에 적는거 생략


갑자기 피피티로 넘어감

중요한건 객체들을 만드는 방법이다.
<bean>태그를 이용하는 방법 (오늘 한 거)
@Configuration과 @Bean 어노테이션을 이용하는 방법 (나중에 배울거임)

객체를 가져다 쓰는 방법은
getBean() (하고 있는것. 나머지는 mvc할 때 수업)
@Inject
@Autowired
getBean은 별로 중요하지 않다. 가져다 쓰는 건 나중에 어노테이션을 직접 쓸 때 중요한 것 (겟빈 밑에 두개가 중요하다는건가)

지금은 mvc까지 가져가지 않아서 일일이 Spring Bean Configuration File을 작성하고 있지만 mvc까지 가져가면 Spring Bean Configuration File 우리가 안 만든다.
Spring Bean Configuration File이 root-context와 servlet-context라는 두 개의 파일 형태로 만들어져 있을 것이다.


7교시 02_IoC_ex

두번째 문제 설명

MyJdbcConnection 객체 만들기

데이터베이스 작업
모든 db 선행작업은 connection (Connection con 만들어서 사용하는 방식)
이 때 커넥션 만들어서 쓰는 방법: 1. jdbc, 2. DataSource (DBCP(데이터베이스 커넥션 풀))로 나눌 수 있음

  1. jdbc에서 커넥션 만드는 방법
    DriveManager.getConnection(url,user,password) : DriveManager라는 클래스에 getConnection 호출하면서 url, user, password를 전달해주면 커넥션이 반환됨.
  2. DataSource... 는 설명을 안해주시고 넘어가셨다

어쨋든 DriveManager로부터 getConnection을 얻어오는 이 과정을 스프링의 도움을 받아 진행해보자


MyJdbcConnection

@NoArgsConstructor
@AllArgsConstructor
@Data
public class MyJdbcConnection {

   private String driver;    // oracle.jdbc.OracleDriver
   private String url;       // jdbc:oracle:thin:@127.0.0.1:1521:xe
   private String user;      // GD
   private String password;  // 1111
   
   public Connection getConnection() {
     Connection con = null;
     try {
       Class.forName(driver); //driver 읽어들임
       con = DriverManager.getConnection(url, user, password); //커넥션 얻어오는 작업
       System.out.println(user + " 접속 성공"); //커넥션 만들어졌다면 출력됨
     } catch (Exception e) {
       e.printStackTrace();
     }
     return con;
   }
}

필드에 저장되어야 하는 이름은 항상 같다고 함. (근데 나 jdbc 때 수업 아파서 학원 빠져서 잘 모르는거 감안..) 무튼 옆에 적어준 주석들이 항상 각 필드의 이름으로 저장되어 있어야 한다고 함. GD랑 1111은 데베 배울때부터 쓰던거라 내 데베랑 연결하기 위해 저런 이름이 나온것 같네 아무튼 ㅇㅋ

저 주석으로 적어준 값들을 지금까지 배운 두가지 방법으로 넣어주면 되는 것 같다.

  <!-- MyJdbcConnection 객체 만들기 -->
  <bean class="com.gdu.app02.xml02.MyJdbcConnection" id="myJdbcConnection">
    <property name="driver" value="oracle.jdbc.OracleDriver" />
    <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe" />
    <property name="user" value="GD" />
    <property name="password" value="1111" />
  </bean>

MyJdbcDao 객체 만들기

MyJdbcDao

public class MyJdbcDao {
  private Connection con; //MyjdbcConnection의 getConnection()클래스로부터 얻어진다(con이 return되고 있음)
  private AbstractApplicationContext ctx;
  private MyJdbcConnection myJdbcConnection;
  
  private Connection getConnection() {
    ctx = new GenericXmlApplicationContext("xml02/appCtx.xml"); // 1
    myJdbcConnection = ctx.getBean("myJdbcConnection", MyJdbcConnection.class); //2
    ctx.close(); // 3
    return myJdbcConnection.getConnection(); //4
  }
  private void close() {
    try {
      if(con != null) {
        con.close();
        System.out.println(myJdbcConnection.getUser() + " 접속 해제");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  public void add() {
    con = getConnection();
    System.out.println("add() 호출");
    close();
  }
  
  public void remove() {
    con = getConnection();
    System.out.println("remove() 호출");
    close();
  }
  
  public void modify() {
    con = getConnection();
    System.out.println("modify() 호출");
    close();
  }
  
  public void select() {
    con = getConnection();
    System.out.println("select() 호출");
    close();
  }
  
}

dao = 하고 싶은 작업을 메소드로 만들어주는 것
1. appCtx에 정의해준 bean 태그를 객체로 생성 (appCtx.xml 작업보다 이거 먼저한듯)
2. myJdbcConnection 가져오기
3. 1번과 2번하면 myJdbcConnection 객체 나온거니까 닫아줌
4. 호출 결과 반환. 즉 connection을 반환하는 getConnection()이었음

getConnection()을 private로 만들어줬으니 이 클래스 내부에서 사용한다는 의미. 모든 메소드들에 커넥션 호출한다는 뜻인 con = getConnection()을 달아준다. 그러면 myJdbcConnection의 getConnection()도 사용할 수 있음 => (이렇게 db 사용가능해질듯)

원리만 보려고 한거라서 각 메소드 본문 채우지 않고 메소드마다 호출됐다는 것만 출력시켜줌. 메시지 출력되면 커넥션도 제대로 가져와진 것

그러면 문제. myJdbcDao를 싱글톤으로 제작해보라.

힌트. 객체 만들려면 xml 열어서 써야함.

정답
appCtx

  <!-- MyJdbcDao 객체 만들기 -->
  <bean class="com.gdu.app02.xml02.MyJdbcDao" id="dao"/>

끝.
property같은 걸로 필드 커넥션 채우면 안되는 것 주의.
dao는 커넥션 미리 채우는 거 아니다. 메시지 호출할 때만 생겼다 없어졌다 하는거임.

해결

다른 질문. 그러면 mvc패턴에서 dao를 부르는건 무엇인가.
힌트: db를 부르는 계층의 이름

-> Service 계층
(컨트롤러가 서비스 부르고 서비스가 dao 부름)

원래는 인터페이스로 만드는데 지금은 구현체 형태만 보는거니까 그냥 클래스로 만들음

MyJdbcService

public class MyJdbcService {

  private MyJdbcDao myJdbcDao;

  public void add() {
    myJdbcDao.add();
  }
  
  public void remove() {
    myJdbcDao.remove();
  }
  
  public void modify() {
    myJdbcDao.modify();
  }
  
  public void select() {
    myJdbcDao.select();
  }
  
}

마지막 미션. MyJdbcService을 객체로 만들기
힌트. myJdbcDao의 값을 채워야 함

정답
우선 setter를 이용해서 값을 저장할 수 있도록 MyJdbcService에

@NoArgsConstructor
@AllArgsConstructor
@Data

어노테이션 달아주기

본격적으로 객체를 만드는 작업은 appCtx.xml에서 service가 가지고 있는 단 하나의 필드인 MyJdbcDao myjdbcDao;를 채워주면 됨

  <!-- MyJdbcService 객체 만들기 -->
  <bean class="com.gdu.app02.xml02.MyJdbcService" id="service">
    <property name="myJdbcDao" ref="dao"/>
  </bean>

채워주기 위해서는 property 태그가 필요. 값으로 바로 위에서 만든 dao(MyJdbcDao 객체)를 넣어줌. bean 태그로 만들어져있는 객체이므로 value가 아닌 ref으로 값을 준다.

이건 실전으로 써도 되는 구조다.

MainWrapper
실행해보기(원래는 컨트롤러로 해야하는데 그냥 대충 해본 거니까)

  public static void main(String[] args) {

    AbstractApplicationContext ctx = new GenericXmlApplicationContext("xml02/appCtx.xml");
    MyJdbcService myJdbcService = ctx.getBean("service", MyJdbcService.class);
    myJdbcService.add();
    myJdbcService.remove();
    myJdbcService.modify();
    myJdbcService.select();
    ctx.close();

  }

service가 dao를 물고 dao가 connection을 물은 전부 연결된 구조라서 service가 잘 돌면 dao도 잘 돌고 connection도 잘 돌음

출력결과
호출 메시지 다 뜬다. 다만 db랑 실제로 연결된 건 아니라서


8교시

코드 개선만 하고 넘어감. 난 개선된 코드로 설명햇음
getConnection() 새로 파준거

0개의 댓글