본문 바로가기

Dev/[Java]

[DBMS] 6. Mybatis 연동후 MariaDB와 붙여서 CRUD작성

반응형

Mybatis 는 자바개발자라면 무조건 알아야하는 프레임워크..

 

국내 기업들은 마이바티스 이런걸 그대로 가져다쓰면 불편한게 많아서 자기들에 맞게 커스터마이징 해서 쓴다.

 

 

아래 API문서를 참고하면서 개발한다.

 

javadoc.io/doc/org.mybatis/mybatis/latest/index.html

 

mybatis 3.5.6 javadoc (org.mybatis)

Latest version of org.mybatis:mybatis https://javadoc.io/doc/org.mybatis/mybatis Current version 3.5.6 https://javadoc.io/doc/org.mybatis/mybatis/3.5.6 package-list path (used for javadoc generation -link option) https://javadoc.io/doc/org.mybatis/mybatis/

javadoc.io

 

Mybatis는 자바 오브젝트와 SQL문 사이의 자동 Mapping 기능을 지원하는 ORM 프레임워크이다.

(사실 완벽한 ORM은아님.. Hibernate..가 완벽한 ORM)

 

Mybatis는 SQL을 별도의 파일로 분리해서 관리하게 해주며, 객체-SQL사이의 파라미터 Mapping 작업을 자동으로 해주기 때문에 많은 인기를 얻고 있는 기술이다.

 

Mybatis는 Hibernate 나 JPA(JAVA Persistence API)처럼 새로운 DB 프로그래밍 패러다임을 익혀야 하는 부담이 없이, 개발자가 익숙한 SQL을 그대로 이용하면서 JDBC 코드 작성의 불편함도 제거해주고, 도메인 객체나 VO 객체를 중심으로 개발이 가능하다는 장점이 있다.

 

Connection 만들고, Statement 객체 만들고.. 이런 불편함이 Mynatis엔 없다는 것..

 

특징1. 쉬운 접근성과 코드의 간결함..

XML형태로 서술된 JDBC 코드라고 생각해도될만큼 JDBC의 거의모든기능을 제공.

 

Java, C#, .net, Ruby 에서도 Mybatis 사용가능

 

 

 

자 이제 할 것..

 

3. Mybatis 개요 및 구현.. 이건 한글로 된 PDF 가 있다.

: mysql jdbc driver설치

: mybatis Architecture 전체 구조 이해

: Mybatis Configuration file 작성

:Mybatis 를 사용한 DAO클래스 작성 및 Test 클래스 작성

이후 서블릿 붙이면된다.

 

 

 

메이븐 레포지토리 접속해서 Mysql Connector 받는다.

이렇게 2개가 받아진다.

 

 

 

이후 프로젝트의 Src폴더에 다음 3가지 파일을 만들어줘야댄다.

 

 

1. db.properties

#db.driver=oracle.jdbc.OracleDriver
#db.url=jdbc:oracle:thin:@127.0.0.1:1521:xe
#db.username=scott
#db.password=tiger

db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306/java_db?useUnicode=true&charaterEncoding=utf-8&useSSL=false&serverTimezone=UTC
db.username=scott
db.password=tiger

이런식으로.. 적어준다

이렇게 하면 db driver, url, id/pw 전부 설정 끝..

다음은 sql Map Config파일..

 

 

SqlMapConfig.XML

: 얘는 마이바티스 설정파일이다.

: 아까 개발자/DBA역할분리한다고했다..

: 여기서 이것을 매핑해준다..

 

mapperXML파일은 여러개 생길 수 있다... SQL문이 추가되념 추가될수록 생겨나니까...

JDBC Properties 은 우리가 이미 다 만들었다..

여기서 가장중요한건 SqlSession이라는 애가 젤중요하다.

 

우리가 작성한 맨밑에 3개를 SqlSessionFactory 라는애가 SqlSession 으로 만들어준다... 이 구조가 중요..

 

 

기존에우리가 Drivermanager라는것을 썻는데 마이바티스는 SQL세션의 데이타소스로부터 뭔가 컨낵션을 가져오는 SQLsession을 생성한다.

아래는 mybatis api doc...

 

 

DATASOURCE는 jdbc에 있다.

아래는 javase api doc..

 

Driver manager 의 alternative 객체이고, 컨넥션을 생성해주는 역할..

 

 

아래는 스택오버플로 참고,.(dataase pooling 으로 검색)

connection 재사용이 가능하다는 특징이있다.

 

 

 

아파치 DBCP

HikariCP라는것도 있다.(Spring boot 채택)

datasource 를 구현해주는 구현체..

 

데이터베이스와 애플리케이션을 효율적으로 연결하는 커텍션 풀 라이브러리는 웹 애플리케이션에서 필수요소,

웹앱에서 서버로 상용 제품을 사용하다보면 보통 제조사에서제공하는 커넥션풀 구현체를 씀.

 

아래 설명이 잘 나와있으니 참고..

네이버 디벨로퍼 참고

d2.naver.com/helloworld/5102792

 

HikariCP라는것도 있다.(Spring boot 채택)

히카리는 빛 광 光자의 일본어라고함..

빠른게 장점..

현업에서도 많이쓴다..

 

아래는 히카리시피 깃헙

github.com/brettwooldridge/HikariCP

 

brettwooldridge/HikariCP

光 HikariCP・A solid, high-performance, JDBC connection pool at last. - brettwooldridge/HikariCP

github.com

 

암튼...

이제 마이바티스 한글화 되어있는 PDF보면서 마이바티스에대한 세팅을 할 것이다.

 

 

아까 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>
	<!-- DB 접속정보를 가진 Properties file을 설정해준다.. -->
	<properties resource="db.properties" />
	
	<!-- VO객체를 설정한다..(클래스 이름이 뭔지 알려주는거지.) -->
	<!-- jdbc.user.vo.UserVO 이걸 짧게 쓰기 위해 Alias를 준다.alias="User" -->
	<typeAliases>
		<typeAlias alias="User" type="jdbc.user.vo.UserVO"/>
	</typeAliases>

	<!--  DataSource 설정 -->
	<!--  나중에 Spring 연동하면 이부분은 안한다. -->
	<!--  db.properties 에 있는 정보들을 아래와같이 넣어준다. -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${db.driver}"/> <!-- 런타임에 이부분 치환됨 -->
				<property name="url" value="${db.url}"/>
				<property name="username" value="${db.username}"/>
				<property name="password" value="${db.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- SQL 문을 포함한 Mapper XML 설정 -->
	<!-- 나중에 XML파일이 많아지면 여기아래에 쭉 써주면된다. -->
	<mappers>
		<mapper resource="UserMapper.xml" />
	</mappers>

</configuration>

 

 

Usermapper.XML 수정할 차례..

여기선 namespace 개념이들어간다..

 

여기서 주의할점..

 

select 문은 setter를 쓴다.

매서드 명과 같이 맞춰줘야 동작한다..!

 

getMyFirstName(), setMyFirstName()이라는 매서드 있으면,,

 

#{myFirstName}

 

 

 

 

<?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="userNS">
 
 	<!-- 파라미터 2개이상일경우 객체로받아야댐... -->
 	<select id="selectUserById" parameterType="string" resultType="User">
 		select * from users where userid = #{value}
 	</select>
 	
 	<select id="selectUserList" resultType="User">
 		select * from users order by id
 	</select>
 	
 	<insert id="insertUser" parameterType="User">
 		insert into users (userid, name, gender, city) value(#{userid},#{name},#{gender},#{city})
 	</insert>
 	
 	<update id="updateUser" parameterType="User">
 		update users set 
 			name = #{name},
 			gender= #{gender},
 			city = #{city}
 		where userid = #{userid};
 	</update>
 	
 	<delete id="deleteUser" parameterType="integer">
 		delete from users where id=#{value}
 	</delete>
 	
 
 </mapper> 

 

 

변수명 이렇게 쓰면안된다...!

마이바티스연동할때 에러남

 

 

자 암튼 이렇게 usermapper까지 완료되었고,, SQLsessionfactory빌더 를 이용하여 빌드하기...

마이바티스 번역문서보기..(5페이지)

이런 구조를 이해하라는...말인것같다..

 

 

이제 DAO 클래스로가본다.

 

 

 

 

 

update, delete, select 등을 만들어준다..

아래와 같은  포맷에 맞춰 작성해주면 된다..

 

package jdbc.user.dao;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.List;

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 jdbc.user.vo.UserVO;

public class UserDAOMyBatis {

	private SqlSessionFactory sqlSessionFactory;

	public UserDAOMyBatis() {
		// 이제 이만큼은 안해도된다.
		// 최초에 한번만 하면된다..
		String resource = "SqlMapConfig.xml";
		try {
			InputStream inputStream = Resources.getResourceAsStream(resource);
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

		} catch (IOException e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
	}

	public int deleteUser(int id) {
		int deleteCount = 0;
		SqlSession session = null;

		try {
			session = sqlSessionFactory.openSession();
			Connection con = session.getConnection();
			// auto commit 모드 해제
			con.setAutoCommit(false);
			deleteCount = session.delete("userNS.deleteUser", id);
			//session.commit();

			if (deleteCount > 0) {
				session.commit();
			} else {
				session.rollback();
			}
		} catch (Exception e) {
			session.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return deleteCount;
	}

	public int updateUser(UserVO user) {
		int updateCount = 0;
		SqlSession session = null;

		try {
			session = sqlSessionFactory.openSession();
			Connection con = session.getConnection();
			// auto commit 모드 해제
			con.setAutoCommit(false);
			updateCount = session.update("userNS.updateUser", user);
			session.commit();

			if (updateCount > 0) {
				session.commit();
			} else {
				session.rollback();
			}

		} catch (Exception e) {
			session.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return updateCount;
	}

	public int insertUser(UserVO user) {
		int insCnt = 0;
		SqlSession session = null;

		try {
			session = sqlSessionFactory.openSession();
			insCnt = session.insert("userNS.insertUser", user);
			if (insCnt > 0) {
				session.commit();
			} else {
				session.rollback();
			}

		} catch (Exception e) {
			session.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}

		return insCnt;
	}

	// UserList
	public List<UserVO> getUsers() {
		List<UserVO> userList = null;
		SqlSession session = sqlSessionFactory.openSession();

		try {
			userList = session.selectList("userNS.selectUserList");
		} finally {
			session.close();
		}

		return userList;
	}

	// User 1건 조회
	public UserVO getUser(String userid) {
		UserVO user = null;
		SqlSession session = sqlSessionFactory.openSession();

		try {
			user = session.selectOne("userNS.selectUserByUserid", userid);
		} finally {
			session.close();
		}

		return user;
	}

}

 

유닛테스트

 

package jdbc.user.test;


import java.util.List;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import jdbc.user.dao.UserDAOMyBatis;
import jdbc.user.vo.UserVO;

public class UserDAOMyBatisTest {
	UserDAOMyBatis dao;
	
	
	@Before
	public void init() {
		dao = new UserDAOMyBatis();
	}
	
	@Test
	public void deleteUser() {
		int deleteCount = dao.deleteUser(2);
		System.out.println("삭제된 건수 : "+ deleteCount);
		
//		List<UserVO> userList = dao.getUsers();
//		for (UserVO userVO : userList) {
//			System.out.println(userVO);
//		}
		
	}
	
	
	@Test @Ignore
	public void updateUser() {
		UserVO user = new UserVO("test","테스트22","여22","오산22");
		int nCount = dao.updateUser(user);
		Assert.assertEquals(1, nCount);
		System.out.println("갱신된 건수" + nCount);
		
		List<UserVO> userList = dao.getUsers();
		for (UserVO userVO : userList) {
			System.out.println(userVO);
		}
	}
	
	
	@Test @Ignore
	public void insertUser() {
		UserVO user = new UserVO("test","테스트","여","오산");
		int nCount = dao.insertUser(user);
		Assert.assertEquals(1, nCount);
		
		System.out.println(user);
	}
	
	
	@Test @Ignore
	public void selectList() {
		List<UserVO> userList = dao.getUsers();
		for (UserVO userVO : userList) {
			System.out.println(userVO);
		}
	}
	
	
	@Test @Ignore
	public void selectOne() {
		UserVO user = dao.getUser("gildong");
		System.out.println(user);
	}
	
	
	

	
}

 

 

 

 

 

 

 

 

반응형