ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL #34 - MyBatis시작
    프로그래밍/TIL(국비과정) 2020. 6. 22. 18:00

    # MyBatis란?

    MyBatis는 SQL쿼리문, 예외처리, 트랜잭션  관리들을 XML 형식으로 관리해주는 퍼시스턴스 프레임워크이다. 

    더보기

    퍼시스턴스 프레임워크(Persistence Framework)란 데이터의 저장, 조회, 변경, 삭제를 다루는 클래스 및 설정 파일드르이 집합니다. 

    (출처 : 위키백과https://ko.wikipedia.org/wiki/%ED%8D%BC%EC%8B%9C%EC%8A%A4%ED%84%B4%EC%8A%A4_%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC )

    그렇기 때문에 POJO(Pain Old Java Object) 객체와 테이블의 칼럼들을 편리하며 빠르고 정확하게 매칭할 수 있다. 

    MyBatis는 의존성이 적은 특징이 있는데 실 사용시 SQL문과 Java 코드를 분리해 쿼리문에 신경을 덜 쓸 수 있다.

     

    MyBatis는 MVC 패턴 중 DB에 직접 접근하는 Control 부분인 BoardListService.java의 파일을 예로 들면 아래와 같은 부분에 들어있다. 

    BoardListService.java 에서 데이터를 읽어오고 BoardDAO로 가 DB로 접근할 때 myBatis 구역에 먼저 접근하게 된다.

    이때 myBatis에 접근하기 위해선 SQL Session 이라는 객체가 필요하다. 

    SQL Session은 SQL Session Factory에 의해 만들어진다. 

    SqlSession sqlSession = sqlSessionFactory.openSession();

     


    여기까지만 해서는 MyBatis 존재의미가 잘 와닿지 않으니 코드를 보도록 한다. 

    먼저 MyBatis를 사용하기 전의 memberDAO.java이다. 

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import javax.sql.DataSource;
    
    import member.bean.MemberDTO;
    import member.bean.ZipcodeDTO;
    
    public class MemberDAO {
        private static MemberDAO instance; // 싱글톤이라는 티를 팍팍 낸다.
        
    	private Connection conn;
    	private PreparedStatement pstmt;
    	private ResultSet rs;	
    	private DataSource ds;
       
        public MemberDAO() {
        	Context ctx;
    		try {
    			ctx = new InitialContext();
    			ds = (DataSource)ctx.lookup("java:comp/env/jdbc/oracle");
    		} catch (NamingException e) {
    			e.printStackTrace();
    		}
    	}
        
        public static MemberDAO getInstance() { 
        	if(instance == null) {
        		synchronized(MemberDAO.class) {
        			instance = new MemberDAO();
    			}
        	}
            return instance;
        }
        
         public int write(MemberDTO memberDTO) {
    		int su = 0;
    
    		String sql = "insert into member values(?,?,?,?,?,?,?,?,?,?,?,?,sysdate)";
    		try {			
    			conn = ds.getConnection(); // 오라클 접속
    			
    			pstmt = conn.prepareStatement(sql);
    
    			pstmt.setString(1, memberDTO.getName());
    			pstmt.setString(2, memberDTO.getId());
    			pstmt.setString(3, memberDTO.getPwd());
    			pstmt.setString(4, memberDTO.getGender());
    			pstmt.setString(5, memberDTO.getEmail1());
    			pstmt.setString(6, memberDTO.getEmail2());
    			pstmt.setString(7, memberDTO.getTel1());
    			pstmt.setString(8, memberDTO.getTel2());
    			pstmt.setString(9, memberDTO.getTel3());
    			pstmt.setString(10, memberDTO.getZipcode());
    			pstmt.setString(11, memberDTO.getAddr1());
    			pstmt.setString(12, memberDTO.getAddr2());
    			
    			su = pstmt.executeUpdate();	
    			
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				if(pstmt != null) pstmt.close();
    				if(conn != null) conn.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}		
    		return su;
    	}
        

    DAO.java 코드 안에 db 연결과 sql 문의 실행까지 다 이루어지고 있다. 

     

     

    다음은 MyBatis를 사용하고 난 이후의 userDAO.java이다. 

    (DB에 데이터를 넣는 것은 똑같기 때문에 DB에 데이터를 넣는 방식만 확인하면 된다.)

    import java.io.IOException;
    import java.io.Reader;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import user.bean.UserDTO;
    
    public class UserDAO {
    	public static UserDAO instance;
    	private SqlSessionFactory sqlSessionFactory;
    
    	public static UserDAO getInstance() {
    		if (instance == null) {
    			synchronized (UserDAO.class) {
    				instance = new UserDAO();
    			}
    		}
    		return instance;
    	}
    
    	public UserDAO() {
    
    		try {
    			Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
    			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    	
    		} catch (IOException e) {
    
    			e.printStackTrace();
    		}
    	}
        	public int write(UserDTO userDTO) {
    		SqlSession sqlSession = sqlSessionFactory.openSession();
    		int su = sqlSession.insert("userSQL.write", userDTO);
    
    		sqlSession.commit(); 
    		sqlSession.close(); // 반환
    		
    		return su; 
    	}

     

    가장 크게 달라진 것은 SQL 문이 DAO 안에 있지 않다는 것과 pstm를 통해 데이터를 일일이 넣어주는 과정이 없어졌다는 것이다. 

    SQL문은 userMapper.xml 이라는 파일로 빠진다. 

    MyBatis는 sql쿼리문, 예외처리, 트랜잭션 관리들을 XML 형식으로 따로 관리하기 때문이다. 

    이를 통해 POJO(Plain Old Java Object) 객체와 테이블의 컬럼들을 편리하고 빠르게 매칭할 수 있게 된다. 

    더보기

    POJO(Plain Old Java Object) 란 그대로 해석하면 오래된 방식의 간단한 자바 오브젝트라는 말로, 

    JavaEE 등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 '무거운' 객체를 만들게 된 것에 반발해서 사용되게 된 용어이다 

    (출처: 위키백과 

    https://ko.wikipedia.org/wiki/Plain_Old_Java_Object)

    POJO(Plain Old Java Object) 란 그대로 해석하면 오래된 방식의 간단한 자바 오브젝트라는 말로, 

    JavaEE 등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 '무거운' 객체를 만들게 된 것에 반발해서 사용되게 된 용어이다 

    (출처: 위키백과 

    https://ko.wikipedia.org/wiki/Plain_Old_Java_Object)

    <?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="userSQL">
    	<insert id="write" parameterType="user.bean.UserDTO">
    		insert into usertable values(#{name},#{id},#{pwd})
    	</insert>

     

    이곳에 sql문을 넣고 

    데이터를 사용자로부터 입력받아 DTO 에 넣어서 따로 DAO로 보내는 과정은 UserInsertService.java 라는 파일에서 따로 이루어진다. 

    import java.util.Scanner;
    
    import user.bean.UserDTO;
    import user.dao.UserDAO;
    
    public class UserInsertService implements UserService {
    
    	@Override
    	public void execute() {
    		// 이름, 아이디, 비밀번호 입력 
    		Scanner scan = new Scanner(System.in);
    		
    		System.out.print("이름 : ");
    		String name = scan.next();
    		
    		System.out.print("아이디 : ");
    		String id = scan.next();
    		
    		System.out.print("비밀 번호 : ");
    		String pwd = scan.next();
    		
    		UserDTO userDTO = new UserDTO();
    		
    		// dto에 데이터 담기 
    		userDTO.setName(name);
    		userDTO.setId(id);
    		userDTO.setPwd(pwd);
    		
    		// userDAO 접근
    		UserDAO userDAO = UserDAO.getInstance();
    		int su = userDAO.write(userDTO); 
    		
    		System.out.println(su + "개 저장 완료");
    	}
    
    }
    

     

    DB에 접근하는 곳, DB에 접근해서 수행할 SQL문을 가진 곳, 데이터를 입력받는 곳 이 모두가 이전엔 ~~DAO.java 라는 파일에서 한꺼번에 이루어졌지만 MyBatis 를 통해 전부 나누어지게 되었다. 

    따라서 MyBatis는 의존성이 적다는 장점을 가지게 된다. 

     

    MyBatis 는 자바오브젝트와 sql문 사이의 자동매핑 기능을 지원하는 ORM(Object Relational Model) 프레임워크로 

    자바코드와 SQL을 분리함으로써 SQL 문의 변경이 있어도 자바코드를 수정하거나 컴파일하지 않아도 된다. 

     

    더보기

    ORM 프레임워크란 데이터베이스와 객체지향프로그래밍 언어간의 호환되지 않는 데이터를 변환, 맵핑하는 프로그래밍 기법이다. 

    ORM 프레임워크란 데이터베이스와 객체지향프로그래밍 언어간의 호환되지 않는 데이터를 변환, 맵핑하는 프로그래밍 기법이다. 

     

    추가적으로 db에 연결하기 위한 driver 경로나 url 의 경우 mybatis-config.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="development">
    		<environment id="development">
    			<transactionManager type="JDBC" />
    			
    			<!-- POOLED,UNPOOLED,JNDI(Java Naming and Directory Interface) -->
    			<dataSource type="POOLED">
    				<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
    				<property name="url" value="url"/>
    				<property name="username" value="username"/>
    				<property name="password" value="password"/>
    			</dataSource>
    		</environment>
    	</environments>
    	
    	<mappers>
    		<mapper resource="user/dao/userMapper.xml"/>
    	</mappers>
    </configuration>

    위의 코드에서 sql 쿼리를 넣어줄 userMapper.xml 의 경로도 알려준다. 

     

    댓글

Designed by Tistory.