티스토리 뷰
| MyBatis Setting
Mybatis 세팅을 해보자 !_!
여기서는 Spring-MyBatis 연동이 아닌 순수 MyBatis만 사용할 것이다.
순수 MyBatis가 아닌 mybatis-spring 세팅을 원한다면
아래 글로 GoGo !!
[Spring-myBatis] Spring-myBatis 프로젝트를 만들어보자 !
|| MyBatis
MyBatis는 Java Object와 SQL문 사이의 자동 Mapping 기능을 지원하는
ORM(Object Relational Mapping) Framework
- MyBatis는 SQL을 별도의 파일로 분리해서 관리
- Object와 SQL 사이의 parameter mapping 작업을 자동으로 해줌
순수 MyBatis 세팅을 위해
다운로드와 Documentation은 아래 링크를 참고하자!
pdf Documentation Link
http://me2py.kldp.net/fwko/release/3410-MyBatis-3-User-Guide_ko.pdf
|| 설정 파일 수정
||| mybatis-config.xml
/src/main/resources/mybatis-config.xml
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 | <?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> <!-- 내부에서 사용하려는 변수가 있는 파일 지정 : ${name}으로 참조 --> <properties resource="dbinfo.properties"/> <!-- 사용하려는 DTO에 대한 축약 이름 --> <typeAliases> <typeAlias type="com.cristoval.web.model.dto.Product" alias="product" /> </typeAliases> <!-- connection pool --> <!-- 보안, 유지보수 차원에서 정보를 빼내서 사용 --> <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="${dbid}"/> <property name="password" value="${dbpwd}"/> </dataSource> </environment> </environments> <!-- 사용할 쿼리에 대한 등록 --> <mappers> <mapper resource="product.xml" /> </mappers> </configuration> | cs |
||| dbinfo.properties
/src/main/resources/mybatis-config.xml 파일의
line 7에 지정된 파일이다.
Database 정보가 저장되어있다.
/src/main/resources/dbinfo.properties
1 2 3 4 | driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:0000/databaseName?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8 dbid=userId dbpwd=userPw | cs |
||| product.xml
Mapper 준비
namespace는 package명 + classname 으로 작성해준다.
/src/main/resources/product.xml
1 2 3 4 5 6 7 | <?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"> <!-- namespace : package + classname --> <mapper namespace="com.cristoval.web.model.repo.ProdRepository"> </mapper> | cs |
|| 필요한 라이브러리 준비
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.3</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> |
mysql-connector-java
mybatis
commons-dbcp
라이브러리가 필요하다.
|| MybatisUtil
src/main/java/com/cristoval/web/util/MyBatisUtil.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 | package com.cristoval.web.util; import java.io.IOException; import java.io.InputStream; 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 org.springframework.stereotype.Component; @Component public class MyBatisUtil { private SqlSessionFactory factory; // 설정 파일에 대한 로딩 필요 public MyBatisUtil() { try (InputStream input = Resources.getResourceAsStream("mybatis-config.xml")) { factory = new SqlSessionFactoryBuilder().build(input); } catch (IOException e) { e.printStackTrace(); } } public SqlSession getSession() { // boolean autoCommit return factory.openSession(true); } } | cs |
openSession(true) 를 해주어야 autoCommit 이 작동한다.
sql exception 발생 시 rollback 처리를 해주어야하는게 아닌가 했는데,
mybatis에서 알아서 sql exception 발생 시 rollback 처리를 해준다고 한다...
엄청나게 착한 framework 다 T_T
//
MyBatisUtil.java 를 @Component Bean으로 등록하였으니
백엔드를 관리하는 ApplicationConfig에
com.cristoval.web.util 에서도 Bean을 스캔해달라고 명시를 해주어야 한다.
src/main/java/com/cristoval/web/config/ApplicationConfig.java
1 2 3 4 5 6 7 8 9 10 | package com.cristoval.web.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan({"com.cristoval.web.model", "com.cristoval.web.util"}) public class ApplicationConfig { } | cs |
//
Bean이 잘 등록되었는지 Client 단에서 확인해볼 수 있다.
src/main/java/com/cristoval/web/client/Client.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.cristoval.web.client; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.cristoval.web.config.ApplicationConfig; public class Client { public static void main(String[] args) { // 스프링에게 메타 정보 파일을 넘겨준다. // Spring container = ApplicationContext ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class); // Bean 테스트 String[] beans = ctx.getBeanDefinitionNames(); for(String bean : beans) { System.out.println(bean); } System.out.println("bean 개수" + beans.length); } } | cs |
결과 화면
...
applicationConfig
prodRepoImpl
myBatisUtil
//
MyBatisUtil을 만들어 Bean으로 등록하고
ProdReopImpl에서는 @Autowired annotation을 사용해서
MyBatisUtil 객체를 얻어올 수 있다.
src/main/java/com/cristoval/web/model/repo/ProdRepoImpl.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 | package com.cristoval.web.model.repo; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.cristoval.web.model.dto.Product; import com.cristoval.web.util.MyBatisUtil; @Repository public class ProdRepoImpl implements ProdRepository { private static final Logger logger = LoggerFactory.getLogger(ProdRepoImpl.class); @Autowired MyBatisUtil util; @Override public int insert(Product info) { logger.debug("userinfo: {}", info); return 0; } // ... } | cs |
|| Mapper에 쿼리 작성
이제 Mapper에 사용할 쿼리를 작성해주면 된다.
사용할 쿼리에 맞는 tag를 사용해주면 된다.
/src/main/resources/product.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 mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace : package + classname --> <mapper namespace="com.cristoval.web.model.repo.ProdRepository"> <select id="select" parameterType="string" resultType="product" > select * from product where id = #{id} </select> <select id="selectAll" resultType="product"> select * from product </select> <insert id="insert" parameterType="product"> insert into product values(#{id}, #{name}, #{price}, #{descript}); </insert> </mapper> | cs |
id 는 쿼리의 id
parameterType 은 말 그대로
resultType 도 말 그대로다.
자세한 설명은 상단 documentation을 확인해보는게 빠를듯 하다!
일부 내용은 아래와 같다.
Mapper에 쿼리를 작성했다면 이제 사용을 해봐야겠지!?
ProdRepoImpl에서 사용할 것이다.
@Autowired 로 얻어온 MyBatisUtil 에서 .getSesion()으로 세션을 얻고
사용할 쿼리에 맞는 Mathod를 선택해준다.
Test로 Select를 사용할 것인데 모든 데이터를 확인할 것이므로 List 형식으로 데이터가 return될 것이다.
그러므로 selectList() 메서드를 사용해보자.
메서드에는 statement, parameter를 포함해야한다.
selectAll은 parameter가 필요 없으므로 statement를 넣어주자.
1 2 3 4 5 | @Override public List<Product> selectAll() { logger.debug("select all"); return util.getSession().selectList(ns + "selectAll"); } | cs |
statement는 package+classname.QueryId 로 작성해야 한다.
"package+classname."는 자주 사용할 것이므로 미리 namespace 변수로 저장해두면 좋을 것 같다.
1 | private static String ns = "com.cristoval.web.model.repo.ProdRepository."; | cs |
src/main/java/com/cristoval/web/model/repo/ProdRepoImpl.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 | package com.cristoval.web.model.repo; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.cristoval.web.model.dto.Product; import com.cristoval.web.util.MyBatisUtil; @Repository public class ProdRepoImpl implements ProdRepository { private static String ns = "com.cristoval.web.model.repo.ProdRepository."; private static final Logger logger = LoggerFactory.getLogger(ProdRepoImpl.class); @Autowired MyBatisUtil util; @Override public int insert(Product info) { logger.debug("userinfo: {}", info); return util.getSession().insert(ns + "insert", info); } // ... @Override public List<Product> selectAll() { logger.debug("select all"); return util.getSession().selectList(ns + "selectAll"); } } | cs |
Mybatis가 잘 세팅되었는지 Client 단에서 확인해볼 수 있다.
src/main/java/com/cristoval/web/client/Client.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.cristoval.web.client; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.cristoval.web.config.ApplicationConfig; import com.cristoval.web.model.repo.ProdRepository; import com.cristoval.web.util.MyBatisUtil; public class Client { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class); System.out.println(ctx.getBean(MyBatisUtil.class).getSession()); ProdRepository prodRepo = ctx.getBean(ProdRepository.class); System.out.println(prodRepo.selectAll()); } } | cs |
결과 화면
DEBUG: com.cristoval.web.model.repo.ProdRepoImpl - select all
DEBUG: com.cristoval.web.model.repo.ProdRepository.selectAll - ==> Preparing: select * from product
DEBUG: com.cristoval.web.model.repo.ProdRepository.selectAll - ==> Parameters:
TRACE: com.cristoval.web.model.repo.ProdRepository.selectAll - <== Columns: id, name, price, descript
TRACE: com.cristoval.web.model.repo.ProdRepository.selectAll - <== Row: 001, 냉장고, 130000, 코끼리만한 냉장고
TRACE: com.cristoval.web.model.repo.ProdRepository.selectAll - <== Row: 002, 세탁기, 230000, 검은옷을 흰옷으로 만들어주는 세탁기
TRACE: com.cristoval.web.model.repo.ProdRepository.selectAll - <== Row: 003, 냉장고, 340000, 남극보다 추운 냉장고
DEBUG: com.cristoval.web.model.repo.ProdRepository.selectAll - <== Total: 3
log4j.xml 에서 아래와 같이 log level을 trace로 설정해서
위와 같은 log를 확인할 수 있다.
1 2 3 4 | <!-- Application Loggers --> <logger name="com.cristoval.web"> <level value="trace" /> </logger> | cs |
** 읽어보고 싶은 참고 글 **
[Spring-myBatis] Spring-myBatis 프로젝트를 만들어보자 !
'Web > Spring' 카테고리의 다른 글
[Spring] 단위 테스트(spring-test, JUnit) (0) | 2020.10.23 |
---|---|
[Spring-myBatis] Spring-myBatis 프로젝트를 만들어보자 ! (0) | 2020.10.23 |
[Spring] Spring@MVC 구조 및 @annotation 살펴보기. (0) | 2020.10.21 |
[Spring] Spring@MVC 프로젝트 세팅하기 (0) | 2020.10.21 |
[Spring] log4j.xml 로그 확인하기 (0) | 2020.10.21 |