본문 바로가기
Programming/JDBC

MyBatis(4) 아키텍쳐

by yoon9i 2024. 4. 5.

MyBatis 아키텍쳐

1) 아키텍쳐
                                                          EmpService(인터페이스)
    |
EmpMain <-----------------> EmpServiceImpl ( 클래스 ) <--------------------------> EmpDAO <--------------------> MySQL
(main 메서드)                        - 비즈니스로직 처리                                             - DB 연동
- 사용자 입력 및 출력            - 트랜잭션처리( * )                    EmpDTO
                                                                                             - 데이터 전달용


2) MyBatis 연동
가. MySQL 드라이버 및 MyBatis 라이브러리 다운로드 및 build path
mysql-connector-j-8.3.0.jar 
mybatis-3.5.14.jar

나. DB 연동시 필요한 4개의 값을 저장한 jdbc.properties 작성
=> src 폴더 ( classpath 경로 )
=> package 형식 사용 가능 ( ex) com.config.jdbc.properties )

* 환경변수
JAVA_HOME=jdk 홈디렉토리경로
PATH=명령어경로; 명령어경로1
CLASSPATH= 클래스파일이있는경로( *.jar )

다. 테이블의 컬럼을 저장하기 위한 DTO 클래스 작성
==> emp 데이터 저장용으로 com.dto.EmpDTO 작성
==> 자동으로 mapping 해서 사용하기 위해서
        EmpDTO 의 변수명은 가능하면 emp 테이블의 컬럼명으로 지정한다.
        반드시 테이블의 컬럼명으로 지정된 set컬럼명( ), get컬럼명( ) 지정해야 된다. ( * )
==> DTO 는 기본생성자가 필수이다.
       이유는 <select id="paging" resultType="EmpDTO"> 지정하면
       내부적으로 시스템이 기본생성자를 이용해서 EmpDTO 를 객체생성한다.
==> 테이블당 한개씩 작성.


라. 2개의 xml 작성
     => src 폴더 ( classpath 경로 )
     => package 형식 사용 가능 ( 예> com.config.jdbc.properties)
       접근할 때는 / 경로 사용 ( 예> com/confog/Configuration.xml )

     a. 설정 정보
       - 용도: jdbc.properties 등록해서 DB 연동함.
              DTO 별칭 지정.
 mapper 등록.
             https://mybatis.org/mybatis-3/getting-started.html#building-sqlsessionfactory-from-xml 참조
예> Configuration.xml


     b. sql 정보
       - 용도: sql 문 설정.
       - 테이블당 한개씩 작성.
       - 테이블Mapper.xml 명명법 권장.
      https://mybatis.org/mybatis-3/getting-started.html#exploring-mapped-sql-statements 참조
        예> EmpMapper.xml



마. Configuration.xml를 자바코드로 읽기
 https://mybatis.org/mybatis-3/getting-started.html#building-sqlsessionfactory-from-xml 참조

  원본:
        String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
  new SqlSessionFactoryBuilder().build(inputStream);

 변경: 

       MySqlSessionFactory.java

       public class MySqlSessionFactory {
  
            static SqlSessionFactory sqlSessionFactory;
             static {
                  String resource = "com/config/Configuration.xml";
                   InputStream inputStream=null;
                   try {
                           inputStream = Resources.getResourceAsStream(resource);
                   } catch (IOException e) {
                       e.printStackTrace();
                    }
               sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
             }//end static 블럭

            // SqlSessionFactory 로부터 SqlSession 얻는 메서드
           public static SqlSession getSession() {
                        // MyBatis는 명시적으로 commit 지정해야 된다.
                SqlSession session = sqlSessionFactory.openSession(); // openSession(false) 동일
                return session;
             }

 

    
}
#####################################################################

 바.  Service 작성
 
     a. 구조
      
       com.service.EmpService (인터페이스)
          |
      com.service.EmpServiceImpl (클래스)
    
     b. 역할
        - 비즈니스 로직
- 트랜잭션 처리 (***** )

     c. 특징
        - SqlSession 만 얻음.
          DAO로 SqlSession를 전달해야 됨.


    * Connection 과 SqlSession 특징
    => 반드시 메서드안에서 로컬 변수로 얻어야 된다. ( thread-safe 보장 )
      이유는 공유하면 절대 안됨.
     # JDBC 버전

     public int insert(){
        Connection con = null;

con.close();
     }
     
      public int select(){
        Connection con = null;

        con.close();
     }

   사. DAO 작성

    a. 구조
      - com.dao.EmpDAO.java

    b. 역할
      - MySQL 연동
      
     c. 특징
      - Service에서 전달한 SqlSession으로 메서드 호출해서 DB 연동.

   아. Main 작성

      a. 구조
      - com.dao.EmpMain

      b. 역할
      - 사용자 데이터 입력 및 출력 ( 화면처리 )
      
     c. 특징
      - Service 와 연동
      - EmpDAO 생성해서 Service에 설정. (****)

# 주석문
# com.config.jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testdb
jdbc.userid=root
jdbc.passwd=1234
package com.service;

import java.util.List;

import com.dao.EmpDAO;
import com.dto.EmpDTO;

public interface EmpService {
	
	public List<EmpDTO> findAll();
	public int save(EmpDTO dto);
	public int removeByEmpno(int empno);
	
	public void setDao(EmpDAO dao);
}
package com.service;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.config.MySqlSessionFactory;
import com.dao.EmpDAO;
import com.dto.EmpDTO;

public class EmpServiceImpl implements EmpService {
	
	private EmpDAO dao;
	
	public void setDao(EmpDAO dao) {
		this.dao = dao;
	}

	// findAll -----------------------------------------------------
	@Override
	public List<EmpDTO> findAll() {
		SqlSession session = null;
		List<EmpDTO> list = null;

		try {
			session = MySqlSessionFactory.getSession();
			// DAO 연동코드
			list = dao.findAll(session);
			//
		} finally {
			session.close();
		}

		return list;
	}

	// save  -----------------------------------------------------
	@Override
	public int save(EmpDTO dto) {
		SqlSession session = null;
		int n = 0;
		
		try {
			session = MySqlSessionFactory.getSession();
			// DAO 연동코드

			//
		} finally {
			session.close();
		}

		return n;
	}
	
	// remove --------------------------------------------

	@Override
	public int removeByEmpno(int empno) {
		SqlSession session = null;
		int n = 0;
		
		try {
			session = MySqlSessionFactory.getSession();
			// DAO 연동코드
			n = dao.removeByEmpno(session, empno);
			session.commit();
			//
		} finally {
			session.close();
		}

		return n;
	}

}
package com.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.dto.EmpDTO;

// DB 연동
public class EmpDAO {
	
	// find
	public List<EmpDTO> findAll(SqlSession session) {
		List<EmpDTO> list = session.selectList("com.config.EmpMapper.findAll");
		return list;
	}
	
	// save
	public int save(SqlSession session, EmpDTO dto) {
		return 0;
		
	}
	
	// remove
	public int removeByEmpno(SqlSession session, int empno) {
		return session.delete("com.config.EmpMapper.removeByEmpno",empno);
	}
	
	
	
}
package com.dto;

public class EmpDTO {
	
	// emp 테이블의 컬럼명과 일치 권장.
	int empno;
	String ename;
	String job;
	int mgr;
	String hiredate; // 날자는 연산이 필요없으면 그냥 String 으로 처리
	int sal;
	int comm;
	int deptno;
	
	// 기본생성자필수(*)
	public EmpDTO() {
		// TODO Auto-generated constructor stub
	}

	public EmpDTO(int empno, String ename, String job, int mgr, String hiredate, int sal, int comm, int deptno) {
		this.empno = empno;
		this.ename = ename;
		this.job = job;
		this.mgr = mgr;
		this.hiredate = hiredate;
		this.sal = sal;
		this.comm = comm;
		this.deptno = deptno;
	}

	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;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public int getMgr() {
		return mgr;
	}

	public void setMgr(int mgr) {
		this.mgr = mgr;
	}

	public String getHiredate() {
		return hiredate;
	}

	public void setHiredate(String hiredate) {
		this.hiredate = hiredate;
	}

	public int getSal() {
		return sal;
	}

	public void setSal(int sal) {
		this.sal = sal;
	}

	public int getComm() {
		return comm;
	}

	public void setComm(int comm) {
		this.comm = comm;
	}

	public int getDeptno() {
		return deptno;
	}

	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}

	@Override
	public String toString() {
		return "EmpDTO [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate="
				+ hiredate + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + "]";
	}
	
	
	
	
}
package com.config;

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

	static SqlSessionFactory sqlSessionFactory;
	static {
		String resource = "com/config/Configuration.xml";
		InputStream inputStream = null;
		try {
			inputStream = Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			e.printStackTrace();
		}
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}// end static 블럭

	// SqlSessionFactory 로부터 SqlSession 얻는 메서드
	public static SqlSession getSession() {
		// MyBatis는 명시적으로 commit 지정해야 된다.
		SqlSession session = sqlSessionFactory.openSession(); // openSession(false) 동일
		return session;
	}

}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<!-- jdbc.properties 등록 -->
	<properties resource="com/config/jdbc.properties"></properties>
	
	<!-- DTO 별칭 -->
	<typeAliases>
		<typeAlias type="com.dto.EmpDTO" alias="EmpDTO"/>
	</typeAliases>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<!-- jdbc.properties 등록된 값을 참조: ${key} -->
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.userid}" />
				<property name="password" value="${jdbc.passwd}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- Mapper.xml 등록 -->		
		<mapper resource="com/config/EmpMapper.xml"/>
	</mappers>
</configuration>
import java.util.List;
import java.util.Scanner;

import com.dao.EmpDAO;
import com.dto.EmpDTO;
import com.service.EmpService;
import com.service.EmpServiceImpl;

public class EmpMain {

	public static void main(String[] args) {

		EmpService service = new EmpServiceImpl();
		service.setDao(new EmpDAO());

		Scanner scan = new Scanner(System.in);

		while (true) {

			System.out.println("1. 전체목록");
			System.out.println("2. 사원삭제");
			System.out.println("0. 종료");
			System.out.println("-------------------");
			String num = scan.next();

			if ("1".equals(num)) {
				
				List<EmpDTO> list = service.findAll();
				for (EmpDTO e : list) {
					System.out.println(e);
				}
				
			} else if ("2".equals(num)) {

				System.out.println("삭제할 사원번호를 입력하시오.");
				String deptno = scan.next();
				
				int n = service.removeByEmpno(Integer.parseInt(deptno));
				System.out.println(n + " 개가  삭제됨.");
				
			} else if ("0".equals(num)) {
				System.out.println("프로그램 종료됨.");
				System.exit(0);
			}

		} // end while
	}

}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="com.config.EmpMapper">
	<!-- 전체 조회 -->
	<select id="findAll" resultType="EmpDTO">
		SELECT	 empno, 
				 ename, 
				 sal, 
				 date_format(hiredate, '%y') AS hiredate, 
				 deptno
		FROM emp
		ORDER BY empno DESC	
	</select>
	
	<!-- 사원삭제 -->
	<delete id="removeByEmpno" parameterType="int">
		DELETE FROM emp
		WHERE empno = #{empno}
	</delete>
	
	
</mapper>

'Programming > JDBC' 카테고리의 다른 글

Swing(2) 레이아웃  (0) 2024.04.09
Swing(1) 기본설명 및 프로젝트 생성  (0) 2024.04.09
MyBatis(3) 동적sql 처리  (0) 2024.04.05
MyBatis(2) MyBatis 사용  (0) 2024.04.04
MyBatis(1) 설치 및 설정  (0) 2024.04.04