log4JDBC , Intercepto

disdos0928·2022년 6월 27일
0

Spring

목록 보기
14/18
post-thumbnail

log4JDBC

Loggger로 info / debug 등 여러 기능을 찍어봤지만
추가적인 라이브러리를 활용해 Mybatis 수행 sql + 결과를 찍어 볼 수 있었다

이거 pom에 Depandency 추가하다가 인텔리제이랑 STS랑 충돌나서 개 지랄지랄을 했다 결과적으로는 추가된 종속석을 인텔리에서 확인을 못해서 난 문제 같다

Anyway

sql이 사용될 때 마다 자동으로 logger찍힌다

<!-- @Inject -->
<dependency>
  <groupId>javax.inject</groupId>
  <artifactId>javax.inject</artifactId>
  <version>1</version>
</dependency>

root-context.xml에서 realDataSource 와 DataSource으로 추가

realDataSource는 실제 DB 연결 위한 정보들

	<!-- log4j를 이용한 SQL 로그 출력용 Bean 
		*realDataSource 를 이용해서 SQL 수행 내용 , 결과를 출력하는 역할		
		*realDataSource를 대체하는 역할
	-->
		<!-- realDataSource -->
		<bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource">
		<constructor-arg ref="realDataSource" />
		
		<property name="logFormatter">
			<bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter">
				<property name="loggingType" value="MULTI_LINE"/>  <!-- 한줄로 찍을건지 여러줄로 찍을건지 -->
				<property name="sqlPrefix" value="[ SQL ]" /> <!-- SQL 관련 Logger를 찍을때 앞에 붙는 접두사 --> 
			</bean>
		</property>
	</bean>

log4j.xml에서 그냥 consolo log 말고 SQL Console도 추가한다.

<!-- sql 로그 출력용 -->
	<!--  -->

	<logger name="java.sql.Connection">
		<level value="debug" />
		<appender-ref ref="sql-console" />
	</logger>

	<logger name="java.sql.Statement">
		<level value="debug" />
		<appender-ref ref="sql-console" />
	</logger>

	<logger name="java.sql.PreparedStatement">
		<level value="debug" />
		<appender-ref ref="sql-console" />
	</logger>

	<logger name="java.sql.ResultSet">
		<level value="debug" />
		<appender-ref ref="sql-console" />
	</logger>

	<logger name="jdbc.sqlonly" additivity="false">
		<level value="INFO" />
		<appender-ref ref="sql-console" />
	</logger>

	<logger name="jdbc.resultsettable" additivity="false">
		<level value="INFO" />
		<appender-ref ref="sql-console" />
	</logger>

뭐 대략적으로 왜 추가한 것이고 왜 사용하는지 같은 맥락은 이해하는데
나중에 추가하고 싶을때는 관련 문서 다시 보고 추가해야겟다
암기하는건 시간 낭비일듯


Interceptor

DispatcherServlet에서 Controller 사이에 위치한다
이 때 매핑된 URL에 접근시 수행된다 .

	// DI
	@Autowired
	private BoardService boardService;

	//Controller 접근 전 처리
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
//		logger.info("전 처리 수행");

		// aplication scope에 " boardTypeList " 가 없을 경우
		// 이를 조회하는 Service 호출 후 결과를 세팅

		// application 가져오기
		ServletContext application = request.getServletContext();

		if (application.getAttribute("boardTypeList") == null) {
			List<BoardType> boardTypeList = boardService.selectBoardType();
			application.setAttribute("boardTypeList", boardTypeList);
			logger.debug(boardTypeList.toString());
		}

		return HandlerInterceptor.super.preHandle(request, response, handler);
	}
	//Controller 접근 후 처리
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}
	//Controller 처리 후 View까지 처리후 . *보통 close등 자원 반환을 수행한다.
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}
}

위 코드는 모든 요청에 대한 처리이지만 application scope으로 선언된 BoardTypeList 요소가 null일때만 수행되는 구문이다
처음에 게시판 리스트를 조회한 후 Application scope로 올려둔 후에는 동작하지 않는다

크게 어려운 기능으로 이해하지 말고
이런 기능이 있다 정도로만 이해해야 될 것 같다.


URI 편하게 잘라주는 @PathVariable(" - ")

@PathVariable ("value") : URL 경로에 포함되어있는 값을 변수로 사용할 수 있게 하는 Annotation

@GetMapping("/list/{boardCode}")
public String boardList(@PathVariable("boardCode") int boardCode
// 없어되 하지만 없으면 기본값을 1으로 세팅해라 
,@RequestParam(value="cp",required=false,defaultValue ="1") int cp
,Model model){ 내용 구분 }


boardCode와 boardNo으로 두개의 Parameter를 매개변수로 전달받은다
기존에 페이지네이션을 위해 매개변수를 inputType="hidden"으로 숨겨두는 등의 번거로운 동작을 수행하지 않아도 된다.

0개의 댓글