<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<Context>
<Resource name="jdbc/db" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="root" password="123456" driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/ssafyweb?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8"/>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>
dl 방식으로 db를 읽어와서 Jndi에 세팅한다.
sqlSession을 설정한다.
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/db"></property>
</bean>
<bean id="sqlSessionFactoryBean"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.main.*.model"></property>
<property name="mapperLocations"
value="classpath:mapper/*.xml"></property>
</bean>
<mybatis-spring:scan base-package="com.main.*.model.mapper"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<mapper namespace="com.main.board.model.mapper.BoardMapper">
<resultMap type="boardDto" id="article">
<result column="article_no" property="articleNo"/>
<result column="user_id" property="userId"/>
<result column="user_name" property="userName"/>
<result column="hit" property="hit"/>
<result column="register_time" property="registerTime"/>
</resultMap>
<delete id="deleteArticle" parameterType="int">
delete from board
where article_no = #{articleNo}
</delete>
public interface BoardMapper {
void deleteArticle(int articleNo) throws SQLException;
}
<resultMap type="boardDto" id="viewArticle" extends="article">
<collection property="fileInfos" column="article_no" javaType="list" ofType="fileInfoDto" select="fileInfoList"/>
</resultMap>
collection는 자료구조 사용 가능. (javaType으로 list사용을 알 수 있음)
ofType => List<"ofType">
'fileInfoList'라는 이름의 sql문으로 데이터를 불어오겠다라는 의미.
property는 자바에서의 변수명
column는 테이블에서의 컬럼명
<resultMap type="boardDto" id="article">
<result column="article_no" property="articleNo"/>
<result column="user_id" property="userId"/>
<result column="user_name" property="userName"/>
<result column="subject" property="subject"/>
<result column="content" property="content"/>
<result column="hit" property="hit"/>
<result column="register_time" property="registerTime"/>
</resultMap>
<resultMap type="boardDto" id="viewArticle" extends="article">
<collection property="fileInfos" column="article_no" javaType="list" ofType="fileInfoDto" select="fileInfoList"/>
</resultMap>
<select id="getArticle" parameterType="int" resultMap="viewArticle">
select b.article_no, b.user_id, b.subject, b.content, b.hit, b.register_time, m.user_name
from board b, members m
where b.user_id = m.user_id
and b.article_no = #{articleNo}
</select>
<select id="fileInfoList" resultMap="file">
select save_folder, original_file, save_file
from file_info
where article_no = #{articleNo}
</select>
순서
getArticle를 호출
-> viewArticle라는 resultMap으로 값을 받아옴
-> 그런데 viewArticle에는 collection이 존재함. 해당 collection은 fileInfoList라는 sql문으로 받아온다.
-> getArticle라는 sql문 결과 하나하나당 fileInfoList라는 sql문 결과가 다 저장된다.
<where>
<if test=”state != null”>
state = #{state}
</if>
<if test=”title != null”>
AND title like #{title}
</if>
<if test=”author != null and author.name != null”>
AND author_name like #{author.name}
</if>
</where>
selectKey로 order로 설정한 순서에 따라, 해당 값은 keyProperty의 이름으로 저장한다.
그 후 그 값을 이용해서 insert하면 그 값을 입력으로 들어간다.
아래 코딩의 경우 boardDto 객체의 articleNo에 같이 들어 간 것이다.
그리고 그 다음 insert에서 boardDto 객체의 articleNo를 읽어서, 테이블에 저장되는 것이다.
<insert id="writeArticle" parameterType="boardDto">
insert into board (user_id, subject, content, hit, register_time)
values (#{userId}, #{subject}, #{content}, 0, now())
<selectKey resultType="int" keyProperty="articleNo" order="AFTER">
select last_insert_id()
</selectKey>
</insert>
<insert id="registerFile" parameterType="boardDto">
insert into file_info (article_no, save_folder, original_file, save_file)
values
<foreach collection="fileInfos" item="fileinfo" separator=" , ">
(#{articleNo}, #{fileinfo.saveFolder}, #{fileinfo.originalFile}, #{fileinfo.saveFile})
</foreach>
</insert>
last_insert_id 함수는 테이블의 마지막 auto_increment 값을 리턴한다.
트랜젝션을 직접 관리할 경우(자바에서는 어노테이션을 @Transactional 으로 설정한다.)
보통 select를 제외하고 설정해주면 된다. 다만, mapper 클래스가 아니라 service 클래스에서 하는 것이 좋다. 이유는 특정 서비스는 insert를 두번할 수도 있고, 그 sql문이 둘 다가 될 때만 적용 시키고 싶을 수도 있기 때문이다.
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
역할 : 오류발생에 따라, 롤백과 commit를 제어하기 위함