티스토리 뷰

반응형



| 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은 아래 링크를 참고하자!

https://blog.mybatis.org/


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>

cs



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





** 읽어보고 싶은 참고 글 **


반응형
댓글
최근에 올라온 글
최근에 달린 댓글
링크
Total
Today
Yesterday