Spring MyBatis & Oracle 연동
https://ggangpae1.tistory.com/228
10.ServerUse
ggangpae1.tistory.com
=> Item 테이블에서 검색조건과 검색어 그리고 페이지 번호 및 페이지 당 데이터 개수를 이용해서 데이터를 조회
=> Itemid(기본키)를 가지고 하나의 데이터 조회하기
=> 데이터 삽입
=> 모든 작업의 결과는 json 형식으로 리턴
2. Spring MVC Project 생성
=> 기본적인 Context path는 패키지의 3번째 이름이 되고 배포하기 위해서 프로젝트를 war 파일로 export 하게 되면 프로젝트 이름이 ContextPath가 된다.
3번째 패키지 이름과 프로젝트 이름을 일치하도록 만들면 좋다.
=> 프로젝트 이름은 oracleserver, 패키지이름은 kakao.itstudy.oracleserver
![]() |
![]() |
3. pom.xml 작업
=> 버전 설정과 의존성 설정(외부 라이브러리 다운로드 및 빌드 패스에 추가)
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
4. 이거를 한다고 서블릿3.0을 사용할 수 잇는건 아직 아니고 web.xml 파일의 DTD를 수정해야 한다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1"> <!-- 서블릿 3.0을 사용할수 있게 해주는 DTD -->
5. web.xml이나 pom.xml을 변경했을 때는 마우스 우클릭후 [Maven] - [Update Project]를 실행
=> 변경한 내용이 적용된다.
![]() |
=> 업데이트를 하지 않으면 실행은 되는데 프로젝트에 에러 표시가 나는 경우가 있다.
6. pom.xml 파일에 의존성을 설정
1) 오라클을 위한 레포지토리 설정
=> 오라클은 중앙저장소에서 다운로드 할수 없기 때문에 직접 다운로드 받는 장소를 설정해줘야 한다.
<repositories>
<repository>
<id>oracle</id>
<name>ORACLE JDBC Repository</name>
<url>http://maven.jahia.org/maven2</url>
</repository>
</repositories>
2) 필요한 라이브러리의 의손성을 dependencies 태그에 작성
=> 자바가 제공해주지 않는 외부 라이브러리를 다운로드하고 현재 프로젝트에서 사용할 수 있도록 빌드 패스에 추가하는 작업이다. 면접시
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>kakao.itstudy</groupId>
<artifactId>oracleserver</artifactId>
<name>OracleServer</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<repositories>
<repository>
<id>oracle</id>
<name>ORACLE JDBC Repository</name>
<url>http://maven.jahia.org/maven2</url>
</repository>
</repositories>
<dependencies>
<!-- Oracle -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- JSON 출력 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.7</version>
</dependency>
<!-- 비밀번호 암호화 -->
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<!-- 파일 업로드 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!--Spring Test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- 데이터베이스 로그 출력 -->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4</artifactId>
<version>1.16</version>
</dependency>
<!-- 롬복 : DTO를 편리하게 만드는 라이브러리 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<!-- 웹 소켓 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- 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>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
3) 의존성을 설정한 경우는 파일을 저장하고 잠시 다운로드 받는걸 기다린다.
7. web.xml 파일에 파라미터 인코딩을 위한 필터 설정을 한다.
=> 웹 페이지나 모바일 기기에서 데이터를 요청할 때 같이 보내는 파라미터의 한글이 포함된 경우 인코딩을 위해서 설정 : ServiceImpl에서 파라미터를 읽을 때 한글이 깨진다.
=> 필터 : 컨트롤러가 요청을 처리하기 전이나 요청을 처리한 후에 호출되는 객체
비슷한 용어로 스프링에서는 Interceptor나 AOP 용어를 사용한다.
Spring 면접 보러 갈때는 AOP에 대해서 반드시 숙지 해야 한다.
<!-- 인코딩 필터 설정 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
8. servlet-context.xml 파일에 2가지 설정 추가
=> controller가 처리하지 못하는 요청은 WAS가 처리하도록 해주는설정 : 이미지 파일 다운로드, 자바스크립트 또는 css 링크를 걸 때 이 설정이 없으면 404 에러가 난다.
=> 파일 업로드를 위한 설정 : 하지 않으면 파일 업로드가 안된다.
<!-- Controller가 처리하지 못하는 요청은 WAS가 처리하도록 해주는 설정 -->
<default-servlet-handler />
<!-- 파일 업로그를 위한 설정 -->
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</beans:bean>
9. 여기까지가 기본설정
=>실행해보자. Run as run on server
에러 없다.
10. Item 테이블에 대한 작업을 위한 코딩
어떤작업을 할지 생각해보자.
=> 검색조건(search type) 과 검색어(keyword) 그리고 페이지번호(pageno)와 데이터 개수(count)를 받아서 조건에 맞는 데이터 조회
searchtype은 null이 가능하고 searchtype이 null이면 keyword 무시
pageno도 생략이 가능한데 생략하면 1
count도 생갹이 가능한데 생략하면 3
searchtype은 생략, itemname, description, both(둘다)
=> itemid를 이용해서 하나의 데이터를 조회
=> item을 입력받아서 데이터 삽입
1) DTO 클래스를 생성
=> 기본 패키지에 domain 패키지에 생성 - quarterback
=> 롬복을 이용하는 경우는 변수만 선언하고 상단에 @Data 추가
=> 롬복을 사용하지 않는 경우는 변수와 접근자 메소드(getter & setter)를 생성
package kakao.itstudy.oracleserver.domain;
import lombok.Data;
@Data
public class Quarterback {
//변수 이름을 만들 때 테이블의 컬럼이름과 일치하게 생성
private String player_name;
private String position_name;
private String team_name;
private Integer passyds;
private Integer att;
private Integer cmp;
private Double cmpper;
private Integer td;
private Integer intercept;
private Double rate;
private Integer longestpass;
private Integer sack;
}
2) quarterback 테이블에 필요한 SQL을 작성해 놓을 mapper 파일을 생성
=> src/main/resources/mybatis/mappers/quarterback.xml
=> 처음 만들 때는 디렉토리를 추가
=> MyBatis 동적 SQL : 조건에 따라 변경되는 SQL
=> MyBatis에서 동적으로 변화하는 SQL 작성은 이렇게
<sql id="아이디">
<if test="조건>
sql 구문
</if>
....
</sql>
=> 동적 sql을 사용할 곳에서 작성
<include refid="아이디"></include>
=> 데이터 개수 구하기 : 페이지 단위로 데이터 가져올 때 필수
searchtype이 null이거나 없으면 : select count(*) from quarterback
searchtype이 itemname이고 keyword가 존재하면 : select count(*) from item where itemname like '%' || keyword || '%'
searchtype이 description이고 keyword가 존재하면 : select count(*) from item where description like '%' || keyword || '%'
searchtype이 both이고 keyword가 존재하면 : select count(*) from item where itemname like '%' || keyword || '%' or description like '%' || keyword || '%'
특정 조건에 맞는 데이터를 특정 컬럼으로 정렬해서 데이터를 페이지 단위로 가져오기
1. Oracle
select 가져올 컬럼이름 나열
from (select rownum rnum, 가져올 컬럼 나열
from (select 가져올 컬럼 나열
from 테이블이름
where 조건
order by 정렬할컬럼이름 ASC 또는 DESC))
where rnum >= 시작번호 and rnum <= 종료번호
=> 시작번호는 1부터
=> 상황에 따라 where 나 order by는 생략되는 경우도 있다.
검색조건: 검색키워드 페이지번호, 페이지당 데이터 개수를 매개변수로 받을 것이다.
검색조건이 itemname 이고 검색키워드가 l, 페이지번호는 1, 데이터 개수는 3
서비스의 메소드에서 페이지 번호와 데이터 개수를 가지고 시작번호와 종료변호를 구해야 한다.
select itemid, itemname, price, description, pictureurl
from (select rownum rnum, itemid, itemname, price, description, pictureurl
from (select itemid, itemname, price, description, pictureurl
from item
where itemname lite '%' + 'i' + '%'
order by itemid desc))
where rnum >=1 and rnum <= 3
=> 데이터목록가져오기
<!-- 데이터 목록 가져오기
searchtype, keyword, start, end를 입력받아서 데이터 목록을 리턴해주는 SQL
Map은 searchtype, keyword, start, end을 묶어주기 위한 자료형
resultType은 select 절의 데이터를 묶을 수 있는 자료-->
<select id=list"
parameterType="java.util.Map"
resultType="kakao.itstudy.oracleserver.domain.Quarterback">
select itemid, itemname, price, description, pictureurl
from (select rownum rnum itemid, itemname, price, description, pictureurl
from itemid, itemname, price, description, pictureurl
from item
<include refid="search"></include>
order by itemid desc))
where rnum >= #{start} and rnum <= #{end}
</select>
2. MySQL에서의 페이징
select 필요한 컬럼이름 나열
from 테이블이름
wherer 조건
order by 정렬한 컬럼이름 ASC 또는 DESC
limit 시작번호, 가져갈 데이터 개수
=> 시작번호는 0부터 시작
=> item 테이블에서 itemname에 l 이 포함된 데이터 중에서 페이지 당 3개씩 1페이지의 데이터 가져오기
select itemid, itemname, price, description, pictureurl
from item
where itemname like '%' 'l' '%'
order by itemid desc
limit 0, 3
<?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 namespace="quarterback">
<!-- 데이터 개수와 데이터 목록을 위한 동적 SQL -->
<sql id="search">
<!-- searchtype 이 null이거나 글자가 없다면 where 절 없다. -->
<if test="searchtype==null"></if>
<if test="searchtype==''.toString()"></if>
<if test="searchtype=='player_name'.toString()">
where lower(player_name) like '%' || #{keyword} || '%'
</if>
<if test="searchtype=='description'.toString()">
where lower(description) like '%' || #{keyword} || '%'
</if>
<if test="searchtype=='both'.toString()">
where lower(player_name) like '%' || #{keyword} || '%' or lower(description) like '%' || #{keyword} || '%'
</if>
</sql>
<!-- 데이터 개수 찾아오기
Map에서 searchType을 확인해서 일치하는 sql을 추가-->
<select id="count"
resultType="java.lang.Integer"
parameterType="java.util.Map">
select count(*)
from quarterback
<include refid="search"></include>
</select>
<!-- 데이터 목록 가져오기
searchtype, keyword, start, end를 입력받아서 데이터 목록을 리턴해주는 SQL
Map은 searchtype, keyword, start, end을 묶어주기 위한 자료형
resultType은 select 절의 데이터를 묶을 수 있는 자료-->
<select id="list"
parameterType="java.util.Map"
resultType="kakao.itstudy.oracleserver.domain.Quarterback">
select itemid, itemname, price, description, pictureurl
from (select rownum rnum itemid, itemname, price, description, pictureurl
from itemid, itemname, price, description, pictureurl
from item
<include refid="search"></include>
order by itemid desc))
where rnum >= #{start} and rnum <= #{end}
</select>
<!-- 상세보기
기본키를 받아서 기본키에 해당하는 모든 컬럼을 가져오면 된다. -->
<select id="detail"
parameterType="java.lang.Integer"
resultType="kakao.itstudy.oracleserver.domain.Quarterback">
select itemid, itemname, price, description, pictureurl
from itemid
where itemid=#{itemid}
</select>
<!-- 데이터 삽입하기
필요한 컬럼의 값을 입력받아서 삽입한다.
삽입이나 삭제나 갱신은 무조건 정수를 리턴하기 때문에 resultType이 없다.-->
<insert id="insert"
parameterType="kakao.itstudy.oracleserver.domain.Quarterback">
insert into quarterback(itemid, itemname, price, description, pictureurl)
values(#{itemid}, #{itemname}, #{price}, #{description}, #{pictureurl})
</insert>
</mapper>
3) 데이터베이스 관련된 작업을 할 때 로그 기록을 위한 설정을 추가 - 1번만 수행
src/main.resources 디렉토리에 log4jdbc.log4j2.properties 파일을 만들고 내용을 작성
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
=> 이 작업과 DataSource 연결부분을 수정하면 콘솔에서 어떤 SQL이 어떻게 수행되고 결과가 어떻게 되는지 출력을 해준다.
4) root-context.xml 파일에 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>net.sf.log4jdbc.sql.jdbcapi.DriverSpy</value>
</property>
<property name="url">
<value>jdbc:log4jdbc:oracle:thin:@192.168.0.76:1521:xe</value>
</property>
<property name="username">
<value>user09</value>
</property>
<property name="password">
<value>user09</value>
</property>
</bean>
</beans>
5) test 패키지에 DataSource를 주입받아서 테스트 - 1번
package kakao.itstudy.oracleserver;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
public class DataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void dsTest() {
System.out.println(dataSource);
}
}
5) root-context.xml 파일에 MyBatis 설정 빈을 추가
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations"
value="classpath:mybatis/mappers/**/*.xml" />
</bean>
<bean id="sqlSession"
class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
6) test 패키지에 Test 클래스를 만들고 MyBatis 설정 빈이 제대로 만들어졌는지 테스트
package kakao.itstudy.oracleserver;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
public class mybatisTest {
//MyBatis 객체
@Autowired
private SqlSession sqlSession;
//MyBatis 설정 테스트
@Test
private void mybatisConfigTest() {
System.out.println(sqlSession);
}
}
7) SQL을 작성하고 전부 테스트
=>SQL 테스트를 할 때 로케일을 확인할 수 없습니다 메시지가 출력되는 경우
Mac OS X을 설치하고 또는 업데이트하고 지역설정을 다시 하지 않아서 입니다.
시스템 환경 설정에서 [언어 및 지역]에서 다른 국가로 설정하고 종료한 후 다시 열어서 대한민국으로 수정
import java.util.HashMap;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import kakao.itstudy.oracelserver.domain.Item;
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
public class MyBatisTest {
//MyBatis 객체
@Autowired
private SqlSession sqlSession;
//MyBatis 설정 테스트
@Test
public void mybatisConfigTest() {
System.out.println(sqlSession);
/*
//아무런 조건없이 테스트
Map<String, Object> map =
new HashMap<String,Object>();
System.out.println("데이터 개수:" +
sqlSession.selectOne(
"item.count", map).toString());
map.put("start", 1);
map.put("end", 2);
System.out.println("데이터 목록:" +
sqlSession.selectList(
"item.list", map).toString());
//description에 비타민이 포함된 데이터 개수
map.put("searchtype", "description");
map.put("keyword", "비타민");
System.out.println("데이터 개수:" +
sqlSession.selectOne(
"item.count", map).toString());
System.out.println("데이터 목록:" +
sqlSession.selectList(
"item.list", map).toString());
*/
//상세보기 테스트
/*
System.out.println(sqlSession.selectOne(
"item.detail", 1).toString());
*/
//가장 큰 itemid 찾아오기
int maxid = sqlSession.selectOne("item.maxid");
System.out.println(maxid);
//삽입
Item item = new Item();
item.setItemid(maxid + 1);
item.setItemname("망고");
item.setPrice(3000);
item.setDescription("노란 과일");
item.setPictureurl("default.jpg");
//MyBatis는 AutoCommit이어서 테스트 할 때 삽입하면
//데이터가 실제 삽입이 됩니다.
//Hibernate는 테스트할 때 결과만 확인할 수 있고
//마지막에 rollback을 수행
int row = sqlSession.insert("item.insert", item);
System.out.println("영향받은 행의 개수:" + row);
}
}
8) dao 패키지에 DAO 클래스 생성
=>dao.ItemDAO
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import kakao.itstudy.oracelserver.domain.Item;
@Repository
public class ItemDAO {
@Autowired
private SqlSession sqlSession;
//searchtype 과 keyword를 이용해서 데이터 개수 찾아오는 메소드
public int count(Map<String, Object> map) {
return sqlSession.selectOne("item.count", map);
}
//searchtype 과 keyword 와 start 와 end를 데이터 목록을 찾아오는 메소드
public List<Item> list(Map<String, Object>map){
return sqlSession.selectList("item.list", map);
}
//itemid에 해당하는 데이터 1개를 메소드
public Item detail(int itemid) {
return sqlSession.selectOne("item.detail", itemid);
}
//가장 큰 itemid를 찾아오는 메소드
public int maxid() {
return sqlSession.selectOne("item.maxid");
}
//데이터를 삽입하는 메소드
public int insert(Item item) {
return sqlSession.insert("item.insert", item);
}
}
9)Test 클래스를 만들거나 이전 테스트 클래스에서 ItemDAO 테스트
//DAO 테스트
@Autowired
private ItemDAO itemDao;
@Test
public void daoTest() {
//DAO 확인
//System.out.println(itemDao);
/*
Map<String, Object> map =
new HashMap<String, Object>();
map.put("searchtype", "description");
map.put("keyword", "비타민");
System.out.println(itemDao.count(map));
*/
/*
Map<String, Object> map =
new HashMap<String, Object>();
map.put("searchtype", "description");
map.put("keyword", "비타민");
map.put("start", 1);
map.put("end", 3);
System.out.println(itemDao.list(map));
*/
//System.out.println(itemDao.detail(3));
//System.out.println(itemDao.maxid());
Item item = new Item();
item.setItemid(8);
item.setItemname("과자");
item.setPrice(2000);
item.setDescription("애들이 좋아함");
item.setPictureurl("default.jpg");
System.out.println(itemDao.insert(item));
}
10)DAO 까지 테스트를 할 때 많이 발생하는 오류
=>Mapped statement not contains value ???? : mapper 파일에 만든 SQL의 이름과 DAO 클래스에서 호출한 이름이 달라서 발생하는 예외
=>jdbc type null parameter ???? : 대입해야 할 파라미터가 제대로 대입이 안된 겁니다.
매개변수를 잘 확인
=>이 모든 것들이 메소드 설계(작업)가 잘 되야 가능한 것이므로 구현할 작업에 대해서 먼저 생각을 하고 메소드 모양을 생각해야 합니다.
무엇을 주어야 하고 무엇을 받을 것인지를 고민
Insert, update, delete는 무엇을 받을 것인지는 고민할 필요가 없음
select만 무엇을 받을 것인지 고민
SQL을 확인
Mapper 파일을 만들고 테스트
DAO를 만들고 테스트