MyBatis

์ฝ”์ฝ”ยท2020๋…„ 8์›” 21์ผ
1

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
4/15

๐Ÿ’ฃ ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค๋Š” ๋ฌด์—‡์ธ๊ฐ€?

๋งˆ์ด๋ฐ”ํ‹ฐ์Šค๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง€์ •ํ•œ SQL, ์ €์žฅํ”„๋กœ์‹œ์ € ๊ทธ๋ฆฌ๊ณ  ๋ช‡๊ฐ€์ง€ ๊ณ ๊ธ‰ ๋งคํ•‘์„ ์ง€์›ํ•˜๋Š” ํผ์‹œ์Šคํ„ด์Šค ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค. ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค๋Š” JDBC๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์ƒ๋‹น๋ถ€๋ถ„์˜ ์ฝ”๋“œ์™€ ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ •๋ฐ ๊ฒฐ๊ณผ ๋งคํ•‘์„ ๋Œ€์‹ ํ•ด์ค€๋‹ค. ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ ˆ์ฝ”๋“œ์— ์›์‹œํƒ€์ž…๊ณผ Map ์ธํ„ฐํŽ˜์ด์Šค ๊ทธ๋ฆฌ๊ณ  ์ž๋ฐ” POJO ๋ฅผ ์„ค์ •ํ•ด์„œ ๋งคํ•‘ํ•˜๊ธฐ ์œ„ํ•ด XML๊ณผ ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
์ถœ์ฒ˜

ํผ์‹œ์Šคํ„ดํŠธ?

๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ„๋‹ค. ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค๋ฃจ๋Š” ๋ฐ์ดํ„ฐ๋“ค์€ ๊ฐ์ฒด๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด ํ•จ๊ป˜ ์‚ฌ๋ผ์ง„๋‹ค. ์ด๋ ‡๊ฒŒ ์ผํšŒ์šฉ์œผ๋กœ ๋ฒ„๋ ค์ง€๋Š” ๋ฐ์ดํ„ฐ๋“ค์„ ์œ ์ง€ํ•˜๋ ค๋ฉด, ๊ฐ์ฒด๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ์ „์— ์–ด๋”˜๊ฐ€์— ์ €์žฅํ•ด๋‘์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋‚˜์ค‘์— ๊ฐ์ฒด๊ฐ€ ๋‹ค์‹œ ์ƒ์„ฑ๋˜์—ˆ์„ ๋•Œ ์ด์ „์— ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐ์ดํ„ฐ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด, ๊ฐ์ฒด๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ์ „์˜ ์ƒํƒœ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฐ ์†์„ฑ์„ '์˜์†์„ฑpersistence'๋ผ๊ณ  ํ•œ๋‹ค.

JDBC | MyBatis ๋น„๊ต

  • JDBC

    • ์ง์ ‘ Connection์„ ๋งบ๋Š”๋‹ค.(DriveManager.getConnection(......))
    • ์ง์ ‘ ๋‹ซ๋Š”๋‹ค. (close())
    • PreparedStatement๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ณ  ์ž…๋ ฅํ•œ๋‹ค.
    • ResultSet์œผ๋กœ ์ง์ ‘ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์•ผ ํ•˜๋Š” ๊ท€์ฐฎ์Œ.

  • MyBatis

    • ์ž๋™์œผ๋กœ Connection๋งŒ๋“ค๊ณ  ์•Œ์•„์„œ ๋‹ซ๋Š”๋‹ค.close()
    • #{์†์„ฑ}๋งŒ ์ง€์ •ํ•˜๋ฉด ์•Œ์•„์„œ PreparedStatment ๋งŒ๋“ค๊ณ  ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • ๋ฆฌํ„ด ํƒ€์ž…์„ ์ง€์ •ํ•˜๋ฉด ResultSet๋งŒ๋“ค์–ด์„œ ํ•˜๋˜ ์ผ ์•Œ์•„์„œ ํ•œ๋‹ค.

MyBatis์—ฐ๋™ํ•ด์„œ TimeMapper ๋งŒ๋“ค๊ธฐ

pom.xml์— ์ถ”๊ฐ€

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.5</version>
</dependency>
		
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis-spring</artifactId>
	<version>2.0.5</version>
</dependency>
		
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
	<version>5.2.6.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>5.2.6.RELEASE</version>
</dependency>

MyBatis์—์„œ ๊ฐ€์žฅ ํ•ต์‹ฌ ๊ฐ์ฒด๋Š” SQLSessionFactory๊ฐ€ ๋งŒ๋“œ๋Š” SQLSession์ด๋‹ค. SQLSession์€ Connection์„ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์›ํ•˜๋Š” SQL์„ ์šด๋ฐ˜ํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.

์„ค์ •

@Configuration
@ComponentScan(basePackages = {"com.coco.controller"})
@MapperScan(basePackages = {"com.coco.mapper"})
public class RootConfig {
	
	@Bean
	public DataSource dataSource() {
		HikariConfig config = new HikariConfig();
		
		config.setDriverClassName("com.mysql.cj.jdbc.Driver");
		config.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/springex?serverTimezone=Asia/Seoul");
		config.setUsername("springuser");
		config.setPassword("springuser");
		config.addDataSourceProperty("cachePrepStmts", "true");
		config.addDataSourceProperty("prepStmtCacheSize", "250");
		config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

		HikariDataSource ds = new HikariDataSource(config);
		
		return ds;
	}
	

	@Bean
	public SqlSessionFactory sqlSessionFactory() throws Exception {
		SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
		sqlSessionFactory.setDataSource(dataSource());
		return sqlSessionFactory.getObject();
	}
}

์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๋ฉด ์—ฐ๊ฒฐ ๋!
ํ…Œ์ŠคํŠธ๋Š” ์•Œ์•„์„œ..

๊ทธ ๋‹ค์Œ Mapper๋ฅผ ๋งŒ๋“ ๋‹ค. Mapper๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์„ ์–ธํ•œ๋‹ค.

public interface TimeMapper {
	@Select("SELECT now()")
	public String getTime();
}

์ด๋ ‡๊ฒŒ @Select์•ˆ์— ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
ํ…Œ์ŠคํŠธ๋„ ๊ฐ„๋‹จํ•˜๋‹ค.

@Autowired
TimeMapper mapper;
	
@Test
public void getTime() {
	assertNotNull(mapper);
	log.info(mapper);
	log.info(mapper.getClass().getName());
	log.info(mapper.getTime());
}

ํด๋ž˜์Šค๋Š” ์—†๊ณ  ์ธํ„ฐํŽ˜์ด์Šค๋ฐ–์— ์—†๋Š”๋ฐ๋„ ํ…Œ์ŠคํŠธ๋Š” ์„ฑ๊ณตํ•œ๋‹ค.

INFO : com.coco.mapper.TimeMapperTest - org.apache.ibatis.binding.MapperProxy@3243b914
INFO : com.coco.mapper.TimeMapperTest - com.sun.proxy.$Proxy29 <--์ต๋ช… ํด๋ž˜์Šค
INFO : com.coco.mapper.TimeMapperTest - 2020-08-21 18:08:47

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ ์ ˆํ•œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฃผ์ž…ํ•œ ๊ฒƒ์ด๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€