2015년 1월 26일 월요일

[평일야간,주말주간야간]JAVA,Network&JSP&Spring,MyBatis,Hibernate-개인부담0~20%

[평일야간,주말주간야간]JAVA,Network&JSP&Spring,MyBatis,Hibernate-개인부담0~20%
 
소수 정예 과정!!
 
자세한 교육일정/상세 및 지원방법은 아래  URL에서 확인 바랍니다.





 

강좌명JAVA,Network&JSP&Spring,MyBatis(자바기초에서JSP,Ajax,jQuery,Spring3.2,MyBatis까지)
오라클자바커뮤니티(www.oraclejavacommunity.co.kr) 추천 실전강좌
교재자체교재 or PDF 제공(교재비 25,000원 별도)
강좌 일정상단 URL 참조
강의 장소[A강의장]구로디지털단지역2번 출구 -> 미니스톱끼고 우회전 -> 100m 직진 후 골목길 끝에서 횡단보도 건너기 --> 우회전 후 구로호텔 직전 좌측길, 호텔 바로 뒤편 파트너스타워2차 301호
[약도보기]
수강절차- 강좌내용 확인
- 전화 또는 홈페이지(www.oraclejavacommunity.com)를 통한 수강지원 및 수강료 결제(무통장입금, 온라인 카드결제)
- 고용보험 가입자(재직자)인 경우 고용보험환급 관련 서류 제출
- 수강전 : 커리큘럼 및 장소에 대해 다시 한번 공지
- 교육 전 설문 작성(간단한 개발 경력, 수강 목적, 강좌진행방식 등)
- 강좌 수강
- 수강후 : 교육 후 설문 작성
수강료- 과정당 수강료 및 환급가능금액은 상단 URL에서 참조바랍니다.
* 휴강 :법정공휴일
수강료
입금안내
- 온/오프라인 카드결제, 계좌이체(수강안내->입금안내 참조)
- 상단 URL에서 확인 부탁드립니다.
문의사항02-851-4790 번으로 연락 부탁 드립니다.
교육개요본과정은 단기간에 자바기반 프로그래머를 양성하기 위한 과정이며, 프로그래밍 언어의 경험이 있는 분이지만 자바를 처음하시는 분들을 위해 짧은 기간에 현장에서 필요로 하는 기술들을 최적화된 교재 및 강사를 통해 배울 수 있도록 하는 과정 입니다.

자바의 기본적인 사항부터 JDBC 프로그래밍, 자바네트워크 프로그래밍, JSP의 기본이 되는 Servlet 그리고 JSP의 기본적인 문법과 Ajax, jQuery를 통해 화면 깜박임없이 웹페이지를 역동적으로 구성할 수 있도록 배우며, 최근 가장 많이 사용되는 JAVA기반의 프레임워크인 Spring, SQL Data Mapper까지 배울 수 있는 그야말로 단기간에 자바 개발자로 가시고자 하는 분들을 위한 최적의 과정 입니다.

많은 양이라고 생각될지 모르지겠만 강사님들이 주시는 과제와 팁을 적절히 수행하고 그날그날 수업에 대해 복습을 하시면서 따라 온다면 자기도 모르는 사이에 자바 개발자로 거듭나 있을 것입니다.

감사합니다.
교육목표- 자바 문법의 이해
- 객체지향 프로그램 개발의 이해
- 자바네트워크의 이해(소켓프로그래밍, 자바RMI 프로그래밍)
- 자바 웹 개발의 이해
- Ajax, jQUERY와 같은 웹 기술에 대한 이해
- Servlet/JSP 개발에 대한 이해
- Spring3.X/4 Framework에 대한 이해
- Spring3/4 @MVC에 대한 이해
- iBATIS/MyBatis에 대한 이해
- Spring Transaction에 대한 이해
- Spring, iBATIS/MyBatis, Hibernate 연동에 대한 이해
교육대상- 자바개발자로 전향을 원하는 개발자
- 자바 초보 개발자
- 학생 및 신입 개발자
선수학습- 프로그래밍 언어 기본
 



JAVA Basic자바 언어 소개
개발환경 설치(JDK7/8, Eclipse4.3 Kepler/Luna)
기본 문법(연산자, 변수, 상수, 제어문, 반복문)
Virtual Machine 소개
JVM 메모리 영역
클래스 패스(Class Path), 설정방법
Array 이론/실습
클래스와 객체(Class & Object)
Abstarct Data Type
상속(Inheritance)과 다형성
추상클래스(Abstract Class)와 다형성
인터페이스(Interface)와 다형성
연관(Aggregation & Composition)
오버로딩(OverLoading)과 오버라이딩(Overriding)
this/super/constructor
Package 만들기 이론/실습
Java에서 예외 처리 요령
사용자 예외 처리 방법
스트림(Stream) 입출력 관련 클래스, InputStream/OutputStream,
FileInputStream/FileOutputStream
Reader/Writer등 입출력 관련 클래스
표준 입출력/FILE 처리, 객체 직렬화 이론/실습
Thread 개요
Java에서의 Process
Thread 우선순위/동기화
Thread Joining/Interrupt
JAVA8 Lambda __EXPRESSION__
JAVA8 Functional Interface
JAVA8 double colon Operator
JAVA Network ProgrammingURL/HTTP URL
URLConnection,HttpURLConnection
URL을 다루는 예제 실습(Get/Post)

Client Socket과 Server Socket의 개요
Echo Server
MultiThread EchoServer
Socket을 이용한 예제 구현

Distributed Computing(java RMI)
Distributed Computing, Object 소개
Java RMI를 이용한 “Hello World” 제작
RMI 응용예제 실습
JDBC ProgrammingConnection, Statement, ResultSet, PreparedStatement
(DML 예제 실습)
Oracle의 function, procedure 다루기
DBCP, DataSource, Connection Pool
Servlet/JSPServlet의 개요
HelloWorld Servlet
Servlet Mapping, WebServlet Annotation
Servlet의 Request, Response
Servlet에서의 Session, Cookie 다루기
JSP 기본문법
JSP 내장 객체
Java Beans
JSP에서의 Session, Cookie 다루기
JSTL, EL
MVC Model의 이해
Ajax/jQUERYAjax 개발환경 구축
왜 Ajax 인가?
Ajax의 기본 구성
XMLHttpRequest 객체
innerHTML의 사용
DOM(Document Object Model) 다루기
Ajax MVC

- jQuery 개요, 다운로드, 설치
- $(document).ready() 메소드
- Selector
- $(“*"), $("#ID"), $("DIV"),$(".classname"), $("p > a"),
- $(“elementname.classname")
- 속성 선택자, 속성(attr)
- 입력양식 필터 선택자
- 위치와 관련된 필터 선택자
- jQuery 배열(Array) 관리
- jQuery 객체 확장
- 기본 필터링 메소드
- 특정 위치 문서 객체 선택
- 문서 객체에서 특정 태그를 선택하는 방법
- innerHTML 속성과 관련된 jQuery 메서드
- 문서객체 생성 , 제거
- jQuery Event
- 이벤트 관련 메소드(발생, 제거)
- 이벤트 자동 발생
- 마우스/키보드/윈도우/입력양식 이벤트
- jQuery 기본효과, 사용자지정효과
- jQuery, Ajax 관련 메소드
- XML 문서 다루기
- 입력양식 전송
Spring3/4 FrameworkJAVA Bean vs EJB vs Spring
J2EE Framework에 대한 흐름과 Spring Framework에 대한 이해
개발 환경 설정(Eclipse4.2, Tomcat7, Spring3.2, MAVEN, STS 다운로드 및 설치)
Spring IoC
DL(Dependency LookUp) &DI(Dependency Injection)
Dependency Pull, CDL(Contaxtualized Lookup)
Setter/Constructor/Method Injection
DL. DI 예제를 통한 이해
Spring 설정(XML, Annotation)
Spring AOP 란 ?Code, Advice, JoinPoint,PointCut
Aspect, Weaving, ProxyFactoryBean
Annotation기반 AOP(AspectJ)
Auto Scanning 컴포넌트 (@Component,@Repository,@Service,@Contoroller)
@Resource vs @Autowired
ProxyFactoryBean을 통한 AOP 구현
AOP NAMESPACE를 통한 AOP 구현
@AspectJ Annotation을 통한 AOP 구현
Spring JDBC(이론 및 실습예제)
Spring Web MVC (이론 및 실습예제)
Spring Controller
Spring MVC Interceptor
@Controller, @RequestMapping, @SessionAttributes, @ModelAttribute
Spring4 @MVC Multiple File Upload
Spring 표현언어 SpEL
Spring Tiles 연동
Spring3/4 Transaction 관리
@Transactional Annotation, XML설정방식, 프로그래밍적 트랜잭션 처리방법의 이해
Spring Interceptor
Spring Tile연동
Spring Scheduling(Quartz연동)

Spring3/4 를 이용한 게시판 작성
- 리스트보기,글쓰기,읽기,댓글,답변글처리
- @MVC, @Controller, @RequestParam, @SessionAttibutes, @ModelAttribute 매핑 적용
- 주입(DI)를 Annotatrion으로 변경
- Spring AOP를 적용하여 게시판 DML 로깅 하기
- 스프링 게시판에 MyBatis 적용하여 SQL문을 XML안으로
iBATIS/MyBatis개요 및 소개
개발환경 설정 및 설치
Data Mapper란
sqlMapConfig 이해 및 환경설정
Spring, MyBatis 연동
SQL Map XML File 이해
SqlMapClient 이해
SQL의 실행(Insert/update/delete) 이해와 실습
Spring연동
HibernateHibernate 소개
SessionFactory 설정
1:1, 1:다 매핑
Session Interface
Hibernate DML
Spring, Hibernate 예제 프로그램 작성
Hibernate 설정을 Annotation으로...@Entity, @Table, @Id, @Column
Spring, Hinernate Transaction 실습
 

 

2015년 1월 22일 목요일

ORA-01950: no privileges on tablespace 해결법

ORA-01950: no privileges on tablespace 해결법

테이블스페이스 사용에 대한 권한이 없어서 발생하는 오류!

아래처럼 관리자 계정에서 해당 USER에게  권한을 주자.

ALTER USER <username> QUOTA 100M ON 유저명;
 
GRANT UNLIMITED TABLESPACE TO 유저명;

db block gets와 consistent gets

이미 아시겠지만 db block gets와 consistent gets는 Logical Read를 나타냅니다. 
두개를 더한 값 과 Pysical Reads를 비교해서 Hit Ratio를 구하죠. 
(The sum of db block gets and consistent gets equals the total read from the RAM data buffer cache) 

우선 consistent gets는 consistent mode에서 db block read를 수행한 숫자입니다. TKPROF 레포트에서 query에 해당하는 값입니다. consistent라는 말은 read consistency와 관련이 있는데 즉 읽기 일관성이 보장되는 상황에서 읽는 숫자라는 것입니다. 데이터를 수정하지 않고 단지 읽기만 하기때문에 lock이 발생하지 않습니다. 

db block gets는 CURRENT mode에 있는 block의 데이터를 읽은 숫자입니다. TKPROF 레포트에서 current에 해당하는 값이구요. current mode에서는 곧 수정될 Segment header나 block을 얻을 때 일어납니다. INSERT, UPDATE, DELETE에서 데이터 쿼리부분이 아니라 수정될 값을 읽을 때 나타나는 숫자입니다. select문일 경우에는 Full table scan일 경우 Segment header를 읽을 때 나타납니다. 

위의 내용은 Performance Tuning 문서에 있는 내용을 대충 정리한 것입니다. 그래서 아마도 위의 내용은 대부분 보셧을 내용이겠지만, 정확한 차이점을 이해하려면 더 많은 것들을 알고 이해해야합니다. 

여기서 Consistent mode와 current mode가 무엇인지를 아는 것이 중요합니다. 

우선 Consistency를 알기 위해서 오라클이 제공하는 Mulitversion concurrency control에 대해 알아야 합니다. 사용자가 쿼리를 날렸을때 그 순간의 이미지를 가지고 데이터를 가져오게 됩니다. 쿼리를 날린 후에 다른 세션에서(자기 자신의 세션에서도 마찬기지입니다.) 원하는 데이터가 수정이 되어도 처음 쿼리의 처리를 시작한 순간의 내용을 오라클은 제공합니다. 이런 처리를 위해 쿼리가 실행되는 순간 SCN(System change number)가 결정의 되고 각 DB Block의 scn과 비교하여 더 큰 scn을 가지고 있는 경우 즉 변경이 일어난 경우에는 rollback segment에서 과거의(자신의 scn보다 낮은 scn을 가지고 있는) 이미지의 block을 가지고 오게 됩니다. 

consistent gets가 consistent mode에서 block의 데이터를 읽은 숫자라는 것은 이와 같이 읽기 일관성이 보장되는 상황에서 읽은 block의 숫자라는 것입니다. 

DML문장이 수행되는 경우에 처리되는 부분을 두 부분으로 나눌 수 있는데, 하나는 수정할 데이터를 찾기 위해 읽는 부분이고, 다른 하나는 실제 데이터를 수정하기 위해 데이터를 읽는 부분입니다. 데이터를 찾기위해 읽는 부분은 INSERT문의 sub query부분과 delete문과 update문의 where 조건절에 해당하는 부분이나 sub query에 해당하는 부분입니다. 

DML문에서는 데이터를 찾기 위한 부분이 consistent gets에 나타나고 수정하기 위한 부분이 db block gets에 나타납니다. 

update t set value = value + 5 where value > 10; 
예를 들어 위와 같은 문장을 보면 처음 위의 문장이 실행 되는 순간의 이미지를 이용해서 조건에 맞는 즉 value가 10보다 큰 row들을 찾습니다. 그리고 각각의 row를 실제로 update하는 value = value + 5를 실행할때는 current mode에서 수행이 됩니다. 조건에 해당하는 row를 이미 읽었지만 수정하기 위해서 다시 또 읽게 됩니다. 이 때는 실제 데이터를 수정해야 하기 때문에 지금 바로 현재의 데이터여야 합니다. consistent mode에서 읽은 데이터는 과거의 이미지의 데이터일 수 있지만 수정시에는 가장 최근의 버젼을 수정해야 하기 때문입니다. 즉 current mode라는 것은 과거의 시점이 아닌 바로 지금의 data를 읽는 것을 말합니다. 

update문을 수행시에 consistent gets와 db block gets의 숫자를 비교해 보면 db block gets의 숫자가 더 큰 경우를 보게 되는데 이것은 consistent gets는 즉 수정될 로우를 찾을 경우는 block단위로 io가 일어나서 읽은 block의 수를 나타내게 되지만, db block gets는 즉 수정될 로우를 찾을 때는 각 로우마다 current mode에서 데이터를 읽기 때문에 같은 block도 row의 수만큼 읽게 됩니다. trace를 보시면 db block gets의 수는 실제 수정될 row의 수와 거의 같은 것을 확인하실 수 있습니다. 

consistent gets는 physical reads를 포함하고 있기 때문에 실제로 쿼리를 튜닝할 때 중요한 것은 Logical IO를 줄이는 것입니다. 이것에 관한 내용도 설명하자면 매우 길어지므로 여기서는 logical reads의 한 경우인 db block gets의 관한 예를 하나만 들겠습니다. 

다음의 두 문장은 똑 같은 읽을 수행합니다. 읽은 범위는 똑 같습니다. 즉 consistent reads의 수는 동일합니다. 그러나 db block gets의 숫자는 두배의 차이가 있기때문에 속도의 차이가 있습니다. 직접 샘플을 만들어 확인해 보시기 바랍니다. 
UPDATE ta A 
SET A.QTY = ( 
SELECT SUM(B.QTY) + A.QTY 
FROM tb B 
WHERE B.ID = A.ID 
); 

UPDATE ta A 
SET A.QTY = A.QTY + ( 
SELECT SUM(B.QTY) 
FROM tb B 
WHERE B.ID = A.ID 
); 


질문의 내용에는 벗어나지만 성능을 향상시키기 위해서는 LIO를 줄여야합니다. 모든 LIO는 latch를 발생시키기 때문에 가능한 적은 LIO를 수행하도록 하여야 좋은 성능과 확장성을 보장할 수 있습니다. 

[출처: dbguide]

[JSP,JSTL c:url 예제]

[JSP,JSTL c:url 예제]

c:url은 url을 만들어 내는데 url인코딩을 한다. 아래의 예제를 보자.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Tag Example</title>
</head>
<body>
<!-- 현재 context명이 web -->
<!-- 클릭시  http://localhost:8080/web/jsp/cookie.jsp 로 이동한다. -->
<!-- c:url이 만들어 내는 url은  'http://localhost:8080/web/jsp/cookie.jsp'-->
<!-- 홍  길   동 이라는 이름은 공백이 있는데 %20으로 url 인코딩되어 넘어간다. -->
<a href="<c:url value='/jsp/cookie.jsp?NAME=홍  길    동'/>"> cookie.jsp</a><br><br>

<!-- 클릭시  http://localhost:8080/web/로 이동한다. -->
<a href="<c:url value='/' />">COntext Root(/)</a>
</body>
</html>

서블릿 필터 어노테이션(Servlet Filter Annotation) 사용법,WebFilter,WebInitParam

서블릿 필터 어노테이션(Servlet Filter Annotation) 사용법,WebFilter,WebInitParam

서블릿 필터는 사용자의 요청을 JSP, Servlet등이 실행되기 전, 후에 가로챌 수 있는 기능이죠,
아래 예제를 참고하세요.
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

@WebFilter(filterName = "onjFilter",
urlPatterns = {"/*"},
initParams = {
    @WebInitParam(name = "addr", value = "seoul")})
public class OnjFilter implements Filter {
    public void init(FilterConfig config) throws ServletException 
    {
         this.fc = config;
    }
    public void doFilter(ServletRequest req, 
                          ServletResponse res, 
                 FilterChain chain) throws ServletException, IOException {
               HttpServletRequest httpReq = (HttpServletRequest) req;
               String ip = httpReq.getRemoteHost();
               System.out.println("IP Address is " + ip);
               chain.doFilter(req, res);
    }
     public void destroy() {// TODO Auto-generated method stub}
}


물론 위 처럼 어노테이션을 사용하지 않고 web.xml에서 아래와 같이 설정을 해도 가능하다.
<filter>
   <filter-name>onjFilter</filter-name>
   <filter-class>filter.OnjFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>onjFilter</filter-name>
   <url-pattern>*.jsp</url-pattern>
</filter-mapping> 

#84. 오라클 시퀀스(Oracle Sequence)

#84. 오라클 시퀀스(Oracle Sequence) 

시퀀스(Sequence) 

 다중 사용자 환경에서 사용하는 숫자 자동 생성기. 
 PK, UK 칼럼의 값을 유일하게 자동으로 생성하는 경우에도 사용된다. 
 트랜잭션 내에서 시퀀스가 생성되어 사용되다가 롤백 되는 경우에 다음 시퀀스 번호는 SKIP 될 수 있다. 
 테이블 또는 칼럼과는 독립적으로 생성, 삭제된다. 
 CURRVAL : 시퀀스의 현재 값을 리턴 
 NEXTVAL : 시퀀스를 증가시키고 next value를 리턴한다. 

 [형식] 
CREATE SEQUENC sequence_name 
                [INCREMENT BY n] 
                [START WITH n] 
                [{MAXVALUE n | NOMAXVALUE}] 
                [{MINVALUE n | NOMINVALUE}] 
                [{CYCLE | NOCYCLE}] 
                [{CACHE n | NOCACHE}] 

 INCREMENT BY n : 생성되는 Sequence번호의 간격을 정수 n으로 정의.  옵션이 생략되면 시퀀스는 1씩 증가한다.
 START WITH n : 첫 번째 Sequence 번호를 정의, 옵션이 생략되면 시퀀스는 1부터 시작한다. 
 MAXVALUE n : Sequence의 최대값을 정의. NOMAXVALUE가 default이며 최대값은 10의 27승이다. 
 MINVALUE n : 생성 가능한 Sequence의 최소값을 정의, 디폴트가 NOMINVALUE이며 최소값은 1이다. 
 CACHE n : 서버가 메모리 캐시에 미리 생성해 놓는 시퀀스 개수. 기본갓은  20이다.  캐시하지 않으려면 NOCACHE 옵션을 사용한다. 

[시퀀스를 사용할 수 없는 예] 
SQL> CREATE TABLE seq_tab ( a NUMBER DEFAULT s1.NEXTVAL); 
(* Error 발생) 
SQL> SELECT DISTINCT s1.NEXTVAL FROM dual; 
(* Error 발생) 
SQL> SELECT SUM(salary) FROM s_emp GROUP BY s1.NEXTVAL; 
(* Error 발생) 


SQL> create sequence seq_e1; 

시퀀스가 생성되었습니다. 

SQL> select seq_e1.currval from dual; 
select seq_e1.currval from dual 
      * 
1행에 오류: 
ORA-08002: 시퀀스 SEQ_E1.CURRVAL은 이 세션에서는 정의 되어 있지 않습니다 
-- 최초 한번은 NEXTVAL해야 CURRVAL 값을 조회 가능하다. 

SQL> create table test4 (n number); 

테이블이 생성되었습니다. 

SQL> insert into test4 values (seq_e1.nextval); 

1 개의 행이 만들어졌습니다. 

SQL> insert into test4 values (seq_e1.nextval); 

1 개의 행이 만들어졌습니다. 

SQL> insert into test4 values (seq_e1.nextval); 

1 개의 행이 만들어졌습니다. 


SQL> select * from test4; 

        N 
---------- 
        1 




SQL>  drop sequence seq_e1; 

시퀀스가 삭제되었습니다.

[PLSQL 반복문, LOOP, FOR, WHILE 예제]임의의 수입력받아 그수까지의 합을 구하는 예제

[PLSQL 반복문, LOOP, FOR, WHILE 예제]임의의 수입력받아 그수까지의 합을 구하는 예제 

Accept를 이용하여 숫자를 입력받고 1부터 그 수까지의 합을 구하세요 

- basic loop문 
- for loop문 
- while loop문 

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

1. BASIC LOOP 이용 


SQL>edit a 

set serveroutput on 
accept p_num prompt 'Enter a number : ' 
create or replace procedure sum1 
is 
  v_sum number := 0; 
  i number := 0; 
begin 
  
  loop 
      i := i + 1; 
      v_sum := v_sum + i;
      exit when  i >= &p_num ; 
  end loop; 
  dbms_output.put_line(&p_num || '까지 합은 ' || v_sum); 
end; 


SQL>@a 

Enter a number : 10 
구  10:      exit when  i >= &p_num ; 
신  10:      exit when  i >= 10 ; 
구  12:    dbms_output.put_line(&p_num || '까지 합은 ' || v_sum); 
신  12:    dbms_output.put_line(10 || '까지 합은 ' || v_sum); 

프로시저가 생성되었습니다. 

SQL> exec sum1; 
10까지 합은 55 

PL/SQL 처리가 정상적으로 완료되었습니다. 



2. FOR LOOP 이용 

SQL>edit a1 

set serveroutput on 
accept p_num prompt 'Enter a number : ' 
create or replace procedure sum2 
is 
  v_sum number := 0; 
begin 
  
  for i in 1..&p_num loop 
      v_sum := v_sum + i;
  end loop; 
  dbms_output.put_line(&p_num || '까지 합은 ' || v_sum); 
end; 



SQL> @a1 
Enter a number : 10 
구  6:    for i in 1..&p_num loop 
신  6:    for i in 1..10 loop 
구  9:    dbms_output.put_line(&p_num || '까지 합은 ' || v_sum); 
신  9:    dbms_output.put_line(10 || '까지 합은 ' || v_sum); 

프로시저가 생성되었습니다. 

SQL> exec sum2; 
10까지 합은 55 

PL/SQL 처리가 정상적으로 완료되었습니다. 


3. WHILE LOOP 이용 


SQL>edit a2 

set serveroutput on 
accept p_num prompt 'Enter a number : ' 
create or replace procedure sum3 
is 
  i number := 0; 
  v_sum number := 0; 
begin  
    while (i < &p_num) loop 
      i := i + 1; 
      v_sum := v_sum + i;     
  end loop; 
  dbms_output.put_line(&p_num || '까지 합은 ' || v_sum); 
end; 



SQL>@a2 

Enter a number : 10 
구  6:    while (i < &p_num) loop 
신  6:    while (i < 10) loop 
구  10:    dbms_output.put_line(&p_num || '까지 합은 ' || v_sum); 
신  10:    dbms_output.put_line(10 || '까지 합은 ' || v_sum); 

프로시저가 생성되었습니다. 

SQL> exec sum3 
10까지 합은 55 

PL/SQL 처리가 정상적으로 완료되었습니다.

[@ApectJ,spring AOP]커스텀어노테이션, @annotation스프링충고,포인트컷에 @annotation 사용하기

[@ApectJ,spring AOP]커스텀어노테이션, @annotation스프링충고,포인트컷에 @annotation 사용하기

1. 사용자정의 어노테이션을 아래처럼 간단히 만들고

package spring.edu.oraclejavacommunity;

public @interface Loggable { 
}


2. Aspect를 작성하자.

package spring.edu.oraclejavacommunity;
 
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
 
@Aspect
public class OjcAspect {

    // 사전충고
    // @Loggable 어노테이션이 붙은 메소드에 아래 충고가 적용

    @Before("@annotation(spring.edu.oraclejavacommunity.Loggable)")
    public void OjcAdvice(){
        System.out.println("충고 받으시오...");
    }
}


3. 충고를 적용할 메소드에 아래처럼 @Loggable을 써주면 된다.

public class OjcService {     
    @Loggable
    public void order() {
......
    }     
}

스프링,마이바티스연동예제(MapperScannerConfigurer, SqlSessionFactoryBean이용)

스프링,마이바티스연동예제(MapperScannerConfigurer, SqlSessionFactoryBean이용)

  [개요]
  SqlSessionTemplate을 주입받고 Mapper Interface 참조를 취득 후 
  MyBatis를 연동하기도 하지만, 이번에는 SqlSessionTemplate을 이용하지 않고
  MapperScannerConfigurer를 이용하여 Mapper Interface를 스프링에서 자동스캔하게
  하여 여러 매퍼를 이용할 수 있는 구성으로 만들어 보자. Mapper만 필요한 곳(DAO)에서
  주입받아 사용하면 된다.


0. 실습을 위한 테이블 생성 및 데이터 입력

create table myemp (
   Empno number,
   Ename varchar2(10)
)

insert into myemp Values (1, 1길동’);

COMMIT;
 
 
1. [classpath:mybatis2/mybatis2.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"
xsi:schemaLocation="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-3.2.xsd">

<bean id="dataSource"
class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@192.168.0.27:1521:onj" />
<property name="username" value="scott" />
<property name="password" value="tiger" />
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis2/config2.xml" />
<property name="mapperLocations" value="classpath:mybatis2/mappers/myemp2.xml" />
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="onj.edu.mybatis2" />
</bean>
</beans>



2. [classpath:mybatis2/config2.xml]


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 <typeAliases>
  <typeAlias
   type="onj.edu.mybatis2.MyEmp"
   alias="myemp" />
 </typeAliases>
</configuration>


3. 매퍼 XML

[classpath:mybatis2/mappers/myemp2.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 namespace="onj.edu.mybatis2.MyEmpDao">
<resultMap type="myemp" id="myemp">
<result property="empno" column="empno" />
<result property="ename" column="ename" />
</resultMap>

    <select id="getMyEmp" parameterType="int" resultMap="myemp">
select empno, ename from myemp where empno=#{empno}
</select>

<insert id="setMyEmp" parameterType="onj.edu.mybatis.model.MyEmp">
insert into myemp (empno, ename) values ( #{empno}, #{ename} )
</insert>

<update id="updateMyEmp" parameterType="onj.edu.mybatis.model.MyEmp">
update myemp
  set  ename = #{ename}
where  empno = #{empno}
</update> 
</mapper>


4. MyEmp.java

package onj.edu.mybatis2;

//myemp 테이블의 도메인 클래스
public class MyEmp { 
private int empno;
private String ename;
public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
}


5. 매퍼인터페이스, MyEmpDao.java

package onj.edu.mybatis2;

import org.springframework.stereotype.Service;

public interface MyEmpDao { 
public MyEmp getMyEmp(int empno);            //empno로 사원데이터 selcet
public int setMyEmp(MyEmp myEmp);            //insert
public int updateMyEmp(MyEmp myEmp);
}



6. MyEmpDaoImpl.java

package onj.edu.mybatis2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
 
@Repository
public class MyEmpDaoImpl implements MyEmpDao{

//Mapper Interface
@Autowired
MyEmpDao myEmpDao ;
public MyEmp getMyEmp(int empno) {
return myEmpDao.getMyEmp(empno);
}

public int setMyEmp(MyEmp myEmp) {
return myEmpDao.setMyEmp(myEmp);
}

public int updateMyEmp(MyEmp myEmp) {
return myEmpDao.updateMyEmp(myEmp);
}
}


7. MyEmpTest.java

package onj.edu.mybatis2;

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;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:mybatis2/mybatis2.xml")
public class MyEmpTest { 
@Autowired
private MyEmpDao myEmpDao;
@Test
public void test() {
MyEmp myEmp = myEmpDao.getMyEmp(1);
System.out.println(myEmp.getEmpno());   //1
System.out.println(myEmp.getEname());   //1길동
myEmp.setEmpno(myEmp.getEmpno()+1);
myEmp.setEname("3길동");
int ret = myEmpDao.setMyEmp(myEmp);   //3번데이터 Insert
System.out.println(ret);
myEmp.setEmpno(1);
myEmp.setEname("변경된이름");
int ret2 = myEmpDao.updateMyEmp(myEmp); //1번데이터 이름변경
System.out.println(ret2);
}

}