본문 바로가기
인턴

[인턴 OJT 7일차] mybatis

by 리잼 2022. 12. 21.
반응형

 

mybatis 란

- 쿼리 기반 웹App을 개발할 때 가장 많이 사용되는 SQL Mapper 프레임워크

- mybatis를 사용하지 않고 JDBC를 이용할 경우 문제점

- 개발자가 반복적으로 작성해야할 코드각 많고, 서비스 로직 코드와 쿼리를 분리하기가 어렵다

- 커넥션 풀의 설정 등 개발자가 신경 써야할 부분이 많아 여러가지 어려움이 있음

- JDBC를 이용해서 직접 개발하기 보다는 mybatis와 같은 프레임워크를 사용하는것이 일반적

- JDBC를 이용하여 프로그래밍 하는 방식

- 클래스나 JSP와 같은 코드안에 SQL문 작성

- 따라서 SQL의 변경 등이 발생할 경우 프로그램을 수정해야한다.

-> 유연하지 않다, 코드가 복잡하게 섞여 있어서 가독성이 떨어짐

- mybatis는 SQL을 XML파일에 작성하기 때문에, SQL의 변환이 자유롭고 가독성이 좋음

 

초기 설정

 

https://mybatis.org/mybatis-3/getting-started.html

 

mybatis – MyBatis 3 | Getting started

It's very important to understand the various scopes and lifecycles classes we've discussed so far. Using them incorrectly can cause severe concurrency problems. Dependency Injection frameworks can create thread safe, transactional SqlSessions and mappers

mybatis.org

해당 사이트에서 사용방법이 설명되어있다.

프로젝트파일 pom.xml에 dependency 넣어준다

driver=org.mariadb.jdbc.Driver
url=jdbc:mysql://localhost:3306/ojt?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
username=root
password=1234
 

프로젝트 resource 폴더에 db.properties 파일 작성

 

SqlMapConfig.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>
	<properties resource="db.properties" />
    // DB 연결 참조
	<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="com/barunsw/ojt/jmlee/day07/AddressBookDao.xml" />
	</mappers>
</configuration>
 

<environments> 엘리먼트는 환경을 설정하는 방법을 정의한다.

<mappers> 엘리먼트는 SQL 구문이 정의되어있는 리소스를 어디서 찾을지 지정을 한다.

클래스패스에 상대적으로 리소스를 지정할 수 있고, URL을 통해서도 지정할 수 있다.

 

그 외 컴포넌트

SqlSessionFactoryBuilder

- MyBatis 설정 파일을 바탕으로 SqlSessionFactory를 생성

sqlSessionfactoryManager

-모든 db의 쿼리 작업을 관리해주는역할

SqlSessionFactory

- SqlSession 생성

SqlSession

- 핵심적인 역할을 하는 클래스로서 SQL 호출과 트랜잭션 관리를 실행한다

Mapping 파일(user.xml)

- SQL문과 OR Mapping을 설정

 

Mybatis value를 받아주는 #{}, ${}의 차이

#{}

  • 파라미터가 String으로 들어와서(= 자동으로 ''가 붙는다) 자동으로 '파라미터 값'으로 적용
  • ex) where id = #{id} 이고 id 값이 1234면, 쿼리에는 where id = '1234'로 출력)
    SQL Injection 예방

${}

파라미터가 그대로 출력

  • 컬럼의 자료형에 맞춰 파라미터의 자료형이 변경
  • 사용자의 입력을 그대로 전달하는 경우에는 부적당
  • 테이블, 컬럼명을 파라미터로 전달할때 적당
  • SQL Injection을 예방할 수 없음

DAO 맵핑

public interface AddressBookDao {
	/**
	 * 주소록 정보를 조회한다.
	 * @param paramData 주소록 정보 리스트
	 * @return
	 */
	public List<AddressBookDto> selectAddressBookList(AddressBookDto paramData);
	/**
	 * 주소록 정보를 생성한다.
	 * @param paramData 주소록 정보
	 * @return
	 * @throws Exception
	 */
	public List<AddressBookDto> insertAddressBookList(AddressBookDto paramData);
	/**
	 * 주소록 정보를 수정한다.
	 * @param paramData 주소록 정보
	 * @return
	 * @throws Exception
	 */
	public List<AddressBookDto> updateAddressBookList(AddressBookDto paramData);
	/**
	 * 주소록 정보를 삭제한다.
	 * @param paramData 주소록 정보
	 * @return
	 * @throws Exception
	 */
	public List<AddressBookDto> deleteAddressBookList(AddressBookDto paramData);
}
 

SqlSessionFactory 생성

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;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class SqlSessionFactoryManager {
	private static final Logger LOGGER = LogManager.getLogger(SqlSessionFactoryManager.class);
	private static final SqlSessionFactory sqlMapper;
    //    처음엔 null이었 맵퍼가 static블럭이 실행된후 리턴되어 객체가 생성된다
	static {
		String resource = "com/barunsw/ojt/jmlee/day07/SqlMapConfig.xml";

		Reader reader = null;

		try {
			reader = Resources.getResourceAsReader(resource);
		} 
		catch ( IOException ex ) {
			LOGGER.error(ex.getMessage(), ex);
		}
		
		long startTime = System.currentTimeMillis();
		
		sqlMapper = new SqlSessionFactoryBuilder().build(reader, "development", System.getProperties());
		
		long endTime = System.currentTimeMillis();
		
		System.out.println(String.format("SqlSessionFactoryManager created(%s)", (endTime - startTime)));
	}

	public static SqlSessionFactory getSqlSessionFactory() {
		return sqlMapper;  
	}
}

 

MybatisAddressBookImpl.java

package com.barunsw.ojt.jmlee.day07;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.barunsw.ojt.constants.Gender;
import com.barunsw.ojt.intf.AddressBookInterface;
import com.barunsw.ojt.jmlee.day07.SqlSessionFactoryManager;
import com.barunsw.ojt.vo.AddressBookVo;

public class MybatisAddressBookImpl implements AddressBookInterface {
   	
	private static final Logger LOGGER = LoggerFactory.getLogger(MybatisAddressBookImpl.class);
	
	private static final SqlSessionFactory sqlSessionFactory = SqlSessionFactoryManager.getSqlSessionFactory();

	@Override
	public List<AddressBookVo> selectAddressBook(AddressBookVo paramData) {
		try (SqlSession session = sqlSessionFactory.openSession()) {
			AddressBookDao mapper = session.getMapper(AddressBookDao.class);
			
			List<AddressBookVo> addressBooklist = mapper.selectAddressBookList(new AddressBookVo());
			
			for (int i = 0; i < addressBooklist.size(); i++) {
				LOGGER.debug(String.format("[%d]%s", i, addressBooklist.get(i)));
			}
			return addressBooklist;
		}
	}

	@Override
	public int insertAddressBook(AddressBookVo paramData) throws Exception {
		// TODO Auto-generated method stub
		try (SqlSession session = sqlSessionFactory.openSession()) {
			System.out.println("insert 호출");
			AddressBookDao mapper = session.getMapper(AddressBookDao.class);
			
			mapper.insertAddressBook(paramData);
			session.commit();
			System.out.println("insert end");	
		}
		
		
		return 0;
	}

	@Override
	public int updateAddressBook(AddressBookVo paramData) throws Exception {
		try (SqlSession session = sqlSessionFactory.openSession()) {
			LOGGER.debug("update 호출");
			AddressBookDao mapper = session.getMapper(AddressBookDao.class);
			
			mapper.updateAddressBook(paramData);
			session.commit();
			LOGGER.debug("update end");	
		}		
		return 0;
	}

	@Override
	public int deleteAddressBook(AddressBookVo paramData) throws Exception {
		try (SqlSession session = sqlSessionFactory.openSession()) {
			LOGGER.debug("Delete 호출");
			AddressBookDao mapper = session.getMapper(AddressBookDao.class);
			
			mapper.deleteAddressBook(paramData);
			session.commit();
			LOGGER.debug("Delete end");	
		}				
		return 0;
	}

}
 

DBTest.java

package com.barunsw.ojt.jmlee.day07;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.barunsw.ojt.constants.Gender;
import com.barunsw.ojt.intf.AddressBookInterface;
import com.barunsw.ojt.vo.AddressBookVo;

public class DBTest {

	private static final Logger LOGGER = LoggerFactory.getLogger(DBTest.class);
	
	private static final SqlSessionFactory sqlSessionFactory = SqlSessionFactoryManager.getSqlSessionFactory();
	
	public static void main(String[] args) {

		AddressBookInterface addressBook = new MybatisAddressBookImpl();
         //mybatis에서는 기존의 커넥션 방식보다 단계가 간편화된다		
		try (SqlSession session = sqlSessionFactory.openSession()){
			AddressBookDao mapper = session.getMapper(AddressBookDao.class);

//			insert		
//			AddressBookVo insert = new AddressBookVo();
//			insert.setName("가나다");
//			insert.setBirthday("1958");
//			insert.setGender(Gender.MAN);
//			insert.setPhoneNumber("1585");
//			insert.setAddress("부산");
//			
//			addressBook.insertAddressBook(insert);
			
			
//			Update
//			AddressBookVo update = new AddressBookVo();
//			update.setSeqNum(3);
//			update.setName("강호동");
//			addressBook.updateAddressBook(update);
			
//			Delete
//			AddressBookVo delete = new AddressBookVo();
//			delete.setSeqNum(4);
//			addressBook.deleteAddressBook(delete);
			
			// select
			List<AddressBookVo> addressBookList = mapper.selectAddressBookList(null);
			for (AddressBookVo b : addressBookList) {
				LOGGER.debug(b.toString());
			}
			
			
		
		}
		catch (Exception ex) {
			LOGGER.error(ex.getMessage(), ex);
		}
		
	}

}
 

 

CRUD

1. Select

 

Insert

 

 

 

 

 

 

Update

 

Delete

반응형