mybatis 란
- 쿼리 기반 웹App을 개발할 때 가장 많이 사용되는 SQL Mapper 프레임워크
- mybatis를 사용하지 않고 JDBC를 이용할 경우 문제점
- 개발자가 반복적으로 작성해야할 코드각 많고, 서비스 로직 코드와 쿼리를 분리하기가 어렵다
- 커넥션 풀의 설정 등 개발자가 신경 써야할 부분이 많아 여러가지 어려움이 있음
- JDBC를 이용해서 직접 개발하기 보다는 mybatis와 같은 프레임워크를 사용하는것이 일반적
- JDBC를 이용하여 프로그래밍 하는 방식
- 클래스나 JSP와 같은 코드안에 SQL문 작성
- 따라서 SQL의 변경 등이 발생할 경우 프로그램을 수정해야한다.
-> 유연하지 않다, 코드가 복잡하게 섞여 있어서 가독성이 떨어짐
- mybatis는 SQL을 XML파일에 작성하기 때문에, SQL의 변환이 자유롭고 가독성이 좋음
초기 설정
해당 사이트에서 사용방법이 설명되어있다.
프로젝트파일 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
'인턴' 카테고리의 다른 글
[인턴 OJT 9일차] Java Swing (0) | 2022.12.23 |
---|---|
[인턴 OJT 8일차] Java swing Jframe, Jpanel, Layout (0) | 2022.12.21 |
[인턴 OJT 6일차] File I/O , DBAddressImpl 수정 및 복습 (0) | 2022.12.20 |
[인턴 OJT 5일차] Java DB 연동 select, insert (0) | 2022.12.16 |
[인턴 OJT 4일차] 직렬화 ( serialization ), file i/o 기반 주소록 (0) | 2022.12.15 |