[231010] <9장> jdbc, junit, log

MJ·2023년 10월 20일

수업 TIL🐣💚

목록 보기
59/68

1교시

9장 (javastudy 22_Jdbc_Ex 리메이크. dao,dto,sql 가져옴)

ContactDao

@Component  // JdbcConnection 객체(Bean)를 Spring Container에 저장해 둔다.
public class JdbcConnection {

  /*
   * 일반 버전
   *  Class.forName("oracle.jdbc.OracleDriver");
   *  url = "jdbc:oracle:thin:@localhost:1521:xe"
   * 
   * 쿼리 출력 버전(log4jdbc 디펜던시)
   *  Class.forName("net.sf.log4jdbc.sql.jdbcapi.DriverSpy");
   *  url = "jdbc:log4jdbc:oracle:thin:@localhost:1521:xe"
   */
  
  public Connection getConnection() {
    Connection con = null;
    try {
      Class.forName("net.sf.log4jdbc.sql.jdbcapi.DriverSpy"); // oracle jdbc 로드
      con = DriverManager.getConnection("jdbc:log4jdbc:oracle:thin:@localhost:1521:xe", "GD", "1111");
    } catch (Exception e) {
      e.printStackTrace();
    }
    return con;
  }
  
  public void close(Connection con, PreparedStatement ps, ResultSet rs) {
    try {
      if(rs != null) rs.close();
      if(ps != null) ps.close();
      if(con != null) con.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

2교시

JUnit 처리 방법

  1. spring-test dependency를 추가한다.
  2. @RunWith를 추가한다.
  3. @ContextConfiguration을 추가한다.
    ContactDao 객체(Bean)을 생성한 방법에 따라서 아래 3가지 방식 중 선택한다.
1) <bean> 태그 : @ContextConfiguration(locations="file:src/main/webapp/WEB-INF/spring/root-context.xml")
2) @Bean       : @ContextConfiguration(classes=AppConfig.class)
3) @Component  : @ContextConfiguration(locations="file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml")
// JUnit4를 이용한다.
@RunWith(SpringJUnit4ClassRunner.class)
// ContactDao Bean 생성 방법을 알려준다.
@ContextConfiguration(locations="file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml")
// 테스트 메소드의 이름 오름차순(알파벳순)으로 테스트를 수행한다.
@FixMethodOrder(MethodSorters.NAME_ASCENDING)

public class ContactUnitTest {

  @Autowired  // Spring Container에서 ContactDao 객체(Bean)를 가져온다.
  private ContactDao contactDao;
  
  @Test  // 테스트를 수행한다.
  public void test01_삽입테스트() {
    ContactDto contactDto = new ContactDto(0, "이름", "연락처", "이메일", "주소", "");
    int insertResult = contactDao.insert(contactDto);
    assertEquals(1, insertResult);  // insertResult가 1이면 테스트 성공이다.
  }
  
  @Test  // 테스트를 수행한다.
  public void test02_조회테스트() {
    int contact_no = 1;
    ContactDto contactDto = contactDao.selectContactByNo(contact_no);
    assertNotNull(contactDto);  // contactDto가 not null이면 테스트 성공이다.
  }
  
  @Test  // 테스트를 수행한다.
  public void test03_삭제테스트() {
    int contact_no = 1;
    int deleteResult = contactDao.delete(contact_no);
    assertEquals(1, deleteResult);  // deleteResult가 1이면 테스트 성공이다.
    // assertNull(contactDao.selectContactByNo(contact_no));  select 결과가 null이면 테스트 성공이다.
  }

}
  • assertEquals: (기대한 값, 실제 값) 기댓값과 실제값이 같으면 테스트 성공
  • location 찾을 때는 file: 명시

3,4교시


5교시

log4j.xml

각종 정보를 콘솔에서 info 레벨로 찍어주는 애가 있다.
Appender : 로그를 찍어주는 놈

name : 어팬더 이름 (console)
콘솔어팬더 = 콘솔에 찍어주는 놈
value값 = 찍는 방식 지정

  • %-5p : 로그 레벨을 5글자로 찍을 것

    'info ' --> 공백까지 총 5글자, 정렬은 왼쪽? 정렬(마이너스)
  • %c : 동작하는 클래스를 찍을 것
    • : 하이픈
  • %m : 로그 메시지를 찍을 것
  • %n : 줄바꿈

하단부 Root logger를 보면

어팬더 사용할 때 console로 이름 지정해준 것을 사용하라고 명시해둔 상태


name으로 지정해준 패키지의 로그는 level value로 지정한 수준으로 찍으라고 적어준 것. 여기선 전부 인포레벨

여기까지 전부 스프링 프로젝트의 기본로그들. 간단히 알고만 있으면 된다.

로그

logger import -> slf4j(로깅 인터페이스)로

출력 결과

  • system out은 실무에서는 쓰지 않는다. 전부 log로
  • 우리가 최종적으로 쓸 로그 프레임워크는 logback (log4j의 다음 버전)




개발자는 slf4j 인터페이스에 맞춰 로그 작업을 하고 slf4j는 실제로 동작할 로깅 프레임워크(log4j, logback 등)을 연결한다. (다양한 로깅 프레임워크가 있지만 사용법을 통일하기 위해 slf4j 인터페이스를 사용한다. 개발자는 slf4j와만 작업하기 때문에 그 뒷단 하나하나 문법은 신경안써도 된다)


6교시

logback.xml

<configuration>

  <!-- Appenders : 로그를 출력하는 Appender 모음 -->
  
  <!--
    %d{날짜시간패턴} : 로그기록시간 (SimpleDateFormat과 같은 날짜시간패턴)
    %level           : 로그 레벨 (OFF > ERROR > WARN > INFO > DEBUG > TRACE)
    %logger          : 로그를 찍는 클래스 (어떤 클래스가 동작할 때 로그가 남겨지는가?)
    %msg             : 로그 메시지
    %n               : 줄 바꿈
  -->
  
  <!-- Console에 로그를 찍는 Appender -->
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>[%d{HH:mm:ss, Asia/Seoul}] %-5level:%logger - %msg%n</pattern>
    </encoder>
  </appender>
  
  <!-- File에 로그를 찍는 Appender -->
  <appender name="file" class="ch.qos.logback.core.FileAppender">
    <file>/log/app09_log.log</file>
    <append>true</append>
    <immediateFlush>true</immediateFlush>
    <encoder>
      <pattern>[%d{HH:mm:ss, Asia/Seoul}] %-5level:%logger - %msg%n</pattern>
    </encoder>
  </appender>
  
  <!-- 매일 새로운 로그 파일을 만드는 RollingFileAppender -->
  <appender name="rolling" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>/log/app09.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
      <maxFileSize>100MB</maxFileSize>
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>[%d{HH:mm:ss, Asia/Seoul}] %-5level:%logger - %msg%n</pattern>
    </encoder>
  </appender>
  
  <!-- Application Loggers -->
  <logger name="com.gdu.app09" level="info" />
  
  <!-- 3rdparty Loggers -->
  <logger name="org.springframework" level="info" />
  <logger name="log4jdbc"            level="info" />
  <logger name="jdbc.sqlonly"        level="info" />  <!-- 쿼리문 출력하기 -->
  <logger name="jdbc.sqltiming"      level="off" />   <!-- 쿼리문 + 실행시간 출력하기 -->
  <logger name="jdbc.resultsettable" level="info" />  <!-- SELECT 결과를 테이블 형식으로 출력하기 -->
  <logger name="jdbc.connection"     level="off" />   <!-- Connection 연결/종료 정보 출력하기 -->
  <logger name="jdbc.audit"          level="off" />   <!-- ResultSet을 제외한 jdbc 호출 정보 출력하기 -->
  <logger name="jdbc.resultset"      level="off" />   <!-- ResultSet을 포함한 jdbc 호출 정보 출력하기 -->
  
  <!-- Root Logger -->
  <root>
    <priority value="warn" />
    <appender-ref ref="console" />
    <appender-ref ref="rolling" />
  </root>
  
</configuration>

ContactController에서 contactlist 로그 찍기


// ContactController를 실행할 때 org.slf4j.Logger가 동작한다.

--> @slf4j 어노테이션으로 대체

@Slf4j  // private static final Logger log = LoggerFactory.getLogger(ContactController.class);
@RequiredArgsConstructor  // private final ContactService contactService;에 @Autowired를 하기 위한 코드이다.
@Controller
public class ContactController {

  // ContactController를 실행할 때 org.slf4j.Logger가 동작한다.
  // private static final Logger log = LoggerFactory.getLogger(ContactController.class);
  
  private final ContactService contactService;
  
  @RequestMapping(value="/contact/list.do", method=RequestMethod.GET)
  public String list(Model model) {
    List<ContactDto> contactList = contactService.getContactList();
    model.addAttribute("contactList", contactList);
    return "contact/list";
  }
  }


msg 자리에 출력됨


7교시

6교시에 작업한 것 실행 결과
목록보기(연락처관리 클릭)하면 자동으로 찍힘

콘솔 로그

파일 로그

정해준 위치에 파일로 생성돼서 잘 찍혔다

RollingFileAppender 로그

지정한 형식대로 날짜 찍혀서 생성

이후에 쿼리로그했음 8교시까지

log4jdbc

쿼리로그
작업하기 위해 필요한 디펜더시 : log4jdbc
작업하기 위해 필요한 파일 : log4jdbc.log4j2.properties
커넥션 연결하려면 dirverName, url이 달라진다

0개의 댓글