그림 첨부
ee레벨에서는 src 폴더의 다각화가 필요
설치 -> mybatis.org
A: DAOImpl에서 DB에 접근하는 Level에서 필요
B: Full Stack Level에서 필요
create table mysawon(
num number constraint mysawon_num_pk primary key,
id varchar2(20) constraint mysawon_id_nn not null,
pwd varchar2(20),
name varchar2(40),
age number(3),
hiredate date,
constraint mysawon_id_uq unique(id));
create sequence mysawon_seq
increment by 1
start with 1;
(그림에서의 w: wiring, c: component)
(Project: sp04_MyBatis)
DI 흐름에 따른 개발 순서
1. 테이블
2. vo
3. SqlMapConfig.xml
4. MyBatisTestApp101
5. UserDAO
6. MyBatisUserDAOImpl
7. MyBatisTestApp102
코드에서는 인터페이스로 소통하고
설정문서에서는 실체클래스가 노출된다.
Bean 5개 등록
5: MyBatis
6: SpringDI + MyBatis
9~13: DI
각각에 필요한 라이브러리 끌어다 쓰다보니 충돌하는 문제 발생 -> mybatis-3.2.8 필요해짐
=> 충돌문제 때문에 maven 등장
project 생성 ~ pom.xml
그림 업로드
빨간색 부분은 알아서 만들어준다
"sql의 id값이 template 기능의 이름이 된다"
=============================itemservice.xml -> businessLogicBean.xml + presentationBean.xml
presentationBean.xml: Presentation Layer에 대한 빈 설정문서
businessLogicBean.xml: Business Logic Layer + MyBatis Framework에 대한 빈 설정문서
web.xml / businessLogicBean.xml / presentationBean.xml 코드 업로드
(web.xml <- WAS)
(businessLogicBean.xml / presentationBean.xml <- DI Container)
sp09_SpringMVC_Product
INSERT 문 작성시
PK에 해당하는 컬럼값이 디비에서 자동증가하는 값일 때는 주의해야 한다.
pvo와 rvo 동기화가 되지 않으면 문제가 발생
(Sequence Number, Sysdata: DB에서 자동적으로 증가되는 값들)
1) 먼저 디비에서 PK값을 증가시킨다
2) 증가된 그 값을 pvo에 setter로 주입
결과적으로 pvo와 디비테이블(rvo)을 완벽하게 동기화시킨다.
<insert id="addProduct" parameterType="myProduct">
<selectKey keyProperty="id" order="BEFORE" resultType="int">
SELECT myproduct_seq.nextVal FROM dual
</selectKey>
INSERT
INTO myproduct(id, name, maker, price)
VALUES(#{id}, #{name}, #{maker}, #{price})
</insert>
addProduct 호출 (INSERT) -> pvo에 id 값이 담기게 된다 -> 동기화 문제 해결
정적쿼리 -> 동적쿼리
<!-- 8. Ajax Json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<beans:property name="order" value="0" />
</beans:bean>
<beans:bean name="JsonView" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
<beans:property name="contentType" value="text/html;charset=utf-8" /> </beans:bean>
Aspect Oriented Programming
<aop:config> -> Annotation
AspectJ 적용 전
- solv.xml
<!-- Target(2) member, product || Advice(1) logging -->
<bean id="member" class="spring.aop.solv.MemberService"/>
<bean id="product" class="spring.aop.solv.ProductService"/>
<bean id="logging" class="spring.aop.solv.LoggingAdvice"/>
<!-- advice의 어떤 기능이 target 메소드 호출될 때 위빙되는지 자세히 설정 -->
<aop:config>
<aop:aspect id="loggingAspect" ref="logging">
<aop:pointcut expression="execution(* spring.aop..*(..))" id="pc"/>
<aop:around method="logPush" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
AspectJ 적용
- Annotation 작성 (LoggingAdvice.java)
@Aspect
public class LoggingAdvice {
private Log log = LogFactory.getLog(getClass());
//target 메서드의 리턴타입이 String이고 spring 패키지 아래에 있는 모든 하위패키지 중에서
//클래스 이름이 Product로 시작하는 클래스, 함수명이 delete로 시작하고 인자값이 1개 이상
@Around("execution(String spring..Product*.delete*(..))")
public void logPush(ProceedingJoinPoint pjp) throws Throwable{
log.info("\ncheck...before logging...");
Object ret=pjp.proceed();//target으로 위빙되는 시점
System.out.println("target method return..."+ret);
}
}
- anno.xml
```
<!-- Target(2) member, product || Advice(1) logging -->
<bean id="member" class="spring.aop.anno.MemberService"/>
<bean id="product" class="spring.aop.anno.ProductService"/>
<bean id="logging" class="spring.aop.anno.LoggingAdvice"/>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
```