개발..너... 2022. 6. 14. 16:46
Mybatis

 

객체지향 언어인 자바의 관계형 데이터베이스 프로그래밍을 좀 더 쉽게 할 수 있게 도와주는 개발 프레임 워크로서, jdbc를 통해 데이터베이스에 엑세스 하는 작업을 캡슐화. 일반 sql쿼리, 저장 프로시저 및 고급 매핑을 지원하며 모든 jdbc 코드 및 매개변수의 중복작업을 제거한다.

 

Mybatis에서는 프로그램에 있는 sql쿼리들을 한 구성파일에 구성하여 프로그램 코드와 sql을 분리할 수 있는 장점을 가지고있다.

 

Mybatis는 sql문을 xml파일에 작성함으로서 코드가 줄어들고, sql문만 따로 관리하기때문에 수정이 편리해진다. 또한 작업 효율과 가독성이 좋다.

 

 

Mybatis 라이브러리 다운로드

 

https://blog.mybatis.org/p/products.html

 

Products

A blog about the the MyBatis data mapper framework.

blog.mybatis.org

 

에서 MyBatis3을 다운로드 하였고

 

 

 

mybatis-3.5.10zip파일을 다운받아 풀어주었다.

 

 

Mybatis의 동작원리

 

 

1,2,3 은 서버가 기동이 되었을 때 Mybatis에서 어떤 기능들을 하고 어떤걸 읽어오는지 나타나 있는 그림이다.

서버가 가동되면 SQLsession factiory builder가 가장먼저 MyBatis Config File 을 읽어오게되고 여기에 정의된 구성에 따라서 sqlSessionFactory라는 객체를 만든다.

 

4번이후는 사용자의 요청이 들어왔을 때는 뜻하는데 Applicaiton 에서 요청이 들어왔을 떄 여기서 5번 방향으로 이동하여  SqlSessionFactory의 객체를 통해서 통해서 sqlSession을 만들어내고 그리고 여기에 매핑되는 MapperInterface의 메핑을 캐치하여 MappingFile을 정의해준다. 그리고 우리가 정의해놓은 SLQ문을 session이라고 하는 객체가 실행시켜주는 것이다.

 

 

 

쿼리를 실행하고 결과값을 실행하는 return값

 

 

select 

  • 성공: select문에 해당하는 결과 return
  • 실패: error

insert

  • 성공: 1(여러개도 1)
  • 실패: error

delete

  • 성공: delete된 행의 개수 반환(없으면 0)
  • 실패: 0

update

  • 성공: update된 행의 개수 반환(없으면 0)
  • 실패: error

 

Mybatis연결

 

 

*SqlMapConfig.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.koreait.mybatis;
 
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 SqlMapConfig {
    private static SqlSessionFactory factory;
    
    static {
    
        try {
            String resource = "./com/koreait/mybatis/config.xml";
            Reader reader = Resources.getResourceAsReader(resource);
            factory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
    
    public static SqlSessionFactory getFactory() {
        return factory;
    }
}
 
cs

 

 

*Config.xml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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="oracle.jdbc.driver.OracleDriver" />
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
                <property name="username" value="wjsp" />
                <property name="password" value="wjsp" />
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <mapper resource="com/koreait/sql/member.xml" />
    </mappers>
</configuration>
cs

 

*member.xml

 

1
2
3
4
5
6
7
8
9
10
11
<?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="Member">
    <select id="checkId" parameterType="string" resultType="_int">
        SELECT count(*) FROM TBL_MEMBER WHERE USERID = #{userid}
    </select>
</mapper>
 
cs

 

*MemberDao.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.koreait.dao;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
 
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
 
import com.koreait.beans.MemberBean;
import com.koreait.mybatis.SqlMapConfig;
 
public class MemberDAO {
    
    Context context;
    DataSource dataSource;
    
    Connection conn;
    PreparedStatement pstm;
    ResultSet rs;
    
    SqlSessionFactory factory = SqlMapConfig.getFactory();
    SqlSession sqlsession;
    
    public MemberDAO() {
        //autocommit
        sqlsession = factory.openSession(true);
    }
    
    
/*    public boolean checkId(String userid) {
        boolean result = false;
        String sql = "SELECT count(*) FROM TBL_MEMBER WHERE USERID = ?";
        
        try {
            
            context = new InitialContext();
            dataSource = (DataSource) context.lookup("java:comp/env/jdbc/oracle");
            conn = dataSource.getConnection();
            
            pstm = conn.prepareStatement(sql);
            pstm.setString(1, userid);
            rs = pstm.executeQuery();
            
            if( rs.next() ) {
                if( rs.getInt(1) == 1 ) {
                    result = true;
                }
            }
        }catch( SQLException e ) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }
        
        return result;
    }
    
*/    
    
    public boolean checkId(String userid) {
        boolean result = false;
        int cnt = 0;
        
        cnt = sqlsession.selectOne("Member.checkId", userid);
        if(cnt >=1) {
            result = true;
        }
        
        return result;
    }
}
cs

point1)

 

 

SqlMapConfig.java의 코드이다. 해당 코드는 서버가 가동되면서 읽어오는 1,2,3 화살표 부분으로 SqlSession Factory Builder로 들어와서 try문 안에서 MyBatis의 구성파일(Config File)을 읽어준 후 SqlSession Factory를 통해 return 시켜주고있다.

 

이 코드는 클래스가 처음 실행될 때 한번만 수행된다.

 

point2)

 

 

config.xml파일의 name,url,username,password는 context.xml에서 복사 붙혀넣기 해준다.

config.xml과 sqlMapConfig.java가 Mybaits를 사용하기 위한 기본 세팅이라고 할 수있다.

 

 

밑의 mapper를 통해서 xml과 이어준다.

pdf 3page

 

해당소스는 pdf파일을 참고로 하여 복사 붙혀넣기를 해주었고 "${driver}"자리의 값만 바꾸어주었다.

 

point3)

 

원래는 memberDao.java에 SQL을 String타입의 변수에 담아서 코드를 작성해주었다면 Mybatis를 활용하면 해당 sql코드를 member.xml로 빼서 MemberDao의 코드를 간편화시킬 수 있다. 

 

point4)

 

 

  • 주황색박스: 기존 MemberDao와 변경한 MemberDao의 동일한 부분
  • 파란색박스: member.xml파일에서 정의해주기에 삭제
  • 분홍색박스: 중복여부를 가리는 코드로서, 왼쪽 기본 MemberDao는 rs.next( )를 사용해야하기때문에 작성해야했던 몇줄의 코드들을 변경된 MemberDao는 sqlsession에 factory 객체를 통해 한줄로 간단히 데이터를 가지고 올 수 있게 되었다.
  • 초록색박스: Mybatis는 더이상 위의 context = new InitialContext()가 필요하지 않고 여기에서 발생하는 오류를 잡아주기위해 작성해야했던 예외처리 코드들도 필요없어 모두 삭제해준다.

 

point5)

 

 

Sql문만 정리해두는 member.xml 파일이다.

 

 

기존에 작성했던 SQL문은 ?을 통해서 key값을 가져왔지만 xml파일에선 #{key}값으로 좀 더 명시적으로 값을 불러올 수 있다.

 

pdf 4page

 

해당 소스도 pdf파일에서 복사 붙혀넣기 하여 안의 select문만 변경한 코드이다

 

point6)

 

여기서 중요한 것은 Dao와 XML부분이다. 

java에다가 바로 쿼리를 넣는 것은 수정할일이 있을 경우 컴파일을 해오고 컴파일이 완료된 클래스파일을 적용해야하는데 xml은 있는 그대로를 읽어오기때문에 따로 분리되어있는 부분이 훨씬 사용하기 좋다. 또한 여러 로직들이 한곳에 작성되는 것 보다 역할별로 세분화되어 개발하는 것을 권고한다.

 

  • DB쿼리가 잘못되었다: member.xml
  • DB리턴 처리가 잘못되었다: memberDao.java

 

DAO와 XML의 연결고리

 

빨간박스: SQL문을 가공할 Dao의 메서드 이름 기입

파란박스: 

 

XML은 id로 Dao에 사용된 메서드명을 가지고 오고 namesapce로는 Member.xml본인 이름을 가지고옴으로서 세팅을 해준다.

파란색박스는 객체의 프로퍼티값이 String으로 저장된다.

분홍색박스는 int형식으로 return하겠다는 의미이다.

 

출처: https://atoz-develop.tistory.com/entry/MyBatis-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-SQL-Mapper-%EC%9E%91%EC%84%B1-%EB%B0%A9%EB%B2%95

 

mybatis-3.5.10.pdf의 16page

 

Mybatis에만 사용할 수 있는 타입 알리아스가 따로 있는데 int형은 _int로 Stirng 은 string으로 표기하는 등의 규칙이 따로 있기에 pdf파일을 보고 알맞게 사용하도록 한다.

 

 

point7)

 

Config.xml
board.xml

 

Config와 board의 xml 파일이다.

resultType은 select문의 실행 결과를 담을 객체인데 우린 select문의 데이터를 DTO로 구조화해서 가지고와야한다. 이 때 resultType에 보통 DTO의 경로를 입력해야하는데 그럴 경우 resultType의 길이가 길어진다.

 

이를 위해 Config.xml에 typeAliases를 설정해준다.

여기에 DTO의 경로를 입력해주고 alias(경로의 별명)을 붙혀줌으로서 DTO의 긴 경로를 boarddto 단어 하나로 불러올 수 있게 되었다.