스프링

 

앞글과 이어져 진행 하는 작업이다.

 

 

28. MyBatis 의 로그 log4jdbc-log4j2   설정

 

SQL 이나 잘못된 속성의 이름으로 인해서 예외가 발생한다. 이런 경우를 대비해서 MyBatis 의 로그를 보다 자세히

조사할 수 있도록 로그를 설정 한다.  이때 필요한것이 log4jdbc-log4j2 라이브러리이다.

 

라이브러리 등록

http://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4


        <!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4 -->
        <dependency>
            <groupId>org.bgee.log4jdbc-log4j2</groupId>
            <artifactId>log4jdbc-log4j2-jdbc4</artifactId>
            <version>1.16</version>
        </dependency>

 

driverClassName 을 다음과 같이 변경한다. =>   net.sf.log4jdbc.sql.jdbcapi.DriverSpy

url 에 log4jdbc 가 들어가야 한다 .   => jdbc:log4jdbc:mysql://localhost:3305/simpleblog

/src/main/resources 폴더에    log4jdbc.log4j2.properties  파일과  logback.xml 파일을 추가 한다.

 

 

log4jdbc.log4j2.properties

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator



 

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- log4jdbc-log4j2 -->
    <logger name="jdbc.sqlonly"        level="DEBUG"/>
    <logger name="jdbc.sqltiming"      level="INFO"/>
    <logger name="jdbc.audit"          level="WARN"/>
    <logger name="jdbc.resultset"      level="ERROR"/>
    <logger name="jdbc.resultsettable" level="ERROR"/>
    <logger name="jdbc.connection"     level="INFO"/>
    
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-4level [%logger.%method:%line]-
                %msg%n</pattern>
        </layout>
    </appender>

    <appender name="LOGFILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/WEB-INF/logback.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logback.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 30일 지난 파일은 삭제한다. -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-4level [%logger.%method:%line]
                - %msg %n</pattern>
        </encoder>
    </appender>

    <!-- 로그의 레벨( 지정된 로그 레벨 이상만 수집 ) : DEBUG < INFO < WARN < ERROR < FATAL -->
    <logger name="myweb" additivity="false">
        <level value="INFO" />
        <appender-ref ref="LOGFILE" />
        <appender-ref ref="CONSOLE" />
    </logger>

    <root>
        <level value="INFO" />
        <appender-ref ref="CONSOLE" />
    </root>

</configuration>


 

28번 까지 진행 했다면  위에 작성한 MyBatisTest  를 진행과

서버를 구동해서  라이브러리 버전에 문제가 없는지 테스트 해보자. 

 

 

 

29.스프링 로깅툴(SLF4J) 적용

 

* 로깅툴을 사용하는 이유

- System.out.println() 명령어는 IO 리소스를 많이 사용하여 시스템이 느려질 수 있음

- 로그를 파일로 저장하여 분석할 필요가 있음

 

* 로깅툴의 종류

- commons-logging : 스프링 3에서 사용하던 로깅툴

- log4j : 효율적인 메모리 관리로 그동안 많이 사용되었음

- logback : log4j 보다 성능이 더 우수하여 최근에 많이 사용되고 있음

 

* SLF4J : logback을 사용하기 위한 인터페이스

* 설정방법

1. pom.xml 의 slf4j-version 을 1.7.21 로 수정

    <properties>
        <java-version>1.8</java-version>
        <org.springframework-version>4.3.0.RELEASE</org.springframework-version>
        <org.aspectj-version>1.6.10</org.aspectj-version>
        <org.slf4j-version>1.7.21</org.slf4j-version>
    </properties>
	

 

프로젝트를 생성 하면 다음 아래 라이브러리가  디폴트 로 셋팅 되어 있다.  1.7.21 을

변경함으로 서 아래 셋팅 된 값들도 자동으로 버전에 맞게 변경 되어 진다.

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j-version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        

 

 

2. pom.xml 에 라이브러리 추가

 

maven 저장소 

http://mvnrepository.com/artifact/ch.qos.logback/logback-classic

 

    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
            <scope>test</scope>
        </dependency>

		

 

WAS 없이 구동 하는  필자가 27번에 적어 놓은 WAS 없이 구동 테스트클래스인 SampleControllerTest 를 실행 하던지.

서버를 실행해서 오류가 생기지 않은지  SLF4J 가 뜨는지 확인하자.

 

29번 까지 아무런 오류 없이 실행 되면 다음과 같은 실행 후 콘솔창 화면이 보일 것이다.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/choi/.m2/repository/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/choi/.m2/repository/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
INFO : org.springframework.test.context.web.WebTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
INFO : org.springframework.test.context.web.WebTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@36d4b5c, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@6d00a15d, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@51efea79, org.springframework.test.context.support.DirtiesContextTestExecutionListener@5034c75a, org.springframework.test.context.transaction.TransactionalTestExecutionListener@396a51ab, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@51081592]
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [G:\dev\spring_simple_blog\test02\src\main\webapp\WEB-INF\spring\appServlet\servlet-context.xml]
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [G:\dev\spring_simple_blog\test02\src\main\webapp\WEB-INF\spring\root-context.xml]
INFO : org.springframework.web.context.support.GenericWebApplicationContext - Refreshing org.springframework.web.context.support.GenericWebApplicationContext@42dafa95: startup date [Fri Oct 13 17:19:08 KST 2017]; root of context hierarchy
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/],methods=[GET]}" onto public java.lang.String net.macaronics.web.HomeController.home(java.util.Locale,org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doD]}" onto public java.lang.String net.macaronics.web.SampleController.doD(org.springframework.ui.Model)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doC]}" onto public java.lang.String net.macaronics.web.SampleController.doC(java.lang.String,java.lang.String)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doA]}" onto public void net.macaronics.web.SampleController.doA()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doB]}" onto public void net.macaronics.web.SampleController.doB()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doE]}" onto public java.lang.String net.macaronics.web.SampleController.doE(net.macaronics.web.ProductVO)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doF]}" onto public java.lang.String net.macaronics.web.SampleController.doF(org.springframework.web.servlet.mvc.support.RedirectAttributes)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doG]}" onto public void net.macaronics.web.SampleController.doG(java.lang.String,javax.servlet.http.HttpServletRequest)
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doJson]}" onto public net.macaronics.web.ProductVO net.macaronics.web.SampleController.doJson()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/doJSON]}" onto public java.util.Map net.macaronics.web.SampleController.doJSON()
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@42dafa95: startup date [Fri Oct 13 17:19:08 KST 2017]; root of context hierarchy
INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@42dafa95: startup date [Fri Oct 13 17:19:08 KST 2017]; root of context hierarchy
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
INFO : org.springframework.jdbc.datasource.DriverManagerDataSource - Loaded JDBC driver: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
INFO : org.springframework.mock.web.MockServletContext - Initializing Spring FrameworkServlet ''
INFO : org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization started
INFO : org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization completed in 17 ms
INFO : net.macaronics.web.SampleController - setUp ----
INFO : net.macaronics.web.SampleController -  doJSON ( )  -  {name=홍길동, age=21} 
INFO : org.springframework.web.context.support.GenericWebApplicationContext - Closing org.springframework.web.context.support.GenericWebApplicationContext@42dafa95: startup date [Fri Oct 13 17:19:08 KST 2017]; root of context hierarchy

 

 

30. 연결 properties 로 변경하기

DB 연결 정보를  팀 프로젝트에서 좀 더  안전하고 편리하게  연결하기 위해  연결정보를 properties 로 변경 해보자.

src/main/resources 에 config 폴더를 생성하고 

mysql-config.properties 파일을 생성 해보자.  

중요한것은 파일명이 아니라 src/main/resources 아래 생성 하는 것이다.

properties 내용

db.driver=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
db.jdbcUrl=jdbc:log4jdbc:mysql://localhost:3305/simpleblog?useSSL=false
db.user=simpleblog
db.password=1111

 

 

그리고  root-context.xml 에 다음을 추가 하자.

    

classpath  가  src/main/resources 의 위치를 인식하고 있기 때문에 위와 같이 적는다.

 

마지막으로 dataSource 빈을 다음과 같이 변경한 후 이상이 없는지 테스트를 해보자.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
        http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

    <!-- Root Context: defines shared resources visible to all other web components -->
    <context:property-placeholder location="classpath:/config/mysql-config.properties" />
    <!-- <context:property-placeholder location="classpath:/config/oralce-config.properties" /> -->
    


    <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
        <property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy" 
        /> <property name="url" value="jdbc:log4jdbc:mysql://localhost:3305/simpleblog?useSSL=false" 
        /> <property name="username" value="simpleblog" /> <property name="password" 
        value="1111" /> </bean> -->

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driver}" />
        <property name="url" value="${db.jdbcUrl}" />
        <property name="username" value="${db.user}" />
        <property name="password" value="${db.password}" />
    </bean>
</beans>

 

 

31. XML Mapper 생성 및 작성 및 인식 및 SqlSessionTemplate 설정 

 

 

위 그림 처럼  src/main/resource 경로 아래 Mapper 를 설정해두는 폴더 mappers 를 생성한다.

sampleMapper.xml

는 다음과 같은 샘플 내용이 있다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="sampleMapper">
    
    
</mapper>

 

상세 설정은  마이바티스 홈페이지에 가면 자세히 나와 있다.

http://www.mybatis.org/mybatis-3/ko/configuration.html

 

스프링에서 mapper 폴더를 인식 할 수 있게 다음과 같이  root-context.xml 을 변경하자

21번 Mybatis 설정 내용을 참조하자.

 
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:/mybatis-config.xml" />
        <property name="mapperLocations"  value="classpath:mappers/**/*Mapper.xml"/>
    </bean>

mappers 폴더 내에 어떤 폴더이건 관계없이 파일의 이름이 'Mapper.xml '  로 끝나면 자동으로 인식하도록 설정 하는 것이다.

 

SqlSessionTemplate 의 설정

dao 의 작업에서 데이터베이스 연결을 맺고 작업이 완료 후에 close() 하는 작업이 있다. 

jsp 에서는 root-context.xml 이 없어서 연결 처리와 close 처리를 자동으로 할 수 없었다.  그러나 스프링 프레임워크에서는

root-context.xml 가 존재하고 여기에  SqlSessionTemplate 클래스를 설정해서 연결과 종료 작업을 자동으로 처리 해준다.

또한, SqlSessionTemplate  는 MyBatis 의 SqlSession 인터페이스를 구현한 클래스로 기본적인 트랜젝션의 관리나 쓰레드

처리의 안정성 을 보장해 주고 , 데이터 베이스의 연결과 종료도 관리해 준다.

 

root-context.xml 에 다음과 같이 추가 하자.

    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:/mybatis-config.xml" />
        <property name="mapperLocations"  value="classpath:mappers/**/*Mapper.xml"/>
    </bean>

    <!-- SqlSession 객체 주입 -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>


 

22 번 MyBatisTest 를 다음과 같이 수정하고 테스트를 진행 해보자. 

만약 에러가 발생하면 필자와 다른 라이브러리를 사용했을 가능성이 있다. 다시한번  살펴 보자.

package net.macaronics.web;


import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/spring/**/*.xml"})
public class MyBatisTest {

	
	private static final Logger log = LoggerFactory.getLogger(MyBatisTest.class);

	
	@Autowired
	private SqlSessionFactory sqlSessionFactory;
	
	
	private SqlSession sqlSession;
	
	@Test
	public void testSqlSessionFactory(){
		log.info("testSqlSessionFactory , {}   " ,sqlSessionFactory);
	}
	
	@Test
	public void testSession() throws Exception{
		try(SqlSession session=sqlSessionFactory.openSession()){
			log.info("testSession() , {}   " ,session);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
   @Test
	public void testSqlSession(){
	   log.info("testSqlSession() , {}   " ,sqlSession);
	}
	
	
	
}

 

 

 

 

 

32. 데이터베이스 연동  및  Mybatis 연동  등 현재 프로젝트가 제대로

돌아가는 CRUD 샘플 테스트  개발해 본다. 

 

31번 까지 완료 했으면 DB  MyBatis 연동  CRUD  테스트를 해서 프로젝트가 이상없이 구동되는지 확인 해 보자.

 

다음과 같은 클래스파일을 만들어 보자.

 

 

 

 

Domain = VO =DTO 

테이블 기준으로 데이터 전달 운송 단위 

비슷한 의미들이다.

MemberVO

package net.macaronics.web.domain;

import java.sql.Timestamp;
import java.util.Date;

public class MemberVO {
	private String userid ; 
	private String userpw ; 
	private String username;
	private String email ;
    private Timestamp regdate; 
    private Timestamp updatedate;
    
setter, getter

 

 

dao 패키지 또는 persistence 

 

MemberDAO

package net.macaronics.web.persistence;

import java.util.List;

import net.macaronics.web.domain.MemberVO;

public interface MemberDAO {  
	//DB 시간정보 물러오기
	public String getTime();
	//멤버 생성
	public void createMember(MemberVO vo);
	//회원 한명 정보 불러오기 
	public MemberVO getReadMember(String userid, String userpw);
	//회원 목록 출력
	public List readListMember();
	//회원 업데이트
	public void updateMember(MemberVO vo);
	//회원 삭제
	public void deleteMember(String userid);
	//회원수
	public Integer getCount();
	
	
	
}

 

MemberDAOImpl

package net.macaronics.web.persistence;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import net.macaronics.web.domain.MemberVO;

@Repository
public class MemberDAOImpl implements MemberDAO {
	
	private static final Logger log = LoggerFactory.getLogger(MemberDAOImpl.class);
	
	private static final String namespace="net.macaronics.mapper.memberMapper.";
	
	@Autowired
	private SqlSession sqlSession;
	
	//DB 시간정보 물러오기
	@Override
	public String getTime() {	
		return sqlSession.selectOne(namespace+"getTime");
	}

	//멤버 생성
	@Override
	public void createMember(MemberVO vo) {
		sqlSession.insert(namespace+"createMember", vo);
	}
	
	
	//회원 한명 정보 불러오기 
	@Override
	public MemberVO getReadMember(String userid, String userpw) {
		Map map=new HashMap<>();
		map.put("userid", userid);
		map.put("userpw", userpw);
		return sqlSession.selectOne(namespace+"getReadMember", map);
	}
	
	
	//회원 목록 출력
	@Override
	public List readListMember() {
		return sqlSession.selectList(namespace+"readListMember");
	}
	
	
	//회원 업데이트
	@Override
	public void updateMember(MemberVO vo) {
		sqlSession.update(namespace+"updateMember", vo);
	}
	
	
	//회원 삭제
	@Override
	public void deleteMember(String userid) {
		sqlSession.delete(namespace+"deleteMember", userid);
	}

	
	//회원수
	@Override
	public Integer getCount() {
	  return sqlSession.selectOne(namespace+"getCount");
	}

	
	

}

 

Service

컨트롤과 dao  완충 역할 즉, 

dao 나 컨트롤에서 하던 복잡한 계산 작업은 서비스에서 하면 된다.

코드상으로 볼때는 dao 와 별차이없다.   하지만 역할이 다르다.

MemberService

package net.macaronics.web.service;

import java.util.List;

import net.macaronics.web.domain.MemberVO;

public interface MemberService {
		//DB 시간정보 물러오기
		public String getTime();
		//멤버 생성
		public void createMember(MemberVO vo);
		//회원 한명 정보 불러오기 
		public MemberVO getReadMember(String userid, String userpw);
		//회원 목록 출력
		public List readListMember();
		//회원 업데이트
		public void updateMember(MemberVO vo);
		//회원 삭제
		public void deleteMember(String userid);
		//회원수
		public Integer getCount();
		
}

 

MemberServiceImpl

package net.macaronics.web.service;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.macaronics.web.domain.MemberVO;
import net.macaronics.web.persistence.MemberDAO;

@Service
public class MemberServiceImpl implements MemberService {
	
	private static final Logger log = LoggerFactory.getLogger(MemberServiceImpl.class);

	@Autowired
	private MemberDAO dao;
	
	
	@Override
	public String getTime() {
		return dao.getTime();
	}

	@Override
	public void createMember(MemberVO vo) {
		dao.createMember(vo);
	}

	
	@Override
	public MemberVO getReadMember(String userid, String userpw){ 
		return dao.getReadMember(userid, userpw);
	}

	@Override
	public List readListMember() {
	
		return dao.readListMember();
	}

	@Override
	public void updateMember(MemberVO vo) {
		dao.updateMember(vo);

	}

	@Override
	public void deleteMember(String userid) {
		dao.deleteMember(userid);

	}

	@Override
	public Integer getCount() {
		return dao.getCount();
	}
	
	

}

 

Mapper

memberMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="net.macaronics.mapper.memberMapper">
  
  <!--     DB 시간정보 물러오기 -->
    <select id="getTime" resultType="string">
      <![CDATA[ select now() ]]>
    </select>
    
    <!--     멤버 생성 -->
    <insert id="createMember">
    insert INTO TBL_MEMBER (userid, userpw, username, email) 

          values (#{userid}, #{userpw}, #{username}, #{email} )
    </insert>
    
    <!--     회원 한명 정보 불러오기  -->
    <select id="getReadMember" resultType="net.macaronics.web.domain.MemberVO">
        select * from TBL_MEMBER where userid=#{userid} and userpw=#{userpw}
    </select>
    
    <!--     회원 목록 출력 -->
    <select id="readListMember" resultType="net.macaronics.web.domain.MemberVO">
        select * from TBL_MEMBER 
    </select>
    
    <!--     회원 업데이트 -->
    <update id="updateMember">
        update TBL_MEMBER SET  userpw=#{userpw}, email=#{email}, username=#{username} where userid=#{userid}
    </update>
    
    
    <!--     회원 삭제 -->
    <delete id="deleteMember">
      delete from TBL_MEMBER WHERE  userid=#{userid}
    </delete>
    
    
    <select id="getCount" resultType="int">
        select count(*) from TBL_MEMBER
    </select> 
    
    
    
    
    
</mapper>

 

 

위와 같이 코딩을 하였으면 다음과 같이 테스트 코드를 작성해 보자. 그전에 의존 성 주입이 잘 되었는지 S 자를 확인해 보자.

파일 위에 S 자 모양이 있어야 servlet-context.xml 의     component-scan  의해 파이들이 스켄되어서 스프링의 특징 중 하나인  DI 의존성 주입 이

설정 되었다는 것을 판단 할 수 있다. 


    


    테스트 

MemberDAOImplTest

package net.macaronics.web.persistence;

import static org.junit.Assert.fail;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import net.macaronics.web.domain.MemberVO;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/spring/**/*.xml"})
public class MemberDAOImplTest {

	private static final Logger log = LoggerFactory.getLogger(MemberDAOImplTest.class);
	
	@Autowired
	private MemberDAO dao;
	
	Integer count;
	
	@Test
	public void testGetTime() {
		log.info("testGetTime  {} ", dao.getTime());
	}
	

	@Test
	public void testCreateMember() {
		count =dao.getCount();			
		MemberVO  vo=new MemberVO();
		
		 if(count==0){	    	
		    	vo.setUserid("user0");
				vo.setUserpw("1111");
				vo.setUsername("name0");
				vo.setEmail("0@macaronics.net");
				dao.createMember(vo);		
		}
		++count;				  
		vo.setUserid("user"+count);
		vo.setUserpw("1111");
		vo.setUsername("name"+count);
		vo.setEmail(count+"@macaronics.net");
		dao.createMember(vo);
	}


	@Test
	public void testReadListMember() {
		List list =dao.readListMember();
		log.info("testReadListMember - {}" , list.toString());
	}

	@Test
	public void testUpdateMember() {
		MemberVO  vo =new MemberVO();
		vo.setUserid("user0");
		vo.setUserpw("1111");
		vo.setUsername("2222name0");
		vo.setEmail("update0@macaronics.net");
		dao.updateMember(vo);
		
	
	}

	@Test
	public void testDeleteMember() {
		dao.deleteMember("user0");
	}

	
	@Test
	public void testGetReadMember() {
		MemberVO vo=dao.getReadMember("user1", "1111");
		log.info("testGetReadMember - {}" , vo.toString());
	}

	
	
}

 

 

테스트 결과 이미지 이다.

 

 

 

 

33. Mysql 에서 테스트를 했으면 Oracle 로 개발할경우 다음 과 같은 설정을 통해

테스트를 진행 해 보자.  

 

DB  - SQL

테이블 생성하기.

----------------------------
----------------------------
----------------------------  오라클

--임의  폴더를 만든다. 필자는 D 드리버의 oracleDB 폴더를 생성했다.

-- 콘솔창을 연다

-- C:> cmd

-- DBA 접속

-- C:> sqlplus / as sysdba

-- 테이블 스페이스 생성

create tablespace simpleblog
datafile 'D:\oracleDB/simpleblog.dbf'
size 20m
autoextend on
next 10m
maxsize unlimited;


-- 계정 생성

create user simpleblog identified by 1111 default tablespace simpleblog;

-- 권한 설정
grant connect, resource, create view to simpleblog;



CREATE TABLE tbl_member
(
   userid       VARCHAR2 (100) PRIMARY KEY,
   userpw       VARCHAR2 (100) NOT NULL,
   username     VARCHAR2 (50) NOT NULL,
   email        VARCHAR2 (100),
   regdate      TIMESTAMP DEFAULT sysdate,
   updatedate   TIMESTAMP DEFAULT sysdate
);



 

 

 

 

pom.xml 에 다음과 같이 추가한다.  상단 부분

    <properties>
        <java-version>1.8</java-version>
        <org.springframework-version>4.3.0.RELEASE</org.springframework-version>
        <org.aspectj-version>1.6.10</org.aspectj-version>
        <org.slf4j-version>1.7.21</org.slf4j-version>
    </properties>
    
<!-- 오라클 연결  -->
    <repositories>
        <repository>
            <id>codelds</id>
            <url>https://code.lds.org/nexus/content/groups/main-repo</url>
        </repository>
    </repositories>
    

 

라이브러리 추가

Ojdbc7

https://mvnrepository.com/artifact/com.github.noraui/ojdbc7

        <!--  오라클 연결 드라이브-->
<!-- https://mvnrepository.com/artifact/com.github.noraui/ojdbc7 -->
<dependency>
    <groupId>com.github.noraui</groupId>
    <artifactId>ojdbc7</artifactId>
    <version>12.1.0.2</version>
</dependency>


다음 이미처럼 oralce-config.properties,  memberMapper.xml  추가  MemberDAOImpl  , root-context.xml

  변경한다.

 

oralce-config.properties

db.driver=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
db.jdbcUrl=jdbc:log4jdbc:oracle:thin:@localhost:1521:xe
db.user=simpleblog
db.password=1111


 

oracle/memberMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="net.macaronics.mapper.o.memberMapper">
  
  <!--     DB 시간정보 물러오기 -->
    <select id="getTime" resultType="string">
      <![CDATA[ select sysdate from dual]]>
    </select>
    
    <!--     멤버 생성 -->
    <insert id="createMember">
    insert INTO TBL_MEMBER (userid, userpw, username, email) 

          values (#{userid}, #{userpw}, #{username}, #{email} )
    </insert>
    
    <!--     회원 한명 정보 불러오기  -->
    <select id="getReadMember" resultType="net.macaronics.web.domain.MemberVO">
        select * from TBL_MEMBER where userid=#{userid} and userpw=#{userpw}
    </select>
    
    <!--     회원 목록 출력 -->
    <select id="readListMember" resultType="net.macaronics.web.domain.MemberVO">
        select * from TBL_MEMBER 
    </select>
    
    <!--     회원 업데이트 -->
    <update id="updateMember">
        update TBL_MEMBER SET  userpw=#{userpw}, email=#{email}, username=#{username} where userid=#{userid}
    </update>
    
    
    <!--     회원 삭제 -->
    <delete id="deleteMember">
      delete from TBL_MEMBER WHERE  userid=#{userid}
    </delete>
    
    
    <select id="getCount" resultType="int">
        select count(*) from TBL_MEMBER
    </select> 
    
    
    
    
    
</mapper>

MemberDAOImpl

@Repository
public class MemberDAOImpl implements MemberDAO {
	
	private static final Logger log = LoggerFactory.getLogger(MemberDAOImpl.class);
	
	private static final String namespace="net.macaronics.mapper.o.memberMapper.";
	
	@Autowired
	private SqlSession sqlSession;


}

 

root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
        http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

    <!-- Root Context: defines shared resources visible to all other web components -->
    <context:property-placeholder location="classpath:/config/mysql-config.properties" />
    <!-- <context:property-placeholder location="classpath:/config/oralce-config.properties" /> -->
    


    <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
        <property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy" 
        /> <property name="url" value="jdbc:log4jdbc:mysql://localhost:3305/simpleblog?useSSL=false" 
        /> <property name="username" value="simpleblog" /> <property name="password" 
        value="1111" /> </bean> -->

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driver}" />
        <property name="url" value="${db.jdbcUrl}" />
        <property name="username" value="${db.user}" />
        <property name="password" value="${db.password}" />
    </bean>


    

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:/mybatis-config.xml" />
        <property name="mapperLocations"  value="classpath:mappers/**/*Mapper.xml"/>
    </bean>

    <!-- SqlSession 객체 주입 -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>



</beans>

 

 

위 같이 진행 후 MemberDAOImplTest 테스트를 하면 될 것이다. 

 

 

제작 : macaronics.net - Developer  Jun Ho Choi

소스 :  소스가 필요한 분은 비밀 댓글로 작성해 주세요.

 

 

 

about author

PHRASE

Level 60  라이트

바람 부는 날 가루 팔러 간다 , 하필 조건이 좋지 않은 때에 일을 시작함을 이르는 말.

댓글 ( 6)

댓글 남기기

작성