Programming/Spring

Spring(11) - Spring & Mybatis 실습1 : Spring과 Mybatis 연결하기

코딩하는 포메라니안 2022. 5. 7. 16:44

이제 Spring과 MyBatis를 연결시켜보겠다.

 

1. MyBatis에서 사용하는 객체 Spring에 등록하기

이제 SqlSessionFactory와 SqlSession을 Spring Container가 관리하도록 하자.

 

 

1. SqlSessionFactory 등록하기

원래, SqlMapConfig라는 java파일을 만들어서 SqlSessionFactory를 만들고 SqlSession을 만들어내도록 했다.

이제는 Spring에서 그 일을 알아서 하도록 한다.

이 작업이 끝나면, mybatis-config.xml과 dbInfo.properties파일은 삭제해도 된다.

 

SqlSessionFactory에는 대략 3가지 정보가 들어갔었다.

1) DB정보

2) mapper의 위치

3) alias(별칭) 정보

 

먼저 DB정보를 등록하기 위해, Spring에 DB Pool로 객체를 등록해주었다.

관련 내용은 2022.04.25 - [웹프로그래밍/Spring] - Spring (4) - MySQL과 연결하기에서 DB  Connection Pool 부분을 참고하면 된다.

 

<!--root-context.xml-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="ds"></property>
    <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
    <property name="typeAliasesPackage" value="com.test.mvcproject.model"></property>
</bean>

 

여기서 dataSource의 ref는 등록한 DB의 id값과 일치시킨다.

mapper관련 xml은 java영역에 있으므로 classpath:를 붙여준다. classpath는 src/로 이동해주는 것이다.

 

그리고 alias에서 어떤 객체를 뭐라고 부르겠다고 직접 정의해주지 않았는데, 이때는 그냥 class이름이 매칭된다.

ex) com.test.mvcproject.model.UserDto = UserDto

+) 직접 이름을 지정해주고 싶다면, alias용 파일을 만들어서 sqlSessionFactory 속성으로 등록해주면 된다.

더보기

1) mybatis-config.xml

<!--mybatis-config.xml-->
<configuration>
	<typeAliases>
		<typeAlias type="com.test.mvcproject.model.UserDto" alias="userDto"/>
	</typeAliases>
</configuration>

 

2) context.xml의 sqlSessionFactory태그 안

<!--context.xml-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>

 

 

 

2. SqlSession 등록하기

SqlSession은 생성하면서 반드시 Factory가 누구인지 받아야 하므로, 앞서 생성한 Factory를 생성자인자로 보낸다.

<!--root-context.xml-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg ref="sqlSessionFactory"/>
</bean>

 

 

 

2. UserServiceImpl 수정

이제 UserMapper(=이전에 UserDao 인터페이스)가 java와 sql문을 맵핑시키는 역할이다.

UserMapper(인터페이스)를 일종의 DB로 가는 다리라고 보면 될 것 같다.

 

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private SqlSession sqlSession;
	
	@Override
	public void registerUser(UserDto userDto) throws Exception {
		sqlSession.getMapper(UserMapper.class).registerUser(userDto);
	}

	@Override
	public UserDto login(Map<String, String> map) throws Exception {
		return sqlSession.getMapper(UserMapper.class).login(map);
	}

	@Override
	public List<UserDto> listUser() throws Exception {
		return sqlSession.getMapper(UserMapper.class).listUser();
	}

	@Override
	public UserDto getUser(String userId) throws Exception {
		return sqlSession.getMapper(UserMapper.class).getUser(userId);
	}

	@Override
	public void updateUser(UserDto userDto) throws Exception {
		sqlSession.getMapper(UserMapper.class).updateUser(userDto);
	}

	@Override
	public void deleteUser(String userId) throws Exception {
		sqlSession.getMapper(UserMapper.class).deleteUser(userId);
	}

}

 

 

 

3. member.xml 수정

이제 UserDaoImpl에서 불러주지 않아도 자동으로 불리기 때문에 UserDaoImpl.java는 삭제하자.

이때, mapper.xml의 id값과 UserDao의 메서드의 이름이 일치해야 맵핑되어 자동으로 불릴 수 있다는 점을 주의

<!--src/main/resources/mapper/member.xml-->

<?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="com.test.mvcproject.model.mapper.UserMapper">
 	<insert id="registerUser" parameterType="com.test.mvcproject.model.UserDto">
 		insert into user
 		values(#{userId}, #{userName}, #{userPwd}, #{email}, now())
 	</insert>
 	
 	<sql id="getById">
	    select * from user
	    where userid=#{userId}
	</sql>
	
	<select id="login" parameterType="map" resultType="userDto">
	    <include refid="getById"></include> 
	    and userpwd = #{userPwd}
	</select>
	
	<select id="getUser" parameterType="string" resultType="userDto">
	    <include refid="getById"></include>
	</select>
 	
 	<resultMap type="userDto" id="userList">
 		<result column="username" property="userName"/>
 		<result column="userid" property="userId"/>
 		<result column="userpwd" property="userPwd"/>
 		<result column="email" property="email"/>
 	</resultMap>
 	
 	<select id="listUser" resultMap="userList">
 		select * from user;
 	</select>
 	
 	<update id="updateUser" parameterType="userDto">
 		update user
 		set userpwd=#{userPwd}, username=#{userName}, email=#{email}
 		where userid=#{userId}
 	</update>
 	
 	<delete id="deleteUser" parameterType="string">
 		delete from user
 		where userid=#{userId}
 	</delete>
 </mapper>

 

 

 

 

+) SqlSession은 DB관련 작업이므로 Service에는 Mapper(Dao)를 통해 사용해야 한다.

=> Mapper를 Scan해서 Autowired로 쓸 수 있도록 하자

 

1. Namespaces에서 mybatis-spring추가

 

 

2. root-context.xml

sqlSession은 주석하고 mapper scan을 등록한다.

<mybatis-spring:scan base-package="com.test.mvcproject.model.mapper"/>

 

3. UserServiceImpl에서 Mapper쓰기

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserMapper userMapper;
	
	@Transactional
	@Override
	public void registerUser(UserDto userDto) throws Exception {
		userMapper.registerUser(userDto);
	}

	@Override
	public UserDto login(Map<String, String> map) throws Exception {
		return userMapper.login(map);
	}

	@Override
	public List<UserDto> listUser() throws Exception {
		return userMapper.listUser();
	}

	@Override
	public UserDto getUser(String userId) throws Exception {
		return userMapper.getUser(userId);
	}

	@Transactional
	@Override
	public void updateUser(UserDto userDto) throws Exception {
		userMapper.updateUser(userDto);
	}

	@Transactional
	@Override
	public void deleteUser(String userId) throws Exception {
		userMapper.deleteUser(userId);
	}

}