마이바티스는 XML 서술자나 어노테이션을 사용하여 저장 프로시저나 SQL 문으로 객체들을 연결해주는 프레임워크이다. 들어가기 앞서 마이바티스에 대한 자세한 내용은 위 포스팅을 참고하자.
종속성 추가
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
...
</dependencies>
스프링에서 Mybatis를 사용하기 위해서는 pom.xml에 설정을 추가해준다. 최신 버전은 https://mvnrepository.com/에서 찾을 수 있다.
root-context.xml
모든 마이바티스 애플리케이션은 SqlSessionFactory 인스턴스를 사용한다. SqlSessionFactory 인스턴스는 SqlSessionBuilder를 사용하여 만들 수 있다. SqlSessionFactoryBuilder는 XML 설정 파일에서 SqlSessionFactory 인스턴스를 빌드할 수 있다.
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- A구역 -->
<bean id="dataSourceSpied"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://주소:포트/DB이름?characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="아이디"/>
<property name="password" value="비밀번호"/>
</bean>
<bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource">
<constructor-arg ref="dataSourceSpied" />
<property name="logFormatter">
<bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter">
<property name="loggingType" value="MULTI_LINE" />
<property name="sqlPrefix" value="SQL : "/>
</bean>
</property>
</bean>
<!-- B구역 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/mybatis/mybatisConfig.xml" />
<property name="mapperLocations" value="classpath:/mybatis/mybatisMapper.xml" />
</bean>
<!-- C구역 -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
XML 설정 파일에서는 데이터베이스 Connection 인스턴스를 가져오기 위한 DataSource를 포함한다. 글쓴이는 수행되는 쿼리를 확인하기 위해서 Log4jdbcProxyDataSource를 사용하였다. A구역에서는 드라이버 클래스 이름, 연결 URL, 유저 이름 및 비밀번호를 프로퍼티로 사용하여 Connection을 만든다. B구역에서는 1번에서 만든 Connection과 설정을 프로퍼티로 사용하여 sqlSessionFactory를 생성한다. C구역에서는 마이바티스의 핵심 템플릿을 담아놓은 라이브러리를 sqlSessionFactory에 적용하여 sqlSession 객체를 만든다.
mybatis-config.xml
<?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>
<typeAliases>
<typeAlias alias="MemberVO" type="패키지명.MemberVO"/>
<typeAlias alias="DateParam" type="패키지명.DateParam"/>
<typeAlias alias="DateVO" type="패키지명.DateVO"/>
<typeAlias alias="FeelingVO" type="패키지명.FeelingVO"/>
<typeAlias alias="DetailParam" type="패키지명.DetailParam"/>
</typeAliases>
</configuration>
직접 정의한 VO 객체로 결과를 받아오기 위해 자주 사용하는 타입의 별칭을 작성해준다. typeAlias 태그의 alias 속성에는 alias로 지정할 클래스 명을 적고, type 속성에는 클래스의 패키지 주소를 적는다.
mybatis-mapper.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="mogi">
<select id="selectUser" parameterType="string" resultType="MemberVO">
select * from user where userId=#{value}
</select>
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id" parameterType="MemberVO">
insert into user(userId, userPw) values(#{userId},#{userPw})
</insert>
...
</mapper>
이제 DAO안의 SqlSession은 해당 Mapper 파일을 참고하여 쿼리를 수행한다. mapper 하위 엘리먼트의 종류는 다음과 같다.
- cache: 해당 네임스페이스를 위한 캐시 설정
- cache-ref: 다른 네임스페이스의 캐시 설정에 대한 참조
- resultMap: 결과데이터를 객체에 로드하는 방법을 정의
parameterMap: 파라미터를 매핑하기 위해 사용되었으나 현재는 권장하지 않음- sql: 다른 구문에서 재사용하기 위한 SQL 조각
- insert: 매핑된 insert 구문
- update: 매핑된 update 구문
- delete: 매핑된 delete 구문
- selefct: 매핑된 select 구문
select
<?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="mogi">
<select id="selectUser" parameterType="string" resultType="MemberVO">
select * from user where userId=#{value}
</select>
...
</mapper>
데이터베이스에서 데이터를 가져오는 엘리먼트이다. 동일한 유형을 제거하고 보자. parameterType과 resultType은 이름에서 알 수 있듯이 각각 파라미터로 넣을 값의 타입, 결과로 받을 값의 타입을 의미한다.
public class MemberVO {
private int id;
private String userId;
private String userPw;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserPw() {
return userPw;
}
public void setUserPw(String userPw) {
this.userPw = userPw;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
위 쿼리는 string 타입 value 파라미터와 userId가 일치하는 행을 가져와서 MemberVO에 세팅(setter)한 후 해당 MemberVO를 돌려준다.
insert, update, delete
insert, update, delete는 동일한 엘리먼트 속성을 가진다.
- parameterType: 구문에 전달될 파라미터의 패키지 경로를 포함한 전체클래스명이나 별칭이다.
parameterMap: 외부 parameterMap을 찾기 위한 접근 방법. 비권장- flushCache: true이면 구문이 호출될 때마다 캐시가 지워진다. 디폴트는 false 이다.
- timeout: 예외가 발생하기 전에 요청 결과를 기다리는 최대 시간을 설정한다.
- statementType: STATEMENT, PREPARED, CALLABLE 중 하나를 선택할 수 있다. 디폴트는 PREPARED이다.
- useGenerateKeys: 데이터베이스에서 내부적으로 생성한 키(ex. 자동 증가 필드)를 이용하는 테이블에서 사용(insert, update 엘리먼트에서만 사용 가능)
- keyProperty: getGenerateKeys 메서드나 insert 엘리먼트의 selectKey 속성에 의해 리턴된 키를 세팅할 프로퍼티를 지정(insert, update 엘리먼트에서만 사용 가능)
- keyColumn: 생성키를 가진 테이블의 컬럼명을 세팅. 키 컬럼이 첫 번째 컬럼이 아닌 DB(ex. PostgreSQL)에서만 필요(insert, update 엘리먼트에서만 사용 가능)
- databaseId: 설정된 databaseIdProvider가 있는 경우 databaseId 속성이 없는 모든 구문을 로드하거나 일치하는 모든 databaseId와 함께 로드될 것이다. 만약 databaseId가 여러 개 나오는 경우 첫번째 것을 제외하고 무시한다.
statementType에 대한 추가 설명
- PREPARED는 DBMS에서 동일하거나 비슷한 쿼리를 높은 효율성으로 반복 실행하기 위해 사용되는 기능이다. 애플리케이션에서는 쿼리 틀만 만들고 DBMS가 이를 받아 쿼리를 컴파일하여 그 결과만 저장한다. 이후 애플리케이션이 변수에 값을 바인드하면 DBMS는 쿼리문을 실행한다.
- STATEMENT는 쿼리를 수행할 때마다 매번 PREPARED의 단계들을 수행한다. 즉, PREPARED는 캐시를 사용하지만 STATEMENT는 캐시를 사용하지 않아 반복적으로 동일한 쿼리를 사용한다면 PREPARED가 효과적이다.
- CALLABLE은 프로시저나 함수를 호출하기 위하여 사용한다.
insert
<?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="mogi">
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id" parameterType="MemberVO">
insert into user(userId, userPw) values(#{userId},#{userPw})
</insert>
...
</mapper>
user 테이블의 PK는 auto_increment이기 때문에 useGenerateKeys를 사용하였다. 이 경우 자동 생성키는 keyProperty로 컬럼 이름을 명시하고 쿼리에서는 컬럼 이름이나 값을 명시해주지 않아도 된다.
update
<update id="updateAuthor" parameterType="domain.blog.Author" flushCache="true"
statementType="PREPARED" timeout="20">
delete
<delete id="deleteAuthor">
delete from Author where id = #{id}
</delete>
참고
'Spring' 카테고리의 다른 글
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 에러 해결 (0) | 2024.02.18 |
---|---|
JPA 복합키 사용 방법 (0) | 2021.10.14 |
프로토타입 빈(Prototype Bean) (0) | 2021.10.09 |
JSON vs XML (0) | 2021.10.03 |
마이바티스(MyBatis) (0) | 2021.10.01 |
댓글