초급의 끄적거림

[Framework] myBatis 본문

Framework/myBatis

[Framework] myBatis

codingD 2019. 10. 14. 11:11

1. Java Framework (구조화)


- Spring Framework

- Struts Framework

- myBatis Framework : 데이터베이스 관련

* 무작정 Framework를 사용해서 만드는 것이 답은 아님

* 개발하는 방식은 편할 수 있지만 구조화 되는데 필요한 라이브러리를 다 가지고 다녀야 한다는 단점

* 환경설정이 복잡함 (외부에 있는 것을 불러다 쓰기 때문에 어쩔 수 없는 부분)

 

 

2. 자바기반 프로젝트 개발방식


 - Model1 방식

 - MVC패턴 (Model2) 방식

  → MyController

  → Spring Framework (졸업작품 방식)

  → MyController + myBatis Framework

  → Spring Framework + myBatis Framework

 

 

3. myBatis


 - SQL과 비즈니스 로직 (자바)이 분리되어 있어 개발 및 배포, 관리가 뛰어남.

 - 자바 개발시 SQL이 DAO class에 포함되어 있으며 SQL을 추철하여 테스트가 어렵고 SQL이 변경되는 경우 관련 자바 코드를 변경해야한다는 단점

 - 자바와 DBMS의 연결을 XML을 이용하여 분리하기 때문에 독립적인 팀 개발이 가능하며 개발 시간을 단축할 수 있음

 - 일반 SQL뿐만 아니라 저장 프로시저까지 처리가능

 - 파라미터를 이용하여 동적으로 실행 할 SQL을 지정할 수 있음

 - 적재지연, JOIN, 실시간 코드 생성, 상속과 같은 기능 지원

 

 3-1) 전자정부 표준프레임워크

   - 우리나라 전자정부 기반이 myBatis Framework 이기 때문에 알아둬야 함

   - sql.append에 들어가는 sql문을 .xml에서 만드는 것 → 이것을 지원해주는 Framework가 myBatis 임

   - https://www.egovframe.go.kr/

실행환경에서 확인 가능, 특히 Mapper XML Files와 Dynamic SQL 중요

 

 

4. Spring Tool Suite 3 다운로드


http://spring.io 

 

spring.io

Let's build a better Enterprise. Spring helps development teams everywhere build simple, portable, fast and flexible JVM-based systems and applications.

spring.io

 

 4-1) TOOLS - Spring Tool Suit 3 page 클릭

 

 4-2) 원하는 버전을 찾기 위해 'See all versions'

 

 4-3) 원하는 버전을 찾았다면 본인 PC운영체제 에 맞게 다운로드

 

 4-4) 작업 공간에 새 폴더 'wsp' 와 다운로드 받은 STS 3.9.10.Release 압축해제 후 구별 쉽게 'sts-3' 이름 변경

       spring 4 이상에서는 플러그인 설치가 필요

 

 4-5) 'sts-3' → 실행파일 'STS.exe' → 4-4 에서 생성한 새폴더 'wsp' 를 작업공간으로 설정

 

 4-6) Java EE 로 변경 후, Dynamic Web Projet 로 'mybatisTest' 생성 (web.xml 생성)

 

 

5. myBatis 라이브러리 설정 


 5-1) UTF-8 설정 & 톰캣서버 연결

 5-2) 오라클 설치 경로 C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib\ojdbc.jar 파일 'lib' 복사 붙여넣기

 5-3) mybatis 다운로드 → Product → download → 원하는 버전 다운로드

https://blog.mybatis.org/

 

The MyBatis Blog

A blog about the the MyBatis data mapper framework.

blog.mybatis.org

 

 

5-4) 다운받은 압축파일을 해제하고 .jar 파일을 lib 폴더에 복사 붙여넣기

 

 

6. myBatis 환경설정


 6-1) Java Resources\src\config (새 폴더 생성)

    : DBOpen을 대체할 xml을 만들 곳

 

 6-2) Java Resources\src\config\jdbc.xml (Design 모드 말고 Source 모드로 보기)

 6-3) mybatis의 압축을 풀면서 같이 나온 'mybatis-3.5.2.pdf'의 p.3의 기본적인 DOCTYPE 복사 붙여넣기 

       (이후 Ctrl+Shift+f 로 자동 정렬) → 앞으로 이것을 수정해가면서 사용할 것

<?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="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" 	value="${driver}"/>
<property name="url" 		value="${url}"/>
<property name="username" 	value="${username}"/>
<property name="password" 	value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>

 

  +) 기존에 oracle DB를 연결 했던 'myweb'의 DBOpen.java에서 복사하여 붙여넣기

본인 것에 맞춰서 수정해야 하는 부분
본인의 db정보에 맞춰서 수정한 모습

 

 6-4) config\mem.xml 생성

  - config\mem.xml   : 맞는 경로에 mem.xml 파일 생성

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

 

  - mapper 는 카테고리에 따라 여러 개가 올 수 있음

  - mappers에 SQL문을 작성해놓은 XML문서의 주소를 적음

 

  - 아래와 같이 기본 구조 생성 ('mybatis-3.5.2.pdf' p.21 을 복사하여 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">

<!-- mem.xml 실행한 SQL문을 정의해 놓은 파일  -->
<mapper namespace="">
	
</mapper>

 

 

7. 클래스 만들기


 7-1) net.mem\MemMainTest.java

package net.mem;

import java.io.InputStream;
import java.sql.PreparedStatement;
import java.util.List;

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 MemMainTest{
	public static void main(String[] args){
    	try{
            //1) DB 환경 설정 관련 파일 가져오기
            String resource="config/jdbc.xml";
            InputStream is=Resources.getResourceAsStream(resource);
            //2) DB 연결하기 위한 팩토리빈 생성
            //팩토리 : 공장에서 쓸 수 있게 완전체로 만들어서 내보내는 것, 사용자는 반환받은 값만을 이용해서 만들면 됨
            //→ 기존의 DBOpen + MemberDAO
            SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);  //파일에 해당하는 is
			System.out.println("DB연결 성공");
            
            //3) 쿼리문 생성
            
            //4) 쿼리문 실행
        }catch{
        	System.out.println("실패 : "+e);
        }//try end
    }//main() end
}//class end

 

8. mem 생성


 8-1) mem.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">

<!-- namespace를 필수로 설정해야 함 -->
<mapper namespace="">

</mapper>

 

 8-2) mem.txt 생성 (sql문을 작성할 것인데 DB연결이 안 되어 있어서 일단 txt 로 생성)

테이블과 시퀀스 생성 후, commit

 

 8-3) MemDTO 생성

  - 테스트를 위해 매개변수가 다른 각각의 생성자 함수 추가

package net.mem;

public class MemDTO {
	private int num; 
	private String name;
	private int age;
	
	//기본 생성자
	public MemDTO() {}
	
	//매개변수가 다른 각각의 생성자 함수 추가 (추가하는 이유는 없고 테스트 위함)
	//1) num
	public MemDTO(int num) {
		this.num=num;
	}
	
	//2) num, age
	public MemDTO(int num, int age) {
		this.num=num;
		this.age=age;
	}

	//3) name, age
	public MemDTO(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	//4) num, name, age
		public MemDTO(int num, String name, int age) {
			this.num=num;
			this.name=name;
			this.age=age;
		}
	
	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}


}//class end

 

9. MemMainTest.java


package net.mem;

import java.io.InputStream;
import java.sql.PreparedStatement;
import java.util.List;

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 MemMainTest {

	public static void main(String[] args) {
		// MyBatis-3 기반 JDBC 연습
		try { //1~3번은 구조, 4번을 확실히 알기
			//1) DB 환경 설정 관련 파일 가져오기
			String resource="config/jdbc.xml";
			InputStream is=Resources.getResourceAsStream(resource);
			
			//2) DB 연결하기 위한 팩토리빈 생성
			//팩토리 : 공장에서 쓸 수 있게 완전체로 만들어서 내보내는 것, 사용자는 반환받은 값만을 이용해서 만들면 됨
			//→ 기존의 DBOpen + MemberDAO
			SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);  //파일에 해당하는 is
			System.out.println("DB연결 성공");
			
			//3) 쿼리문 생성
			//PreparedStatement와 비슷한 기능을 함
			SqlSession sql=ssf.openSession(true); 
			
			//4) 쿼리문 실행
			//가) 행추가
			int cnt=sql.insert("mem.insertRow",new MemDTO("이지은", 27)); //mem.insertRow의 mem 은 namespace에서 가져온 것
			System.out.println("행추가 결과 : "+cnt);
			
			//다) 행수정 (목록 전에 수정을 만들 것)
			int cnt=sql.update("mem.updateRow", new MemDTO(2, "fullmoon", 30));
			System.out.println("행 수정 결과 : "+cnt);
						
			//라) 행삭제 (num=3을 기준으로 그 이하는 다 삭제할 것)
			int cnt=sql.delete("mem.deleteRow", 2);
			System.out.println("행 삭제 결과 : "+cnt);
			
			//나) 전체 목록
			List<MemDTO> list=sql.selectList("mem.selectAll");
			
			//마) 검색 (이름에 "은" 자가 들어간 행 검색)
			List<MemDTO> list=sql.selectList("mem.search", "은");
			for(int idx=0; idx<list.size(); idx++) {
				MemDTO dto=list.get(idx);
				System.out.print(dto.getNum() + " ");
				System.out.print(dto.getName() + " ");
				System.out.print(dto.getAge() + " ");
				System.out.println();
			}//for end
			
		}catch(Exception e) {
			System.out.println("실패 : "+e);
		}//try end		

	}//main() end
}//class end

 

 9-1) mem.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">

<!-- mem.xml 실행한 SQL문을 정의해 놓은 파일 -->

<!-- namespace를 필수로 설정해야 함 -->
<mapper namespace="mem">
	<!-- 이렇게 작성된 것들을 mapper (맵퍼) 라고 함  -->
	<!-- 
		- 데이터베이스 결과 데이터를 객체에 매핑하는 방법을 정의한다
		- ResultSet에서 가져와서 DTO에 담는 것과 비슷
		- 기본키(PK)는 <id>에 지정한다 	
	 -->
	<resultMap type="net.mem.MemDTO" id="rs"> 
		<!-- pk가 없기 때문에 id를 만들지 않았지만 pk가 있다면 result에 넣는게 아닌 따로 id로 만들어줘야함 -->
		<!-- <id/> PK 칼럼 지정 -->
		<!-- 3개의 column이 ResultSet에 담겼다고 보면 됨, dto에 담아서 진행했던것처럼 자료형을 지정해서 진행, 때문에 DTO를 철저하게 만들어야 getter와 setter를 제대로 가져와서 사용 -->
		<result column="num" 	property="num"/>
		<result column="name"	property="name"/>
		<result column="age" 	property="age"/>
	</resultMap>

 	<insert id="insertRow" parameterType="memDTO"> <!-- 안에 들어갈 쿼리문의 id가 insertRow, parameterType이 memDTO라는 것 -->
		INSERT INTO mem(num, name, age)
		VALUES(mem_seq.nextval, #{name}, #{age}) <!-- MemDTO의 name과 age를 사용한 것 -->
	</insert>	
	
	<select id="selectAll" resultMap="rs"> <!-- result를 사용할 때 num, name, age를 사용하기 편하게 하기 위해 하나로 담음-->
		SELECT num, name, age <!-- 칼럼명은 result의 칼럼명이고, property는 resultMap type="net.mem.MemDTO"에 들어 있음 -->
		FROM mem
		ORDER BY num DESC
	</select>
	
	<update id="updateRow" parameterType="memDTO">
		UPDATE mem
		SET	name=#{name}, age=#{age} <!-- getter, setter가 있다는 전제하에 parameterType이 memDTO가 되는 것 -->
		WHERE num=#{num}
	</update>
	
	<delete id="deleteRow" parameterType="int"> <!-- int 형으로 받겠다 -->
	<!-- < 가 비교연산자가 아닌 태그로 인식되기 때문에 [![CDATA]] 사용, a 는 임의 지정-->
		<![CDATA[
		DELETE FROM mem
		WHERE num<=#{a}  
		]]>
	</delete>
	
	<sql id="tablename">
		SELECT num, name, age FROM mem
	</sql>

	<sql id="sort">
		ORDER BY num DESC
	</sql>	
	
	<select id="search" parameterType="String" resultMap="rs">
		<include refid="tablename"></include>
		WHERE name LIKE '%' || #{keyword} || '%'
		<include refid="sort"></include>
	</select>
</mapper>

 가) 행추가

    - mem.xml의 mapper 이름 설정 후, MemMainTest.java 실행 → 콘솔창에 'DB연결 성공'

    → MemMainTest.java에 '가) 행추가 후', mem.xml에 insert 태그 생성 후 쿼리문 작성

  +) CRUD 작업을 위해서 5개 정도 행추가 진행

  나) 전체 목록

    - & mem.xml에 select 태그를 생성하여 selectAll 만들기

    - mem.xml의 select 태그의 resultMap="rs"는 resultMap 태그의 id와 동일

    - resultMap 태그와 result 태그 

 

 다) 행 수정

   - 2번의 장만월 20 을 수정할 것 → 2번 fullmoon 30 으로    

   - mem.xml 에서 'id=updateRow' 생성 

 

 라) 행 삭제

   +) > 와 같은 비교연산자로 쓰이는 것이 태그로 인식이 되기 때문에 이것을 막고자 사용하는 방법

     - 전자정부 프레임워크 → 개발 가이드 → 실행 환경 → 표준프레임워크 실행환경 3.8 에서 사용방법을 알 수 있음

    - 실행환경 메뉴얼에 있는 사용 방법을 이용하여 <![CDATA[]]> 안에 쿼리문을 작성

 

 마) 특정 글자를 가지고 있는 행 검색

Comments