매일 조금씩

01/20 ! - MyBatis(1) : MyBatis 설정파일(mapper)을 xml로 자바,웹 프로젝트 구현 본문

빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정

01/20 ! - MyBatis(1) : MyBatis 설정파일(mapper)을 xml로 자바,웹 프로젝트 구현

mezo 2021. 2. 25. 19:56
728x90
반응형

java / JSP framework

myBatis(iBatis)

            http://blog.mybatis.org  

            ▶ 설정 파일

               * XML 파일 - 많이 사용됨

               1. 데이터베이스 설정

               2. SQL Mapper

                               * 로그 출력에 필요한 프레임워크(에러, 진행과정 확인용) - log4j

                                               log4j용 설정파일

                                               logging.apache.org/log4j/2.x    → log4j를 내가 설정할 수 있는데 그 설정에 대해 나옴

               + 라이브러리

spring

 

 

 

 

myBatis


마이바티스는 무엇인가?

마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크이다. 마이바티스는 JDBC로 처리하는 상당부분의 코드와 파라미터 설정및 결과 매핑을 대신해준다. 마이바티스는 데이터베이스 레코드에 원시타입과 Map 인터페이스 그리고 자바 POJO 를 설정해서 매핑하기 위해 XML애노테이션을 사용할 수 있다.

 

원랜 SQL문이 JAVA안에 있어서 SQL을 수정하려면 java소스에서 String으로 된 SQL문을 수정하고 컴파일 후 사용할 수 있는데, 마이바티스는 이 SQL을 분리해서 외부파일로 저장해 두고 특별한 이름으로 가져다 쓰는 것이다. 매핑 시켜놓은 것이다.  XML, 또는 JAVA파일 형식이다.

 

 

※ 자바 프로젝트 환경설정

1) 프로젝트 만들기

이클립스에서 jsp-workspace로 바꾼다. 다 똑같은데 그냥 구분지으려고 바꾸는 것이다.

New > Other.. > java project 로 프로젝트 만든다.

 

2) 라이브러리 추가

 http://blog.mybatis.org 에 접속한다.

위의 MyBatis 3 의 download를 클릭한다.

 

 

압축파일을 다운받는다.

 

 

파일 압축을 풀면 많은 jar파일이 나온다. 

C:\Java\APIs   여기에 모든 jar파일을 넣는다. (APIs - 프로젝트에서 라이브러리 추가 쉽게하려고 api 모아둔 폴더)

 

다음으로 라이브러리를 다음과 같은 과정으로 프로젝트에 추가한다.

프로젝트 우클릭 > Build Path

xml쓰는거 빼고 거의다 추가한다.

 

 

3) 설정 파일 가져오기

ftp로 xml 파일 3개를 받았다.

  • log4j.xml : 출력 설정
  • myBatisConfig.xml : 데이터베이스 연결 설정
  • mapper.xml : 

log4j.xml만 빼고 나머지 2갠 이름 바꿔도 된다.

 

 

1. myBatis  구현 - xml

1-1. 파일 가져오기

먼저 다음과 같이 log4j.xml과 myBatisConfig.xml를 작성한 다음

실행 파일인 myBatisEx01.java를 만들어서 실행시키면 파일이 제대로 가져와 지는지 확인이 가능하다.

 

> log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
     <appender name="console" class="org.apache.log4j.ConsoleAppender">
          <!-- 출력형태 -->
          <layout class="org.apache.log4j.PatternLayout">
               <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%-5p](%-35c{1}:%-3L) %m%n" />
          </layout>
     </appender>
     <root>
     	<!-- 출력시점 -->
     	<level value="DEBUG" />
     	<!-- 출력방법 -->
     	<appender-ref ref="console" />
     </root>
</log4j:configuration>

> myBatisConfig.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>
	<environments default="mariadb">
		<!-- environment는 여러개가 될수 있고 id값이 default에 들어간다. -->
		<environment id="mariadb">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="org.mariadb.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3307/sample" />
				<property name="username" value="root" />
				<property name="password" value="!123456" />
			</dataSource>
		</environment>
	</environments>
</configuration>

이때 <environment>는 여러개가 있을 수 있고  id 값이 <environments>의 default에 들어간다.  

 

 

> MyBatisEx01.java - InputStream


import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class myBatisEx01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String resource = "myBatisConfig.xml";
		
		// 파일 읽어 오기
		InputStream is = null;
		
		try {
			is = Resources.getResourceAsStream( resource );
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
			System.out.println("호출 성공");
			
		} catch (IOException e) {
			System.out.println("에러" + e.getMessage());
		} finally {
			if(is != null) try { is.close(); } catch(IOException e) {}
		}
	}

}

 

> MyBatisEx02.java - Reader


import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class myBatisEx02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String resource = "myBatisConfig.xml";
		
		Reader reader = null;
		
		try {
			reader = Resources.getResourceAsReader( resource );
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
			System.out.println("호출 성공");
		} catch (IOException e) {
			System.out.println("에러" + e.getMessage());
		} finally {
			if(reader != null) try { reader.close(); } catch(IOException e) {}
		}
	}

}

위의 사진처럼 나오면 정상적으로 실행되는 것이다.

 

 

1-2. 데이터베이스 연결

이제 데이터 베이스와 연결을 해보자

가장먼저 mapper.xml에 sql문을 작성한다.

> mapper.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="mybatis">
	<select id="select1">
		select deptno, dname, loc
		from dept
		where deptno=10;
	</select>
</mapper>

 

그다음 실행파일에 데이터베이스 연결하는 코드를 추가 작성한다.

SqlSession sqlSession = null;

sqlSession = sqlSessionFactory.openSession();
System.out.println("연결 성공");

finally에서 닫아줘야한다.

if(sqlSession != null) sqlSession.close();

 

 

1-3. 파일 가져와서 데이터베이스 연결 후 결과 가져오기

가장먼저 DeptTO.java를 만든다.

 

그 다음 sql 결과로 데이터는 하나만 가져올 수 있으며 to로 가져와야하므로 

<select> 에 resultType을 추가한다. 

sql문의 where절을 parameter값으로 전달할 경우엔

<select>에 parameterType를 추가한다.

<?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="mybatis">
	<select id="select1" resultType="DeptTO">
		select deptno, dname, loc
		from dept
		where deptno=10;
	</select>
	<!-- 한개의 데이터만 가져올수 있다. -->
	<!-- 그냥은 못가져오고 to로 가져와야함 -->
	<!-- 자동적으로 sql결과를 resultType으로 set한다. 그래서 setter가 호출된다. -->


	<!-- where'절'이 있는 경우 -->
	<!-- parameterType을 사용 -->
	<select id="select2" parameterType="String" resultType="DeptTO">
		select deptno, dname, loc
		from dept
		where deptno=#{deptno};
	</select>

</mapper>

 

 

//원래
//DeptTO to = (DeptTO)sqlSession.selectOne("select1");

//where절에 parameter로 값을 전달 할 경우
DeptTO to = (DeptTO)sqlSession.selectOne("select2", "10");

 

그리고 다시 실행파일에 sql 실행 결과 to값을 가져오는  아래 코드를 추가한다.

//DeptTO to = (DeptTO)sqlSession.selectOne("select1");

//where절에 parameter로 값을 전달 할 경우
DeptTO to = (DeptTO)sqlSession.selectOne("select2", "10");

System.out.println(to.getDeptno());
System.out.println(to.getDname());
System.out.println(to.getLoc());

 

그리고 이 mapping.xml 파일에 작성된 sql문을 데이터베이스 연결 후 가져다 쓰려면 mapping.xml파일이 어디있는지 알아야한다. 그러기 위해선 데이터베이스 연결 설정 파일인 myBatisConfig.xml에 <mappers> 를 추가해서 mapper.xml 파일을 명시해줘야한다.

<mappers>
    <mapper resource="mapper.xml" />
</mappers>

 

실행시키면 아래와 같은 출력결과가 나온다.

select1을 실행시키면 select1이 실행되고, select2를 실행시키면 select2가 실행되는 것을 확인 가능하다.

 

 

 

>> 전체 코드

> log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
     <appender name="console" class="org.apache.log4j.ConsoleAppender">
          <!-- 출력형태 -->
          <layout class="org.apache.log4j.PatternLayout">
               <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%-5p](%-35c{1}:%-3L) %m%n" />
          </layout>
     </appender>
     <root>
     	<!-- 출력시점 -->
     	<level value="DEBUG" />
     	<!-- 출력방법 -->
     	<appender-ref ref="console" />
     </root>
</log4j:configuration>

 

> myBatisConfig.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>
	<environments default="mariadb">
		<!-- environment는 여러개가 될수 있고 id값이 default에 들어간다. -->
		<environment id="mariadb">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="org.mariadb.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3307/sample" />
				<property name="username" value="root" />
				<property name="password" value="!123456" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="mapper.xml" />
	</mappers>
</configuration>

 

> mapper.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="mybatis">
	<select id="select1" resultType="DeptTO">
		select deptno, dname, loc
		from dept
		where deptno=10;
	</select>
	<!-- 한개의 데이터만 가져올수 있다. -->
	<!-- 그냥은 못가져오고 to로 가져와야함 -->
	<!-- 자동적으로 sql결과를 resultType으로 set한다. 그래서 setter가 호출된다. -->


	<!-- where'절'이 있는 경우 -->
	<!-- parameterType을 사용 -->
	<select id="select2" parameterType="String" resultType="DeptTO">
		select deptno, dname, loc
		from dept
		where deptno=#{deptno};
	</select>

</mapper>

 

> MyBatisEx03.java

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class myBatisEx03 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String resource = "myBatisConfig.xml";
		
		// 파일 읽어 오기
		InputStream is = null;
		// 데이터베이스 연결
		SqlSession sqlSession = null;
		
		
		try {
			is = Resources.getResourceAsStream( resource );
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
			System.out.println("호출 성공");
			
			sqlSession = sqlSessionFactory.openSession();
			System.out.println("연결 성공");
			
			//DeptTO to = (DeptTO)sqlSession.selectOne("select1");
			DeptTO to = (DeptTO)sqlSession.selectOne("select2", "10");
			
			System.out.println(to.getDeptno());
			System.out.println(to.getDname());
			System.out.println(to.getLoc());
		} catch (IOException e) {
			System.out.println("에러" + e.getMessage());
		} finally {
			if(sqlSession != null) sqlSession.close();
			if(is != null) try { is.close(); } catch(IOException e) {}
		}
	}

}

 

 

1-4. SELECT문 구현

실습1) sql 문에 여러개 값을 넣어야하는 경우

mybatis 밑에 select3 이 있다는 뜻이므로 mybatis.select3 이런식으로 부를수도 있다.

> mapper.xml

<mapper namespace="mybatis">
  <!-- 여러개 값을 들고 들어갈 경우 -->
  <!-- to로 들고 들어감 -->
  <select id="select3" parameterType="DeptTO" resultType="DeptTO">
      select deptno, dname, loc
      from dept
      where deptno=#{deptno} and dname=#{dname};
  </select>
</mapper>

 

> MyBatisEx03.java

// 여러개 값을 sql에 넣어야 할경우
DeptTO pto = new DeptTO();
pto.setDeptno("10");
pto.setDname("ACCOUNTING");

DeptTO to = (DeptTO)sqlSession.selectOne("mybatis.select3", pto);

System.out.println(to.getDeptno());
System.out.println(to.getDname());
System.out.println(to.getLoc());

데이터 가져오는 부분 수정

 

 

실습2) to가 아닌 HashMap으로 가져올 경우

> mapper.xml

<!-- HashMap으로 가져가고 싶을 때 -->
<select id="select4" parameterType="DeptTO" resultType="java.util.HashMap">
    select deptno, dname, loc
    from dept
    where deptno=#{deptno} and dname=#{dname};
</select>

이렇게 resultType을 달리해야한다.

 

> MyBatisEx04.java

Map map = sqlSession.selectOne("select4");

System.out.println(map.size());
Set<String> keys = map.keySet();

for(String key : keys) {
    System.out.println(key + " : " + map.get(key));
}

데이터 가져오는 부분을 이렇게 작성한다.

 

 

실습3) 여러개의 데이터를 한꺼번에 가져오고 싶은경우

원래는 selectOne()사용해서 하나만 가져올수 있었다.

mapper.xml을 하나더 만든다. 

가져다 쓰는 mapper 파일이 바뀌면 myBatisConfig.xml에서 mapper파일 이름을 바뀐 파일 이름으로 변경해줘야한다.

> mapper2.xml

<!-- 알아서 to 안에 list형태로 담김 -->
<select id="selectList1" resultType="DeptTO">
    select deptno, dname, loc
    from dept;
</select>

데이터 하나를 가져올때와 mapper파일에선 변함이 없다. 

자기가 알아서 DeptTO 형태에 list로 담아서 가져오기 때문이다.

 

> MyBatisEx05.java

//List<DeptTO> lists = sqlSession.selectList("selectList1");
ArrayList<DeptTO> lists = (ArrayList)sqlSession.selectList("selectList1");
System.out.println(lists.size());

for(DeptTO to: lists) {
    System.out.println(to.getDeptno());
    System.out.println(to.getDname());
    System.out.println(to.getLoc());
}

java파일에서 selectOne이 아닌 selectList로 데이터를 가져온다.

 

 

 

응용실습) deptno 값 전달해서 emp테이블의 사원정보 가져오기

> EmpTO.java

> mapper2.xml

> MyBatisEx06.java

 

 

 

실습4) like 검색 (유사검색) 

> MyBatisEx07.java

1) 호출 문에 % 넣기

2) sql 문에 % 넣기 

 

 

응용실습) 동이름으로 주소 검색하는 우편번호 검색기 

> ZipcodeMyBatisEx01

> log4j.xml

> mapper.xml

> myBatisConfig.xml

> ZipcodeTO.java

> ZipcodeEx01.java

 

 

 

 

실습5)  join으로 여러개 데이터 가져오기 - HashMap

> MyBatisEx08.java

1) between 사용

 

2) 부등호 사용

'<' 이게 html태그의 '<'와 충돌한다.

  • < : &lt;
  • > : &gt;

 

 

실습6) mapper 여러개를 조합해서 사용하기

> myBatisEx02

> mapper1.xml

> mapper2.xml

> MyBatisEx01.java

 

mapper파일 각각의<mapper namespace="">는 다르게 <select>의 id는 같게 넣어준다.

<?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="mybatis1">
	<select id="select1" resultType="DeptTO">
		select deptno, dname, loc
		from deptno=10;
	</select>
</mapper>
<?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="mybatis2">
	<select id="select1" resultType="DeptTO">
		select deptno, dname, loc
		from deptno=20;
	</select>
</mapper>

 

myBatisConfig.xml 에서 mappers에 mapper를 두개 적어준다.

<mappers>
    <mapper resource="mapper1.xml" />
    <mapper resource="mapper2.xml" />
</mappers>

 

java파일에서 다음과 같이 "mapper namespace.select id" 를 하면 된다. 

그냥 "select1"을 하면 select1이 mapper1.xml에도 하나 mapper2.xml에도 하나 이렇게 두개여서 모호하다고 에러가 난다.

// DeptTO to = (DeptTO)sqlSession.selectOne("select1"); // 모호하다고 에러남
DeptTO to = (DeptTO)sqlSession.selectOne("mybatis1.select1");
System.out.println(to.getDeptno());
System.out.println(to.getDname());
System.out.println(to.getLoc());

 

 

실습7) mapper에서 sql 반복되는 부분을 선언해서 쓰기

미리 선언하고 include로 참조해서 쓴다.

> mapper1.xml 수정

 

 

 

 

 

mapper의 sql문을 jstl처럼 if, forEach 같은걸로 조작이 가능하다. 

 

 

 

1-5. DML문 구현

> myBatisEx03

실습1) insert문

> MyBatisEx01.java

 

실습2) delete문

> MyBatisEx02.java

 

실습3) update문

> MyBatisEx03.java

 

 

 

 

 

1-6. DDL문 구현

> myBatisEx04

실습1) create문

> MyaBatisEx01.java

1) sql 문을 parameter로 전달

update 태그를 사용하며 update한 return 값이 다른 것들과 다르게 0이여야 성공이다.

표현언어를 사용해서 SQL문에 넣을 수도 있다. 

> mapper.xml

<update id="createTable1" parameterType="String">
    ${value}
</update>

 

이렇게 update를 사용하며 표현언어 ${value}를 쓴다.

 

> MyBatisEx01.java

String sql = "create table tb1 (col1 varchar(10))";
int result = sqlSession.update("createTable1", sql);
if(result == 0) {
    System.out.println("성공");
}else {
    System.out.println("실패");
}

create문을 parameter로 sql문에 전달하고 그 결과 가 0이여야 성공이다.

 

같은 표현언어여도 #{}는 ""가 붙고 ${}는 ""가 안붙는다.

그래서 String인 것을 표현할 땐 #{}를 쓰고 아닐 땐 ${}를 쓰는게 편하다.

 

2) 특정값만 parameter로 전달

 

 

실습2) drop문

> MyBatisEx02.java

 

 

 

 

 

 

 

 

2. Web Project 에서 myBatis 사용하기 - xml 방식

Java Project에서 myBatis를 구현한 것을 JSP에 옮기는 작업을 해야한다.

 

※ 웹 프로젝트 환경설정

Dynamic Web Project 만들어서 

모든 라이브러리를 'WebContent > WEB-INF > lib' 에 전부 추가한다.

(자바 프로젝트처럼 프로젝트 우클릭해서 Build Path로 넣는거 아님!!!!)

 

 

 

그리고 log4j.xml과 myBatisConfig.xml 파일을 와서 'Java Resources >  src' 에 넣는다.

 

 

그리고 WebContent에 jsp 파일(ex01.jsp)을 하나 만들어서 연결을 확인한다.

브라우저에 아무것도 안떠야 정상이다.

 

 'Java Resources >  src' 에 'model1'이라는 패키지를 만들고

그안에 mapper.xml과 DeptTO.java를 만든다. mapper.xml은 웬만 하면 to와 같은 이름으로 해주는 것이 좋기때문에 

파일명을 dept.xml로 수정하였다.

 

 

 

2-1. 구현

ex02.jsp를 다음과 같이 코딩한다. 

<%@page import="com.sun.org.apache.xml.internal.utils.SystemIDResolver"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import="java.io.IOException" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="org.apache.ibatis.io.Resources" %>
<%@ page import="org.apache.ibatis.session.SqlSession" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %>

<%@ page import="model1.DeptTO" %>



<%
	String resource = "myBatisConfig.xml";

	InputStream is = null;
	SqlSession sqlSession = null;
	
	try{
		is = Resources.getResourceAsStream( resource );
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
		System.out.println("설정 성공");
		
		sqlSession = sqlSessionFactory.openSession(true);
		
		DeptTO to = (DeptTO)sqlSession.selectOne("select1");
		
		System.out.println(to.getDeptno());
		System.out.println(to.getDname());
		
	}catch(IOException e){
		System.out.println("[에러]" + e.getMessage());
	}finally{
		if(is != null) is.close();
	}
%>

model1의 DeptTO를 import해줘야한다.

그리고 myBatisConfig.xml에서 아래의 mapper를 추가한다.

<mappers>
    <mapper resource="model1/dept.xml" />
</mappers>

 

 

2-2. 커넥션 풀 사용

context.xml 파일 만들기

context.xml를 부르는건 myBatisConfig.xml 이므로 

myBatisConfig.xml에 다음과 같이 environment를 추가한다.

<environment id="mariadb2">
    <transactionManager type="JDBC" />
    <dataSource type="JNDI">
        <property name="data_source" value="java:comp/env/jdbc/mariadb1" />
    </dataSource>
</environment>

그리고 다음과 같이 environments의 default를 커넥션 풀의 id로 해주면 된다.

jsp 파일은 변화가 없다.

 

 

 

 

응용 실습) 웹을 동이름 검색으로 주소 출력하는 우편번호 검색기  만들기

1) JSP

> zipcodeJSP.jsp

 

2) model1

> zipcodeModel1.jsp

> model1

 

3) model2

> views

> zipcodeModel2.jsp

> zipcodeModel2_ok.jsp

> model2

728x90
반응형