Post

๐Ÿฅœ [Spring] MyBatis & Bean

Backend ์—์„œ DB ์— ์ ‘๊ทผํ•  ๋–„ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์ˆ ์ธ MyBatis ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

MyBatis ๋ž€?

image-31

๋นจ๊ฐ„์ƒ‰ ๋„ค๋ชจ ๋ถ€๋ถ„์ด MyBatis ๋™์ž‘ ์œ„์น˜

Component๋Š” Business Logic์„ ํ˜ธ์ถœ

Business Logic์„ Resources Factory์—์„œ Connection์„ ๋ฐ›์•„์„œ ์ˆ˜ํ–‰ํ•œ๋‹ค.

DAOImpl์˜ ์—ญํ• ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. connection ๋ฐ›๊ธฐ
  2. ์ฟผ๋ฆฌ๋ฌธ ์ž‘์„ฑ - PreparedStatement
  3. ๊ฐ’ ๋ฐ”์ธ๋”ฉ
  4. ์ฟผ๋ฆฌ๋ฌธ ์ˆ˜ํ–‰
  5. close

์œ„์˜ 5๊ฐ€์ง€ ์—ญํ• ์„ ํ”„๋ ˆ์ž„์›Œํฌ ํ˜•ํƒœ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ๋‹ค.

์ด๊ฒƒ์ด MyBatis Framework ์ด๋‹ค.

MyBatis Framework์˜ ์—ญํ• ์„ ํ•˜๋Š” ๋‹ค๋ฅธ Framework ๋„ ๋‹ค์–‘ํ•˜๊ฒŒ ์กด์žฌํ•œ๋‹ค.

Spring JDBC(์ผ๋ณธ์ด ๋งŽ์ด ์‚ฌ์šฉ), Hibernate(๋ฏธ๊ตญ), MyBatis(ํ•œ๊ตญ) ๋“ฑ

๊ตฌํ˜„๋ถ€์— ์žˆ์–ด์„œ ์ž‘์—…์˜ ํ๋ฆ„

1.ํ…Œ์ด๋ธ” ์„ธํŒ…

1
2
3
4
5
6
7
8
9
10
11
12
create table mysawon(
num number constraint mysawon_num_pk primary key,
id varchar2(20) constraint mysawon_id_nn not null,
pwd varchar2(20),
name varchar2(40),
age number(3),
hiredate date,
constraint mysawon_id_uq unique(id));

create sequence mysawon_seq
increment by 1
start with 1;

2.vo ์ž‘์„ฑ

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.service.mybatis.vo;

public class MySawon {
	private int num, age; //์ปฌ๋Ÿผ๋ช…๊ณผ ๋™์ผ
	private String id, pwd, name, hiredate; //์ปฌ๋Ÿผ๋ช…๊ณผ ๋™์ผ
	
	//Framework์—์„œ๋Š” ๋ฐ˜๋“œ์‹œ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ํ•„์š”...
	public MySawon() {}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getHiredate() {
		return hiredate;
	}

	public void setHiredate(String hiredate) {
		this.hiredate = hiredate;
	}

	@Override
	public String toString() {
		return "MySawon [num=" + num + ", age=" + age + ", id=" + id + ", pwd=" + pwd + ", name=" + name + ", hiredate="
				+ hiredate + "]";
	}
}

3.MyBatis Framework ์„ค์ •๋ฌธ์„œ๋ฅผ ๋“ฑ๋ก

dbconn.properties (DB ์„œ๋ฒ„ ์ •๋ณด)

1
2
3
4
5
### dbconn.properties file....dbServer Information Storing
jdbc.oracle.driver=oracle.jdbc.driver.OracleDriver
jdbc.oracle.url=jdbc:oracle:thin:@127.0.0.1:1521:XE
jdbc.oracle.username=dbid
jdbc.oracle.password=1234

sqlMapConfig.xml (MyBatis Framework์˜ ํ•ต์‹ฌ ๋ฌธ์„œ)

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
37
<?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">
<!-- 
MyBatis์˜ ํ•ต์‹ฌ์ด ๋˜๋Š” ์„ค์ •๋ฌธ์„œ๋กœ์„œ
1. db์„œ๋ฒ„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค...dbconn.properties ํŒŒ์ผ์— ์žˆ๊ธฐ์— Wiring๋˜์–ด์ง„๋‹ค.
2. DataSource์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋“ฑ๋ก
3. sql Query๋ฌธ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋“ฑ๋ก...mapper.xmlํŒŒ์ผ์— ์žˆ๊ธฐ์— Wiring ๋˜์–ด์ง„๋‹ค.
4. VO๋ฅผ ์—ฌ๊ธฐ๋‹ค ๋งคํ•‘์‹œํ‚จ๋‹ค..์•Œ๋ฆฌ์•ผ์Šค๋ฅผ ๊ธฐ์–ตํ•˜์ž!!
 -->
<configuration>
	<properties resource="config/dbconn.properties"/>
	
	<typeAliases><!--vo๋ฅผ ๋งคํ•‘  -->
		<typeAlias type="com.service.mybatis.vo.MySawon" alias="mySawon"/>
	</typeAliases>
	
	<environments default="AA">
		<environment id="AA">
			<transactionManager type="JDBC"/>
			<dataSource type="UNPOOLED">	<!--DriverManager ๋ฐฉ์‹ ๋งŒ์•ฝ pooled๋กœ ํ•˜๋ฉด ResourcesFactory ๋ฐฉ์‹์ด๋‹ค-->
				<!--setDriver();  -->
				<!-- value์—๋Š” dbconn.properties๋ฅผ ๋ณด๊ณ  key๊ฐ’์ด ๋“ค์–ด๊ฐ„๋‹ค -->
				<property name="driver" value="${jdbc.oracle.driver}"/>
				<property name="url" value="${jdbc.oracle.url}"/>
				<property name="username" value="${jdbc.oracle.username}"/>
				<property name="password" value="${jdbc.oracle.password}"/> 
			</dataSource>
		</environment>
	</environments>
	
	<!--sql ์ฟผ๋ฆฌ๋ฌธ ๋“ฑ๋ก๋œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ  --> mapper๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ์ถ”๊ฐ€ํ•ด์„œ ์ž‘์„ฑํ•ด์ค˜์•ผํ•จ
	<mappers>
		<mapper resource="mapper/mysawon-mapping.xml"/>
	</mappers>
</configuration>

4.mysawon-mapping.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--  config๋ฅผ ๋ชจ๋‘ mapper๋กœ ๋ฐ”๊ฟ”์•ผ ํ•จ -->
<?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="SawonMapper">
	<insert id="sawonAdd" parameterType="mySawon">
		INSERT
		INTO mysawon (num, id, pwd, name, age, hiredate)
		VALUES (mysawon_seq.nextVal, #{id},#{pwd},#{name},#{age},sysdate)
	</insert>
</mapper> 


image-31

SqlMapConfig.xml ์€ vo, mysawon.xml, dbconn.properties ์„ ๋ชจ๋‘ hasing, ๋ชจ๋“  ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

SqlSessionFactory ๊ฐ€ SqlMapConfig ์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ ๊ฐ„๋‹ค.

SqlSession ์€ SqlSessionFactory ์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ ๊ฐ„๋‹ค.

์ฆ‰, SqlMapConfig ๊ฐ€ DI ์„ SqlSessionFactory ์— ํ•ด์ฃผ๊ณ  SqlSessionFactory ๊ฐ€ DI ์„ SqlSession ์—

ํ•ด์ค€๋‹ค.

SqlSession ์€ DB ์™€ ์†Œํ†ตํ•œ๋‹ค.

insert(), delete(), update(), selectList(), selectOne() ๋“ฑ

MyBatis ์˜ Null ์ฒ˜๋ฆฌ

DB์— null ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋ฉด ํฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

1
2
3
4
//==> Test ์šฉ User instance ์ƒ์„ฑ ๋ฐ age / regData null setting
//==>@@@ null๊ฐ’์„ ํ—ˆ์šฉํ• ๋ ค๋ฉด SqlMapConfig01.xml์— Settings ํƒœ๊ทธ๋ฅผ ๋ถ€์ฐฉํ•ด์•ผํ•œ๋‹ค.@@@
User user = new User("user04","์ฃผ๋ชฝ","user04",null,1);
user.setRegDate(null);

์œ„์™€ ๊ฐ™์ด null ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Oracle ์€ null ๊ฐ’ ํ—ˆ์šฉ์ด ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ

๋”ฐ๋ผ์„œ MyBatis ์—์„œ null ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค.

SqlMapConfig01.xml ๋กœ ๋“ค์–ด๊ฐ€์„œ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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="config/dbconn.properties"/>
	
	<!--์˜ค๋ผํด์—์„œ๋Š” null ๊ฐ’์„ ํ—ˆ์šฉํ•˜๋Š” ์˜ต์…˜์„ ์ง€์ • :: MySqL์—์„œ๋Š” ์ด๋ถ€๋ถ„์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค.  -->
	<settings>
		<setting name="jdbcTypeForNull" value="NULL"/>
	</settings>
	
	<typeAliases> <!--vo๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ๋ฉด ์—ฌ๋Ÿฌ๊ฐœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. alias๋Š” ์†Œ๋ฌธ์ž๋กœ ์ค˜์•ผ ํ•œ๋‹ค  -->
		<!-- <typeAlias type="mybatis.services.domain.User" alias="user"/> -->
		<package name="mybatis.services.domain"/> <!-- ํŒจํ‚ค์ง€ ์•ˆ์— ๋“ค์–ด์žˆ๋Š” User๊ฐ€ user๋กœ alias ๋œ๋‹ค. -->
	</typeAliases>
	
</configuration>

Alias Skip

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 mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--์ด๊ฑฐ ์™„์„ฑํ•˜๋…„ CRUD ๋‹ค ํ•ด๋ณด๋Š” ๊ฒƒ์ž„  -->
<mapper namespace="UserMapper07">	
	
	<!-- AS ์•ˆ์“ฐ๊ธฐ ์œ„ํ•ด  -->
	<!--๊ฒฐ๊ณผ๋งต์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๋ฉด SELECT ํƒœ๊ทธ๋งˆ๋‹ค AS ์‚ฌ์šฉ ์•ˆํ•ด๋„ ๋œ๋‹ค.  -->
	<!--resultType ๋Œ€์‹ ์— resultMap์„ ์•ž์œผ๋กœ๋Š” ์‚ฌ์šฉํ•œ๋‹ค.  -->
	<resultMap type="user" id="userSelectMap">
		<result property="userId" column="user_id"/>
		<result property="userName" column="user_name"/>
		<result property="password" column="password"/>
		<result property="age" column="age"/>
		<result property="grade" column="grade"/>	
		<result property="regDate" column="reg_date"/>
	</resultMap>
	
	<!-- id๊ฐ€ user01์ธ ์‚ฌ๋žŒ์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ์ฟผ๋ฆฌ -->
	<select id="getUserList01" parameterType="user" resultMap="userSelectMap">
		SELECT
		user_id ,
		user_name ,
		password,
		age,
		grade,
		reg_date
		FROM users
		WHERE user_id=#{userId}
	</select>
	<!--๋งค๋ฒˆ AS ์“ฐ๋ฉด ๊ท€์ฐฎ  -->
	
</mapper>

MyBatis Dynamic SQL

์ƒ๋‹จ์˜ ์ฟผ๋ฆฌ๋Š” ์ •์ ์ธ ์ฟผ๋ฆฌ๋ผ Business Logic์ด ๋งŒ์•ฝ 100๊ฐœ๋ฉด 100๊ฐœ์˜ Query ๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์ข€ ๋” ๋™์ ์ธ ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜ 4๊ฐœ์˜ ์ฟผ๋ฆฌ๋ฅผ ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. userName์ด โ€œํ™๊ธธ๋™โ€ ์ด๊ณ  age=30 ์ธ ์‚ฌ๋žŒ์„ ๊ฒ€์ƒ‰
  2. userName๋งŒ โ€œํ™๊ธธ๋™โ€ ์ธ ์‚ฌ๋žŒ์„ ๊ฒ€์ƒ‰
  3. age=30 ์ธ ์‚ฌ๋žŒ ๊ฒ€์ƒ‰
  4. ๋ชจ๋“  ์‚ฌ๋žŒ์„ ๊ฒ€์ƒ‰
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<select id="getUserList" parameterType="user" resultMap="userSelectMap">
	 	SELECT
		user_id ,
		user_name ,
		password,
		age,
		grade,
		reg_date
		FROM users
		<where>
			<if test="userName != null">
				user_name LIKE #{userName}
			</if>

			<if test="age != null">
				OR age LIKE #{age}
			</if>
		</where>
		ORDER BY user_id DESC
</select>

์œ„์™€ ๊ฐ™์€ SQL ๊ตฌ๋ฌธ์„ ์ง ๋‹ค.

<where></where> ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด WHERE ์ ˆ์„ ๋‚˜๋ˆ  ์ฃผ์—ˆ๋‹ค.

๋‚˜๋ˆ ์ค„ ๋•Œ๋Š” <if></if> ๋ฅผ ์‚ฌ์šฉํ•ด ์กฐ๊ฑด๋ฌธ์„ ์‚ฌ์šฉํ•ด ์ฃผ์—ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
User user = new User("user01","ํ™๊ธธ๋™","user01",new Integer(30),1);

//์ด๋ฆ„์ด ํ™๊ธธ๋™์ด๊ณ  age=30์ธ 
(List)session.selectList("UserMapper08.getUserList",user);

//age=30์ธ ์‚ฌ๋žŒ์„ ๊ฒ€์ƒ‰
user.setUserName(null);
(List)session.selectList("UserMapper08.getUserList",user);

//์ด๋ฆ„์ด ํ™๊ธธ๋™์ธ ์‚ฌ๋žŒ์„ ๊ฒ€์ƒ‰
user.setUserName("ํ™๊ธธ๋™");
user.setAge(null);
(List)session.selectList("UserMapper08.getUserList",user);

//๋ชจ๋“  ์‚ฌ๋žŒ์„ ๊ฒ€์ƒ‰
user.setUserName(null);
user.setAge(null);
(List)session.selectList("UserMapper08.getUserList",user);

SQL ๊ตฌ๋ฌธ์˜ ๋ชจ๋“ˆํ™”

์ˆ˜๋งŽ์€ ์ฟผ๋ฆฌ ์ค‘์— ๊ณตํ†ต๋˜๋Š” ๋ถ€๋ถ„์„ ๋”ฐ๋กœ ๋ชจ๋“ˆํ™”๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<sql id="select-users">
		SELECT
		user_id ,
		user_name ,
		password,
		age,
		grade,
		reg_date
		FROM
		users
</sql>

<sql id="orderby-userid-desc">
		ORDER BY user_id DESC
</sql>

์œ„์™€ ๊ฐ™์ด <sql></sql> ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋ชจ๋“ˆํ™”๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

<sql> ์•ˆ์— id๋ฅผ ์„ค์ •ํ•ด ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<select id="getUser" parameterType="user" resultMap="userSelectMap">
		<include refid="select-users" />
		WHERE password=#{password}
</select>

<select id="getUserList" parameterType="user" resultMap="userSelectMap">
		<include refid="select-users"></include>
		<where>
			<if test="userName != null">
				user_name LIKE #{userName}
			</if>

			<if test="age != null">
				OR age LIKE #{age}
			</if>
		</where>
		<include refid="orderby-userid-desc"></include>
</select>

<include> ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ด refid ์˜ ์†์„ฑ๊ฐ’์„ sql ํƒœ๊ทธ์˜ id๊ฐ’ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

image-33

MyBatis ์—์„œ ๊ฐ€์žฅ ํ•ต์‹ฌ๋ฌธ๋Š” SqlMapConfig.xml ์ด๋‹ค.

์ด ๋ฌธ์„œ๋Š” SqlSessionFactory ๊ฐ€ ๋จน๊ณ ,

SqlSessionFactory ๋Š” SqlSession ์ด ๋จน๊ฒŒ ๋œ๋‹ค.

MyBatis ์—๋Š” SqlSession ์ด ์ตœ์ƒ์œ„์ง€๋งŒ

์ด๊ฒƒ์„ WAS ์— ๋„˜๊ฒจ์•ผ ํ•œ๋‹ค.

๋ฐ›๋Š” ๊ฒƒ์€ Business Logic Layer์—์„œ DAOImpl ์ด ๋จน๊ฒŒ ๋œ๋‹ค.

DAO ์ธํ„ฐํŽ˜์ด์Šค์—๋Š” 5๊ฐœ์˜ ํ…œํ”Œ๋ฆฟ์ด ๋งŒ๋“ค์–ด ์ ธ์•ผ ํ•œ๋‹ค.

mybatis-userservice-mapping ์—์„œ ์ฟผ๋ฆฌ๋ฅผ 5๊ฐœ ์งฐ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋˜ํ•œ DAO ์ธํ…ŒํŽ˜์ด์Šค ํ…œํ”Œ๋ฆฟ ์ด๋ฆ„์€ ๊ฐ๊ฐ ์ฟผ๋ฆฌ 5๊ฐœ์˜ id๋กœ ํ•ด์•ผํ•œ๋‹ค.

์ฆ‰, ๋ชจ๋“  ๊ฒƒ์€ ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•œ๋‹ค.

๋จผ์ € mybatis-userservice-mapping10.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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?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">

<!--์ด๊ฑฐ ์™„์„ฑํ•˜๋…„ CRUD ๋‹ค ํ•ด๋ณด๋Š” ๊ฒƒ์ž„ -->
<mapper namespace="UserMapper10">

	<resultMap type="user" id="userSelectMap">
		<result property="userId" column="user_id" />
		<result property="userName" column="user_name" />
		<result property="password" column="password" />
		<result property="age" column="age" />
		<result property="grade" column="grade" />
		<result property="regDate" column="reg_date" />
	</resultMap>

	<sql id="select-users">
		SELECT
		user_id ,
		user_name ,
		password,
		age,
		grade,
		reg_date
		FROM
		users
	</sql>

	<sql id="orderby-userid-desc">
		ORDER BY user_id DESC
	</sql>


	<select id="getUser" parameterType="user" resultMap="userSelectMap">
		<include refid="select-users" />
		WHERE password=#{password}
	</select>

	<select id="getUserList" parameterType="user" resultMap="userSelectMap">
		<include refid="select-users"></include>
		<where>
			<if test="userName != null">
				user_name LIKE #{userName}
			</if>
			<if test="age != null">
				OR age LIKE #{age}
			</if>
		</where>
		<include refid="orderby-userid-desc"></include>
	</select>
	
	<insert id="addUser" parameterType="user">
		INSERT
		INTO users(user_id, user_name, password, age, grade, reg_date)
		VALUES(
			#{userId}, #{userName}, #{password},#{age},#{grade},#{regDate}
		)
	</insert>
	
	<update id="updateUser" parameterType="user">
		UPDATE users
		SET user_name=#{userName}
		WHERE user_id=#{userId}
	</update>
	
	<delete id="removeUser" parameterType="string">
		DELETE
		users
		WHERE user_id=#{VALUE}
	</delete>
</mapper>

์ฟผ๋ฆฌ์˜ parameterType ๊ณผ id , resultMap ์˜ type์„ ์ž˜ ์‚ดํŽด๋ณด์ž.

์ด ์ฟผ๋ฆฌ๋กœ ๋งŒ๋“ค์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์ œ WAS์˜ DAO๊ฐ€ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

์ฟผ๋ฆฌ๋ฌธ tag id ๊ฐ’์ด Template ๊ธฐ๋Šฅ์˜ ์ด๋ฆ„์ด ๋œ๋‹ค.

์ฟผ๋ฆฌ๋ฌธ tag parameterType์ด Template ๊ธฐ๋Šฅ์˜ ์ธ์ž ๊ฐ’

์ฟผ๋ฆฌ๋ฌธ tag resultMap, resultType์˜ ๊ฐ’์ด Template๊ธฐ๋Šฅ์˜ return type๊ณผ ์—ฐ๊ฒฐ

1
2
3
4
5
6
7
public interface UserDAO {
	int addUser(User user)throws Exception;
	int updateUser(User user)throws Exception;
	int removeUser(String userId)throws Exception;
	User getUser(String userId)throws Exception;
	List<User> getUserList(User user)throws Exception;
}

์ด์ œ ์ด interface๋ฅผ ๊ตฌํ˜„ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

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
37
38
39
40
41
public class MyBatisUserDAOImpl10 implements UserDAO{
	private SqlSession sqlSession;
	public static final String MAPPER_NAME="UserMapper10.";
	
	//DI... ์™„์„ฑ
	public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
		System.out.println("::" + getClass().getName() + ".setSqlSession()...");
	}

	@Override
	public int addUser(User user) throws Exception {
		int result = sqlSession.insert(MAPPER_NAME + "addUser", user);
		sqlSession.commit();
		return result;
	}

	@Override
	public int updateUser(User user) throws Exception {
		int result = sqlSession.update(MAPPER_NAME+"updateUser", user);
		sqlSession.commit();
		return result;
	}

	@Override
	public int removeUser(String userId) throws Exception {
		int result = sqlSession.delete(MAPPER_NAME+"removeUser", userId);
		sqlSession.commit();
		return result;
	}

	@Override
	public User getUser(String userId) throws Exception {
		return sqlSession.selectOne(MAPPER_NAME+"getUser", userId);
	}

	@Override
	public List<User> getUserList(User user) throws Exception {
		return sqlSession.selectList(MAPPER_NAME+"getUserList",user);
	}
}

DAO๋Š” SqlSession์œผ๋กœ ๋ถ€ํ„ฐ DI ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

1
2
3
4
5
6
7
private SqlSession sqlSession;

//DI... ์™„์„ฑ
public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
		System.out.println("::" + getClass().getName() + ".setSqlSession()...");
}

setSqlSession() ์„ ํ†ตํ•ด sqlSession ์„ ์–ป๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ• ๊นŒ? ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

1
2
3
4
5
6
7
8
9
10
SqlSession session = null;
//==> TestUtil ์˜ getSqlSessionFactory()์„ ์ด์šฉ SqlSessionFactory instance GET
SqlSessionFactory factory = TestUtil.getSqlSessionFactory();
session=factory.openSession();

MyBatisUserDAOImpl10 dao = new MyBatisUserDAOImpl10();
dao.setSqlSession(session); //DI ์ฃผ์ž…!!!!!!!!!!!!!!!!!!!!!!!!!

User user = new User("user04","์ฃผ๋ชฝ","user04",null,1);
dao.addUser(user)

์ด๋Ÿฐ ์‹์œผ๋กœ DI ๋ฅผ ํ†ตํ•ด ๋ฐ›์•„์˜จ SqlSession ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.



Business Logic Layer ๋ถ„๋ฆฌ

image-34

ํ˜„์—…์—์„œ๋Š” Business Ligic Layser๋ฅผ ๋‘˜๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.

Service Layer ์™€ Persistence Layer ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.

Persistence Layer์—์„œ DB์˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๊ณ 

Service Layer์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณต ํ•˜๋Š” ๊ฒƒ

์˜ˆ๋ฅผ ๋“ค์–ด 1000๊ฐœ์˜ column์„ Persistence Layer์—์„œ ๊ฐ€์ ธ์˜ค๋ฉด

ํ•œ ํ™”๋ฉด์— ๋‚˜์˜ค๋ฉด ๋„ˆ๋ฌด ๋งŽ์œผ๋‹ˆ๊นŒ Service Layer์—์„œ 10๊ฐœ์”ฉ ํŽ˜์ด์ง€์— ๋ณด์ด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค

image-35

๋จผ์ € Service Layer๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์ž

1
2
3
4
5
6
7
8
9
10
11
12
package mybatis.services.user;

import java.util.List;

import mybatis.services.domain.User;

public interface UserService {
	void addUser(User user)throws Exception;
	void updateUser(User user)throws Exception;
	User getUser(String userId)throws Exception;
	List<User> getUserList(User user)throws Exception;
}

DAO ์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜๋‹ค

์ˆ˜์ •๋œ ์ ์ด remove ์ฟผ๋ฆฌ๊ฐ€ ๋น ์กŒ๋‹ค.

์™œ๋ƒํ•˜๋ฉด Service Layer ์—์„œ๋Š” ๊ตณ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•  ์ด์œ ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€๊ณตํ•˜๋ฉด ๋œ๋‹ค.

๋˜ํ•œ addUser() ์™€ updateUser() ์˜ return ํƒ€์ž…์ด void๋กœ ๋ฐ”๊พธ์—ˆ๋‹ค.

๊ตณ์ด ์ฟผ๋ฆฌ๊ฐ€ ์ œ๋Œ€๋กœ ๋Œ์•„๊ฐ”๋Š”์ง€ ํ™•์ธํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒƒ์ด๋‹ค.

์œ„ interface๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ์ž.

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
public class MyBatisUserServiceImpl11 implements UserService{
	
	private UserDAO userDAO;

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
		System.out.println("::" +getClass().getName() + "sqlSesseion()");
	}

	@Override
	public void addUser(User user) throws Exception {
		userDAO.addUser(user);
	}

	@Override
	public void updateUser(User user) throws Exception {
		userDAO.updateUser(user);
	}

	@Override
	public User getUser(String userId) throws Exception {
		return userDAO.getUser(userId);
	}

	@Override
	public List<User> getUserList(User user) throws Exception {
		return userDAO.getUserList(user);
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SqlSession session = null;
//==> TestUtil ์˜ getSqlSessionFactory()์„ ์ด์šฉ SqlSessionFactory instance GET
SqlSessionFactory factory = TestUtil.getSqlSessionFactory();
session=factory.openSession();

//==> MyBatisUserDAOImpl10 ์ƒ์„ฑ ๋ฐ SqlSession ๊ฐ์ฒด setter injection
MyBatisUserDAOImpl10 dao = new MyBatisUserDAOImpl10();
dao.setSqlSession(session);

//==> IBatisUserServiceImpl11 ์ƒ์„ฑ ๋ฐ IBatisUserDAOImpl10 ๊ฐ์ฒด setter injection
MyBatisUserServiceImpl11 userService = new  MyBatisUserServiceImpl11();
userService.setUserDAO(dao);

User user = new User("user04","์ฃผ๋ชฝ","user04",null,1);

userService.addUser(user);

DAO์— SqlSession์„ ๋ฐ›๊ณ  ๊ทธ๊ฒƒ์„ ๋‹ค์‹œ Service์— ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

DI Bean ์—ฐ๊ฒฐ

image-36

5๊ฐœ์˜ bean์„ ๋งŒ๋“ ๋‹ค.

์‚ฌ์‹ค SqlSessionFactory ๊ฐ€ SqlMapConfig ๋งŒ ๊ฐ€์ ธ๊ฐ€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. DataSourceFactory ์˜ Connection ์„

๋ฐ›์•„์˜จ๋‹ค. ๋”ฐ๋ผ์„œ Connection ์„ ๋ณด๊ด€ํ•˜๋Š” Factory Bean, Connection ๊ณผ SqlMapConfig ์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ๊ฐˆ

SqlSessionFactory Bean, ์ด๊ฒƒ์„ ๋ชจ๋‘ ๊ฐ€์ ธ๊ฐˆ SqlSession Bean, SqlSession์˜ ์ •๋ณด๋ฅผ ๋ฐ›์„

MyBatisUserDAOImpl Bean, ์ด๊ฒƒ์„ ๋ชจ๋‘ ๊ฐ€์ ธ๊ฐ€๋Š” UserServiceImpl Bean ๋”ฐ๋ผ์„œ ์ด 5๊ฐœ์ด๋‹ค.

์ด์ œ bean ์„ ๋“ฑ๋กํ•  ์„ค์ • ๋ฌธ์„œ ๋งŒ๋“ ๋‹ค.

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
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
        
<!--      
1. DataSource ๋นˆ ์ •์˜ :: API Bean
2. SqlSessionFactory ๋นˆ ์ •์˜ :: API Bean
3. SqlSession ๋นˆ ์ •์˜ :: API Bean
4. UserDAOImpl ๋นˆ ์ •์˜ :: User Definition Bean
5. UserServiceImpl ๋นˆ ์ •์˜ :: User Definition Bean   
-->
<context:property-placeholder location="classpath:config/dbconn.properties"/>

<!--MyBatis Framework API Bean  -->
DataSource Bean(Factory Bean)
<bean id = "dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	<property name="driverClassName" value="${jdbc.oracle.driver}"/>
	<property name="url" value="${jdbc.oracle.url}"/>
	<property name="username" value="${jdbc.oracle.username}"/>
	<property name="password" value="${jdbc.oracle.password}"/>
</bean>

SqlSessionFactory Bean
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="configLocation" value="config/SqlMapConfig01.xml"/>
	<property name="dataSource" ref="dataSource"/>
</bean>

SqlSession Bean
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
	<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
</bean>


<!--User Definition Bean  -->
UserDAOImpl Bean
<bean  id="myBatisUserDAOImpl12" class="mybatis.services.user.impl.MyBatisUserDAOImpl12">
	<property name="sqlSession" ref="sqlSessionTemplate"/>
</bean>

UserServiceImpl Bean
<bean id="myBatisUserServiceImpl12" class="mybatis.services.user.impl.MyBatisUserServiceImpl12">
	<property name="userDAO" ref="myBatisUserDAOImpl12"/>
</bean>
  
</beans>

์ž˜ ๋ณด๋ฉด ref ๋กœ ์„œ๋กœ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋งˆ์ง€๋ง‰ bean๋งŒ ๊ฐ€์ ธ์˜ค๋ฉด ๋ชจ๋‘ ์—ฎ์—ฌ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

์ด์ œ ๋นˆ์„ ํ™œ์šฉํ•  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

1
2
3
4
5
ApplicationContext context =new ClassPathXmlApplicationContext(new String[] {"/bean/userservice12.xml"});
UserService userService = (UserService)context.getBean("myBatisUserServiceImpl12");

User user = new User("user04","์ฃผ๋ชฝ","user04",40,40);
userService.addUser(user);

getBean() ์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ธ์ž๋กœ myBatisUserServiceImpl12 ๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค.

์ค‘์š”ํ•œ์ ์€ ์ฒซ๋ฒˆ์งธ ๊ธ€์ž๊ฐ€ ์†Œ๋ฌธ์ž๋กœ ๋“ค์–ด๊ฐ„๋‹ค. MyBatisUserServiceImpl12 ๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด๋‹ค.

๋‹น์—ฐํ•œ๊ฒƒ์ด bean์ฃผ๋ฌธ์„œ id๊ฐ€ myBatisUserServiceImpl12๊ฐ€ ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋‚˜์ค‘์— ๋ฐฐ์šธ @Autowired ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™์ ์œผ๋กœ ์†Œ๋ฌธ์ž๋กœ ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.

๋ฒˆ์™ธ๋กœ Bean์„ ํ™œ์šฉํ•˜๋ฉด Sql์—์„œ Commit() ์„ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ž๋™์ ์œผ๋กœ ํ•ด์ค€๋‹ค.

๋”ฐ๋ผ์„œ DAOImpl์—์„œ sqlSession.commit() ์„ ์ฃผ์„ ์ฒ˜๋ฆฌํ•ด์ค˜์•ผ ํ•œ๋‹ค.

Annotation ์„ ํ™œ์šฉํ•œ Bean ์—ฐ๊ฒฐ

image-37

Annotation ์€ bean ์ฃผ๋ฌธ์„œ๋ฅผ ์ถ•์•ฝํ•˜๋‚˜ ๊ฒƒ์ด๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์œ„์—์„œ ๋ดค๋˜ bean ์ฃผ๋ฌธ์„œ์— <bean></bean> ์„ @Component ๋ฅผ ์‚ฌ์šฉํ•ด ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
@Component
public class MyBatisUserDAOImpl13 implements UserDAO{
	...
}

@Component
public class MyBatisUserServiceImpl13 implements UserService{
	...
}

์‚ฌ์‹ค Service Layer์™€ Persistence Layer ๋ชจ๋‘ @Component ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ „๋ฌธ๊ฐ€๋“ค์€ @Component ์ž˜ ์•ˆ์“ด๋‹ค.

PersistenceLayer์—๋Š” @Repository

ServiceLayer์—๋Š” @Service

๊ทธ ๋‹ค์Œ ํ•„๋“œ๊ฐ’ ์„ ์–ธ ๋งจ ์œ„์— @Autowired๋ฅผ ์‚ฌ์šฉํ•ด bean์„ ์„œ๋กœ ์—ฎ๋Š”๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Repository
public class MyBatisUserDAOImpl13 implements UserDAO{
	
	@Autowired //setterํ•  ํ•„์š”์—†์Œ
	private SqlSession sqlSession;
	...
}

@Service
public class MyBatisUserServiceImpl13 implements UserService{
	
	@Autowired
	private UserDAO userDAO;
	...
}

์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด ์œ„์—์„œ ๋ดค๋˜ bean ์ฃผ๋ฌธ์„œ์—์„œ User Definition Bean์„ ๋ชจ๋‘ ์ง€์›Œ๋„ ๋œ๋‹ค.!!

Annotation์„ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
       
<context:property-placeholder location="classpath:config/dbconn.properties"/>

<!--MyBatis Framework API Bean  -->
<bean id = "dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	<property name="driverClassName" value="${jdbc.oracle.driver}"/>
	<property name="url" value="${jdbc.oracle.url}"/>
	<property name="username" value="${jdbc.oracle.username}"/>
	<property name="password" value="${jdbc.oracle.password}"/>
</bean>

<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="configLocation" value="config/SqlMapConfig01.xml"/>
	<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
	<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
</bean>

<!-- DI์—๊ฒŒ base-package ํ•˜์œ„๋ฅผ ๊ผญ ๋ด๋ผ๊ณ  ์•Œ๋ ค์ค€๋‹ค. -->
<context:component-scan base-package="mybatis.services.user.impl"></context:component-scan>
  
</beans>

๋งˆ์ง€๋ง‰์œผ๋กœ <context:component-scan> ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์œ„์—์„œ Annotation์„ ์ž‘์„ฑํ•œ ๋ฌธ์„œ๊ฐ€ ์œ„์น˜ํ•œ package ๋ช…์„ base-package ์˜ ๊ฐ’์œผ๋กœ ๋„ฃ์–ด์ค€๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด Spring์€ ์œ„์น˜๋ฅผ ๋ณด๊ณ  Annotation ์„ ์–ธ๋œ ํด๋ž˜์Šค๋ฅผ bean์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

This post is licensed under CC BY 4.0 by the author.