2015년 11월 25일 수요일

오라클 버전 지원


안녕하세요.. 구멍가게 코딩단입니다.

갑자기 날씨가 겨울이 되었네요..

지난 8월 '코드로 배우는 스프링'의 출간 후 벌써 100일의 시간이 지났습니다.


코드로 배우는 스프링의 오라클 버전에 대한 문의가 많아서 다음과 같이 결정 사항을 알려드리도록 합니다.

* 오라클 버전으로 새로운 책은 아직 결정된 적이 없습니다.

* 현재 MySQL로 처리된 데이터베이스를 오라클 버전(11g)로 블로그를 통해서만 수정합니다.

* 블로그를 통해서 도서의 특정 페이지의 MySQL의 부분을 오라클로 변경해서 블로그에 게시합니다.

* 블로그에 게시된 내용은 별도의 워드 파일로 제공해서 필요하신 분들이 인쇄해서 원래의 도서와 같이 사용할 수 있도록 제공합니다.


--------------------------------------------------------------------------------------------------

오라클 버전 제작 일정

오라클 버전의 갱신은 12월 10일 이후 진행하여, 12월 31일 이전까지 완료하는 것을 목표로 합니다.

 



2015년 11월 1일 일요일

@ModelAttribute에 대한 짧은 이야기


스프링 MVC에서 사용되는 @ModelAttribute 애노테이션은 말 그대로 객체를 모델의 속성으로 자동으로 지정하는 역할을 하게 됩니다. 이 기능을 이용하면 파라미터로 수집된 객체를 다시 모델로 처리해야하는 번거로운 과정을 줄일 수 있습니다.


일반적으로 컨트롤러에서는 다음과 같은 패턴의 작업이 이루어 집니다.

1) 전달받은 파라미터를 이용해서 결과 데이터를 만들어서 화면에 결과 데이터만을  전송하는 경우


2) 전달받은 파라미터를 이용해서 처리한 결과 데이터와 더불어 입력시에 사용한 파라미터를 다시 전송하는 경우


1)의 경우에는 결과 페이지로 새롭게 생성된 결과를 전송하기 때문에 굳이 @ModelAttribute를 이용하지 않아도 관계 없습니다.

반면에 2)의 경우는 만들어진 결과 뿐이 아니라, 입력된 값도 객체로 처리해서 재사용하는 경우입니다.

간단한 클래스를 이용해서 예제를 만들어 보도록 합니다.

Sample클래스는 id,pw의 속성과 price라는 속성을 가지고 있습니다.



컨트롤러에서 아래와 같은 메소드를 작성해 주었습니다.



samlePost( ) 메소드의 경우는 별도의 Model객체를 사용하지 않지만, @ModelAttribute를 이용해서 자동으로 모델로 처리되고, setPrice( )를 이용해서 추가적인 정보를 처리하고 있습니다.


JSP에서는 EL을 이용해서 간단히 처리할 수 있습니다.





@ModelAttribute는 이와 같이 Request로 전달된 데이터를 가공하는 데 있어서 좀 더 편리한 수단을 제공합니다.



PART 2에서의 게시판 처리 부분에 @ModelAttribute를 이용하는 부분은 아래와 같습니다.




라인 101에 선언된 listAll( )의 경우는 @ModelAttribute가 없는 상태입니다. listAll( )의 결과 페이지 역시 아래와 같이  Criteria를 사용하지 않고 있습니다.





라인 108의  listPage( )의 경우는 조금 얘기가 다릅니다. 라인 109에서 Criteria를 @ModelAttribute를 이용해서 cri라는 이름으로 저장했고,

라인 115에서 pageMaker.setCri( )를 통해서 저장해서 엄밀히 말해서 2중으로 결과 데이터로 전송하고 있습니다.


JSP에서는 아래의 코드를 이용하고 있습니다.




이 경우 PageMaker객체의 내부에 있는 Criteria객체를 이용하고 있기 때문에 @ModelAttribute로 저장한 cri는 사용하고 있지 않습니다.


굳이 Criteria를 2중으로 JSP로 전송한 이유는 사실 페이징 처리가 없는 무한 스크롤 페이징 처리를 고려한 것입니다.


즉 무한 스크롤에서는 페이징 처리는 없지만, 페이지에 대한 정보는 유지해야 하기 때문에 Criteria를 JSP로 전송하는 것이 좋습니다.

반면에 페이지 처리는 PageMaker만을 이용해서만 모든 것이 가능한 것이 좋다고 생각합니다.


따라서 Criteria를 @ModelAttribute로도 전송하고, PageMaker내부로도 저장해서 전송하는 형태가 되었습니다.



2015년 10월 31일 토요일

오라클의 scott계정 테이블 스크립트

CREATE TABLE DEPT
(DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY,
DNAME VARCHAR2(14) ,
LOC VARCHAR2(13) ) ;


CREATE TABLE EMP
(EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT);


INSERT INTO DEPT VALUES
(10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT VALUES
(30,'SALES','CHICAGO');
INSERT INTO DEPT VALUES
(40,'OPERATIONS','BOSTON');
INSERT INTO EMP VALUES
(7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);
INSERT INTO EMP VALUES
(7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
INSERT INTO EMP VALUES
(7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
INSERT INTO EMP VALUES
(7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
INSERT INTO EMP VALUES
(7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);
INSERT INTO EMP VALUES
(7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);
INSERT INTO EMP VALUES
(7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);
INSERT INTO EMP VALUES
(7788,'SCOTT','ANALYST',7566,to_date('13-JUL-87')-85,3000,NULL,20);
INSERT INTO EMP VALUES
(7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);
INSERT INTO EMP VALUES
(7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);
INSERT INTO EMP VALUES
(7876,'ADAMS','CLERK',7788,to_date('13-JUL-87')-51,1100,NULL,20);
INSERT INTO EMP VALUES
(7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);
INSERT INTO EMP VALUES
(7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);
INSERT INTO EMP VALUES
(7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);


CREATE TABLE BONUS
(
ENAME VARCHAR2(10) ,
JOB VARCHAR2(9) ,
SAL NUMBER,
COMM NUMBER
) ;

CREATE TABLE SALGRADE
( GRADE NUMBER,
LOSAL NUMBER,
HISAL NUMBER );

INSERT INTO SALGRADE VALUES (1,700,1200);
INSERT INTO SALGRADE VALUES (2,1201,1400);
INSERT INTO SALGRADE VALUES (3,1401,2000);
INSERT INTO SALGRADE VALUES (4,2001,3000);
INSERT INTO SALGRADE VALUES (5,3001,9999);
COMMIT;

2015년 10월 7일 수요일

2015년 9월 24일 목요일

오라클 연동시에 JDBC드라이버 주의하세요.


책의 예제는 MySQL로 작성되어 있지만, 간혹 오라클 버전에 관한 문의가 많이 와서 몇 자 적습니다.


Maven을 이용해서

<repository>
<id>oracle</id>
<name>ORACLE JDBC Repository</name>
<url>http://mesir.googlecode.com/svn/trunk/mavenrepo</url>
</repository>

에 있는 오라클용 JDBC를 받으시는 분들이 많습니다만..


이것은 과거에 CD에 있는 jar파일을 이용하시는 것 만큼 위험한 일입니다.

JDBC를 이용하실 때에는 반드시 현재 자신이 사용하는 DB의 드라이버 버전을 확인해 주시고 이에 맞게 사용해야만 합니다.

위의 경로의 경우는 오라클 10 버전의 드라이버이고, JDK1.4 버전에 최적화된 드라이버이므로 이를 사용하는 것은 에러를 발생하는 원인이 됩니다.

JDK1.6버전을 이용하신다면 이에 맞는 ojdbc6를 이용하시길 바랍니다.

2015년 9월 23일 수요일

Tomcat7 버전에서 파일다운로드 한글처리


Tomcat 8버전과 달리 Tomcat7 버전은 get방식으로 한글 데이터를 자동으로 처리하지 않습니다.

만일 Tomcat 7 버전에서 한글을 처리하려면 Tomcat의 설정을 변경하거나, 파라미터에 대한 대한 한글 처리를 해 주어야 합니다.


Tomcat이 설치된 실제 경로를 찾아서 conf 폴더내의 server.xml을 찾아서 아래와 같이 설정을 변경합니다.


 <Connector connectionTimeout="20000" port="8081" protocol="HTTP/1.1" redirectPort="8443"  URIEncoding="UTF-8"/>


STS나 Eclipse에서 Tomcat을 설정하는 경우 server.xml의 위치는

현재의 workspace 밑의

\.metadata\.plugins\org.eclipse.wst.server.core\tmp2\conf

와 같은 경로입니다.

(해당 폴더가 안 보인다면 제어판의 폴더 옵션에서 숨김 폴더 보기를 설정합니다).



만일 코드로 처리한다면 다음과 같은 형태로 작성할 수 있습니다. 

 String test = request.getParameter("test ");
 test = new String(test .getBytes("8859_1"), "UTF-8");

2015년 9월 22일 화요일

Part4에서의 오라클 적용 참고하세요

Part 4의 예제에서는 tbl_user와 tbl_message 테이블이 생성됩니다.

오라클의 경우에는 Sequence를 이용해야 하므로 테이블의 생성은 다음과 같이 작성되어야 합니다.



create table tbl_user (
 userid varchar2(50) not null,
 userpw varchar2(50) not null,
 username varchar2(100) not null,
 upoint number(10,0) default 0
 );

alter table tbl_user add constraint pk_user primary key (userid);

create table tbl_message (
 mid number not null,
 targetid varchar2(50) not null,
 sender varchar2(50) not null,
 message varchar2(2000) not null,
 opendate date,
 senddate date default sysdate
 );

create sequence seq_message;


SQL Mapper에서는 Sequence를 사용하는 코드로 변경되어야 합니다.
아래의 코드는 소스 코드 중에서 messageMapper.xml의 일부 입니다.



<mapper namespace="org.zerock.mapper.MessageMapper">

<insert id="create">
insert into tbl_message (mid, targetid, sender,message)
values (seq_message.nextval, #{targetid}, #{sender}, #{message})
</insert>


<select id="readMessage" resultType="MessageVO">
select * from tbl_message where mid = #{mid}
</select>

<update id="updateState">
update tbl_message set opendate = now() where mid= #{mid}
</update>

</mapper>

실행되는 코드의 결과는 아래와 같이 출력되어야 합니다.


참고로 질문하신 479페이지까의 소스 코드 올려 두었으니 본인이 작성하신 부분과 다른 점들 비교해 보시면 좋을 듯 합니다.




2015년 9월 17일 목요일

오라클에서의 페이징 처리


구코단의 쿠키입니다. 




질문하시는 내용 중에 오라클로 페이징 처리와 관련해서 문의하시는 분들이 있으셔서 블로그에 정리해 놓도록 하겠습니다. 


게시판 생성 SQL문입니다. 


create table tbl_board (
bno number,
title varchar2(400) not null,
content varchar2(2000) not null,
writer varchar2(50) not null,
regdate date default sysdate,
viewcnt number default 0
);

create sequence seq_board;

alter table tbl_board add constraint pk_board primary key (bno);



페이지 처리 기본 



일반적으로 오라클의 경우는 페이징 처리에 rownum을 활용합니다. rownum은 테이블에서 데이터가 출력될 때 붙는 번호라고 이해하시면 좋습니다.

rownum은 출력되면서 붙는 번호이기 때문에 어떤 식으로 SQL문이 실행되는지에 따라서(실행 계획)에 붙는 번호가 달라지게 됩니다.



위의 SQL의 경우는 오라클의 힌트를 이용해서 역순으로 데이터를 조회하는 예입니다. 이 경우 pk_board는 PK의 이름으로 해석하자면 pk_board를 역순으로 뒤지면서 데이터를 찾아내라는 뜻입니다.

rownum이 10보다 작거나 같기 때문에 10개의 데이터만 출력되는 것을 볼 수 있습니다.




2페이지 처리 하기 


rownum은 데이터가 나오면서 붙여주는 번호이기 때문에 rownum > 10 and rownum <= 20과 같은 SQL문은 제대로 결과가 나오지 않습니다.

rownu > 10 구문에서 어떤 데이터가 나오면 rownum은 1이 되기 때문에 rownum > 10조건에 맞지 않기 때문에 건너뛰게 됩니다.

이러한 이유로 흔히 rownum은 반드시 1이 포함되어야 한다고 합니다.


2페이지를 처리하기 위해서는 'in-line view'라는 기술을 알아야만 합니다. in-line view는 쉽게 말해서 from 구문에 다른 SQL문이 들어간 형태입니다.


2페이지의 데이터 처리는 다음과 같습니다.



SQL문을 자세히 보면 from  내부에 SQL문이 하나 더 사용되는 것을 볼 수 있습니다.

위의 SQL문은 rownum이 20보다 작거나 같은 데이터(2페이지까지의 모든 데이터)를 in-line view로 처리하고, rn이라는 컬럼을 만들어 냅니다.

외부에서는 rn컬럼의 값이 10보다 크다는 조건을 이용합니다.




위의 결과와 비교해 보면 2페이지의 데이터가 출력되는 것을 볼 수 있습니다.



MyBatis의 SQL문 

MySQL의 limit의 경우 사용하기 쉽지만, 오라클의 경우는 조금 복잡하므로 페이징 처리와 관련한 SQL문은 아래와 같은 형태로 수정되어야 합니다. 




작성된 SQL문은 PART 2의 예제에서 다음과 같이 출력되어야 합니다.






2015년 9월 1일 화요일

PART1 1장에서 3장 동영상

PART 1의 강의자료와 동영상입니다. 

8월 말까지 제작을 목표로 했으나 9월 첫주까지 조금 연기될 듯 합니다.
작성되는 데로 게시물을 수정하도록 하겠습니다. 

강의자료 PPT 링크입니다. 



PART 1.1 STS설치 및 프로젝트 생성하기 




PART 1.1 STS설치 및 프로젝트 Tomcat 



PART 1. 2 스프링 간략 소개 



PART 1. 3 MySQL 설치 및 설정 




PART 1. 3 MySQL 연결 테스트 



2015년 8월 28일 금요일

PART2의 static.zip과 include.zip파일의 링크를 추가합니다.


구코단의 쿠키입니다.

죄송스럽게도 출판사의 홈페이지에 업로드된 소스 코드의 링크 중에 static.zip과 include.zip파일이 누락되었습니다.

현재 제공중인 ex01.zip파일에서 해당 폴더를 참고해서 작업하시는 것도 가능합니다만, 필요하실지도 몰라서 아래의 링크로 해당 파일들을 업로드 해 두었습니다.


include.zip



static.zip

빠른 시간 내에 출판사에 홈페이지 수정작업을 부탁드리겠지만, 혹시 주말 동안 학습하신다면 위의 링크를 이용해서 파일을 다운로드 해 주시면 감사하겠습니다.

-----------------------------------------------------------------------------
2015년 9월 3일 이후 남가람 북스 페이지에서도 받으실 수 있습니다.



불편을 끼쳐드려서 죄송합니다.


2015년 8월 25일 화요일

PART1의 동영상 제작 계획입니다.

PART 1의 동영상 제작 및 배포


구멍가게 코딩단(이하 구코단)에서는 PART 1 부분은 YouTube를 통해서 제작한 동영상과 강의자료를 무료로 업로드 하기로 결정하였습니다. 


PART 1의 동영상은 2015년 8월 말을 목표로  Windows 8.1버전을 대상으로 제작되어 블로그에 공유될 예정입니다.





구코단 집필 담당 쿠키

2015년 8월 19일 수요일

2015년 8월 12일 수요일

MyBatis에서 Mapper인터페이스를 활용하기

대부분의 SI업체의 코드를 보면 MyBatis를 이용하고 있기는 하지만, 실제적으로 그 코딩 방식은 MyBatis의 이전 버전이었던 iBatis의 코딩 방식과 거의 동일하게 사용하는 것을 많이 보게 된다.

MyBatis의 Mapper인터페이스를 활용한다면 좀 더 간결하게 코드를 생성할 수 있을텐데..

















2015년 8월 10일 월요일

MyBatis에서 사용하는 SQL의 로그를 찍자. log4jdbc-log4j2


과거에는 주로 log4jdbc를 이용했지만, log4jdbc-log4j2가 성능면에서 더 낫다고 해서 요즘은 주로 아래와 같이 설정해서 사용 중.






코딩단의 쿠키 - 공부도 요령이지!




새로운 공부를 하는 데 있어서 내가 중요하게 생각하는게 몇 가지가 있다.

* 우선 내가 아는 것과 연결시키려고 애쓰지 않는다. 

새로운 언어나 기술을 공부하다보면 유독 기존의 어떤 기술과 비교하는 경우가 많은데, 이 방법은 처음 접하는 사람들에게는 좋을수 있지만, 제대로 공부하는데에는 방해가 된다.

오히려 새로 배우는 것이 전혀 다른 내용이라고 생각하고, 접근하다가 기존의 기술과 통하는 접점을 찾는 것이 더 즐거운 일이 되는것 같다.


예를 들어 C언어의 포인터와 Java의 레퍼런스는 분면 거의 유사한 개념이지만, 처음부터 Java의 레퍼런스를 포인터로만 본다면 십중팔구 혼란스러운 부분이 생길 수 있다.

반면에 포인터와 별개로 레퍼런스 개념을 보다보면 결국 두 언어 모두 포인터를 사용하는 언어라는 사실을 느낄 수 있는 것과 같다.




물론 이렇게 되기 위해서는 다른 방식보다 약간의 인내와 노력이 더 필요하지만, 나중에 여러 기술을 가로지르는 공통의 '원리'를 깨달을 수 있기 때문에 발전하는 데 있어서 중요한 추진력이 되는 것 같다.




* 눈에 보이는 결과가 중요하다. 

사람이란 감정의 동물이다. 아무리 좋은 기술이라고 해도 자신이 만들 수 있는 결과가 없다면 공허하고, 지치게 마련이다.

프로그래밍을 처음 했을 때 'Hello World'에 감동했던 그 순간을 기억해야 한다. 작지만 한 발짝 앞으로 나가는 느낌. 그 느낌을 지속적으로 느끼는 일이야말로 지치지 않는 힘이 된다.


* 따라할 때는 철저하게 따라하라. 

가끔 라이브러리나 프레임워크를 이용하는 코드를 만들었는데 제대로 실행되지 않는다고 투덜되는 사람들의 코드를 보면, 서둘러 자신이 원하는 결과를 보기 위해서 코드를 마음대로 고쳐서 사용하는 경우가 많다.

처음 해보는 기술이라면 반드시 자료와 동일한 코드를 작성하는 것이 좋다. 이 작업이 시간이 더 걸릴것처럼 보이지만, 실제로는 정반대인 경우가 많다.

돌아가는 모습을 확인해야 나중에 어디를 수정해서 사용할 수 있는지 판단할 수 있기 때문에, 자신이 잘 아는 분야가 아니라면 철저하게 자료의 코드를 그대로 작성하는 것이 좋다.


* 개발도 과정이 필요하다. 

어떤 기술을 이용해서 개발하는 데 있어서 단계를 미리 결정하는 것은 중요하다. 예를 들어 구구단을 만들 때에도 처음부터 2중루프를 돌리면 배우는 사람들은 이해하기 힘들수 밖에 없다.

처음에는 단일 루프로 번호가 바뀌는 것을 보여주고, 그 다음에 다시 변수를 하나 추가하고, 그 다음에 그 변수에 루프를 적용하는 등의 작지만 단계를 가지는 형태의 개발이 중요하다.

잘하는 개발자와 못하는 개발자들을 보면 자신만의 이러한 단계를 빨리 수립하는 차이가 있다. 잘하는 개발자들을 보면 자신이 만들어서 확인하려는 목표가 확실하다.




MySQL의 설치와 스프링에서의 확인 작업



스프링을 이용하기 전에 데이터베이스를 올바르게 설정하는 작업은 필요합니다. 

이번 포스트의 내용은 MySQL의 설치와 이를 스프링의 테스트를 이용해서 연결 작업을 테스트하는 것입니다.