본문 바로가기
Java Web Programming/6. Spring | MyBatis

[SpringMVC/MyBatis] 마이바티스에도 Proxy(프록시)를 적용해보자!

by 파프리카_ 2020. 11. 16.
728x90
반응형

→ Spring AOP의 proxy 개념


[ MyBatis & Spring Framework 관계도 ] 

출처 : https://terasolunaorg.github.io


> SpringTemplate project를 복사해서 사용한다.

 

1. paste 후, 오른쪽 마우스 클릭 > Refactor > Rename Maven Artifact 클릭

2. Artiface Id를 프로젝트 명으로 수정

3. pom.xml에서 <artifactId>와<name>를 바꾼 프로젝트 명으로 변경

4. maven update 실행 후 동작 확인


아래의 설정 정보는 아래 포스팅을 참고하세요!

  • Maven pom 설정 - pom.xml
  • DD (Deploytment Descriptor) 설정 - web.xml

> SpringMVC 환경설정 Template

 

[SpringMVC/MyBatis] SpringMVC Template Project 환경설정

[ 환경 설정 ] 1. Spring Legacy Project 프로젝트 생성 > 'Spring MVC Project' 선택 > 프로젝트 명 작성 (작성한 프로젝트 이름이 실제 브라우저상 보이는 서버프로그램 url 이 된다 *주로 프로젝트 명을 쓴다..

creamilk88.tistory.com


Spring configure 설정 

 

 > @Mapper 어노테이션을 이용해 Proxy(대리인) 객체 (DAOImpl)를 생성하게 하는 설정 추가

<mybatis-spring:scan base-package="[mapper path]"/>

 

- Namespaces에서 'beans', 'context', 'mybatis-spring' 체크

/WEB_INF/spring-model.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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xsi:schemaLocation="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">
	
	<!-- 1. DBCP(ver.2) 설정 -->
	<bean id="dbcp" class="org.apache.commons.dbcp2.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
		<property name="username" value="scott"/>
		<property name="password" value="tiger"/>
	</bean>
	
	<!--2. SqlSessionFactory 설정 -->
	<!-- @Mapper 어노테이션을 이용해 Proxy(대리인) 객체 (DAOImpl)를 생성하게 하는 설정 -->
	<mybatis-spring:scan base-package="org.kosta.myproject.model.mapper"/>
	<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- DBCP(datebase connection pool) 주입 -->
		<property name="dataSource" ref="dbcp"/>
		
		<!-- Mapper 어노테이션을 적용하여, 자동으로 DAO 구현체를 생성할 때는
			 아래 설정은 필요없다. 
		<property name="mapperLocations" value="classpath:/mybatis/config/*.xml"/>-->
		
		<!-- Package에 별칭주기 : vo까지 잡아주어 상세히 한다.-->
		<property name="typeAliasesPackage" value="org.kosta.myproject.model.vo"/>
		<!-- underScore 표기법을 Camel 표기법으로 mapping(변환)해주는 설정 -->
		<property name="configuration">
			<bean class="org.apache.ibatis.session.Configuration">
				<property name="mapUnderscoreToCamelCase" value="true"></property>
			</bean>
		</property>
	</bean>
 
	<!--3. SqlSessionTemplate설정 : 트랜잭션 제어를 지원-->
	<bean id="SqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg ref="sqlSessionFactoryBean"/>
	</bean>
	
	<!--4. IOC 설정 : <context:component-scan> :  IOC, DI, DL에 대한 설정-->
	<context:component-scan base-package="org.kosta"></context:component-scan>

</beans>

 

/WEB_INF/spring-web.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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!--5. SpringMVC 설정-->
	<mvc:annotation-driven/>

	<!--6. ViewResolver 설정 : client에게 응답하는 view에 대한 설정 -->
	<bean id="ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
</beans>

/src/main/webapp/WEB-INF/views

 

View

 

/home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Project HOME</title>
</head>
<body>
	<h4>MyBatis Proxy 연습</h4>
	총 회원 수 : ${memberCount} <br>
	총 상품 수 : ${productCount} <br>
</body>
</html>

 

★ MyBatis Proxy 설정 !

1. ProductMapper.xml의 namespace의 경로는 ProductMapper.java<<interface>>의 package.class명이 동일해야 한다.

2.  ProductMapper.java<<interface>>의 메서드명은 ProductMapper.xml의 id와 동일해야 한다.

 

/src/main/resource/org.kosta.myproject.model.mapper

 

/ProductMapper.xml

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

	<!-- 1. 상품 목록 -->
 	<select id="findProductList" resultType="productVO">
 		SELECT product_no, name, maker, price
 		FROM   m_product
 	</select>
 	
 	<!-- 2. 상품 수  -->
 	<select id="getTotalProuctCount" resultType="int">
 		SELECT COUNT(*)
 		FROM   m_product
 	</select>
</mapper>

 

/MemberMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Sql Mapper -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.kosta.myproject.model.mapper.MemberMapper">
 	
 	<select id="getMemberTotalCount" resultType="int">
 		SELECT COUNT(*)
 		FROM   spring_member
 	</select>
 	
 	<select id="findMemberById" resultType="memberVO">
 		SELECT id, password, name, address
 		FROM   spring_member
 		WHERE  id = #{value}
 	</select>
</mapper>

src/main/java/org.kosta.myproject.model.mapper

 

- 어노테이션 @Mapper를 명시하면,

스프링 컨테이너에 의해 Proxy구현체 (DAOImpl의 역할)가 생성된다.

 

 

/ProductMapper.java<<interface>>

package org.kosta.myproject.model.mapper;

import java.util.List;

import org.kosta.myproject.model.vo.ProductVO;

public interface ProductMapper {

	// 1. 상품 목록
	public List<ProductVO> findProductList();

	// 2. 상품 수
	public int getTotalProuctCount();
	
}

 

/MemberMapper.java<<interface>>

package org.kosta.myproject.model.mapper;

import org.apache.ibatis.annotations.Mapper;
/*
 * 어노테이션 @Mapper를 명시하면,
 * 스프링 컨테이너에 의해 Proxy구현체 (DAOImpl의 역할)가 생성된다.
 */
import org.kosta.myproject.model.vo.MemberVO;
@Mapper
public interface MemberMapper {
	public int getMemberTotalCount();
	
	public MemberVO findMemberById(String id);
}

SQL

 

1. m_product 테이블 생성 및 값 insert

create table m_product(
	product_no number primary key,
	name varchar2(100) not null,
	maker varchar2(100) not null,
	price number not null
)
create sequence m_product_seq;

insert into m_product values(m_product_seq.nextval,'아이폰8','애플',100);
insert into m_product values(m_product_seq.nextval,'갤럭시7','삼성',120);
insert into m_product values(m_product_seq.nextval,'갤럭시2','삼성',20);

 

2. m_product 테이블


Model

 

/src/main/java/org.kosta.myproject.model.vo

 

/ProductVO.java

package org.kosta.myproject.model.vo;

public class ProductVO {
	private String productNo; //column name은 product_no
	private String name;
	private String maker;
	private int price;
	public ProductVO() {
		super();
	}
	public ProductVO(String productNo, String name, String maker, int price) {
		super();
		this.productNo = productNo;
		this.name = name;
		this.maker = maker;
		this.price = price;
	}
	public String getProductNo() {
		return productNo;
	}
	public void setProductNo(String productNo) {
		this.productNo = productNo;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getMaker() {
		return maker;
	}
	public void setMaker(String maker) {
		this.maker = maker;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "ProductVO [productNo=" + productNo + ", name=" + name + ", maker=" + maker + ", price=" + price + "]";
	}
}

 

/MemberVO.java

package org.kosta.myproject.model.vo;

public class MemberVO {
	private String id;
	private String password;
	private String name;
	private String address;
	public MemberVO() {
		super();
	}
	public MemberVO(String id, String password, String name, String address) {
		super();
		this.id = id;
		this.password = password;
		this.name = name;
		this.address = address;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "MemberVO [id=" + id + ", password=" + password + ", name=" + name + ", address=" + address + "]";
	}
	
}

Controller

 

/src/main/java/org.kosta.myproject.controller

 

/HomeController.java

package org.kosta.myproject.controller;

import javax.annotation.Resource;

import org.kosta.myproject.model.mapper.MemberMapper;
import org.kosta.myproject.model.mapper.ProductMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {

	@Resource
	private MemberMapper memberMapper;
	@Resource
	private ProductMapper productMapper;
	
	@RequestMapping("home.do")
	public String home(Model model) {
		//모델과 연동하여, 연동 정보 공유
		model.addAttribute("memberCount", memberMapper.getMemberTotalCount());
		model.addAttribute("productCount", productMapper.getTotalProuctCount());
		//viewResolver에 의해 WEB-INF/views/home.jsp가 실행
		return "home"; 
	}
	
}

Test - 단위 테스트

 

/src/test/java/org.kosta.myproject

 

/TestProductUnit.java

package org.kosta.myproject;

import java.util.List;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.kosta.myproject.model.mapper.MemberMapper;
import org.kosta.myproject.model.mapper.ProductMapper;
import org.kosta.myproject.model.vo.ProductVO;
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-model.xml"})
public class TestProductUnit {
	
	@Resource
	private ProductMapper pm;
	
	@Test
	public void productUnitTest() {
		
		// 1. 상품 목록
		List<ProductVO> list = pm.findProductList();
		for (ProductVO vo:list) {
			System.out.println(vo);
		}
		/* 출력값:
		 	ProductVO [productNo=1, name=아이폰8, maker=애플, price=100]
		 	ProductVO [productNo=2, name=갤럭시7, maker=삼성, price=120]
		 	ProductVO [productNo=3, name=갤럭시2, maker=삼성, price=20]
		 */
		
		
		// 2. 상품 수
		int totalCount = pm.getTotalProuctCount();
		System.out.println("총 상품 수 : " + totalCount);
		/*  출력값 :
		    총 상품 수 : 3
		 */
	}
	
}

[ Template 결과 화면 ] 

 

1. home.jsp 화면

728x90
반응형