ㅁ (스프링) root-context.xml
<?xml version="1.0" encoding="UTF-8"?>
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- mybatis 사용을 위한 빈 3개 -->
<bean class="org.apache.commons.dbcp2.BasicDataSource" id="dataSource" destroy-method="close">
<!-- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> -->
<property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy" />
<property name="url" value="jdbc:log4jdbc:oracle:thin:@localhost:1521:xe" />
<property name="username" value="spring" />
<property name="password" value="spring" />
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="configLocation" value="classpath:config/mybatis-config.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
<constructor-arg ref="sqlSessionFactory" />
</bean>
<!-- 트랜잭션 처리용 aop를 위한 구문 3개 -->
<!-- AOP를 이용한 트랜잭션 처리 -->
<!-- 1) 트랜잭션 매니저 빈으로 등록 (dataSource 객체 필요함) -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 2) 트랜잭션 Advice 등록 -->
<tx:advice transaction-manager="txManager" id="txAdvice">
<tx:attributes>
<tx:method name="*" /> <!-- pointcut의 모든 메소드에서 실행하겠다. (삽입, 수정, 삭제, 목록조회, 상세조회 등의 메소드가 있음) -->
<tx:method name="select*" read-only="true" /> <!-- 단, select로 시작하는 메소드는 실행하지 않는다. (삽입, 수정, 삭제 메소드만 실행됨) -->
</tx:attributes>
</tx:advice>
<!-- 3) AOP 등록 -->
<aop:config>
<aop:pointcut expression="execution(* com.br.spring.service.*Impl.*(..))" id="txPointcut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>
<!-- 파일 업로드를 위한 빈 등록 -->
<!-- 주의사항 : 빈 이름을 내 마음대로 하면 안되고 반드시 multipartResolver로 해야 한다. -->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<property name="maxUploadSizePerFile" value="10485760" />
<property name="maxUploadSize" value="104857600" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
</beans>
- 스프링에서 트랜잭션 처리를 aop로 했었다.
ㅁ BoardSelectImpl
package com.br.boot.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.br.boot.dao.BoardDao;
import com.br.boot.dto.AttachDto;
import com.br.boot.dto.BoardDto;
import com.br.boot.dto.PageInfoDto;
import com.br.boot.dto.ReplyDto;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
public class BoardServiceImpl implements BoardService {
private final BoardDao boardDao;
@Override
public int selectBoardListCount() {
return boardDao.selectBoardListCount();
}
@Override
public List<BoardDto> selectBoardList(PageInfoDto pi) {
return boardDao.selectBoardList(pi);
}
@Override
public int selectSearchListCount(Map<String, String> search) {
return boardDao.selectSearchListCount(search);
}
@Override
public List<BoardDto> selectSearchList(Map<String, String> search, PageInfoDto pi) {
return boardDao.selectSearchList(search, pi);
}
@Transactional
@Override
public int insertBoard(BoardDto b) { // 컨트롤러에서 BoardDto에 작성자, 제목, 내용, 첨부파일 list도 담아서 넘겼다.
int result = boardDao.insertBoard(b);
List<AttachDto> list = b.getAttachList();
if(result > 0 && !list.isEmpty()) {
result = 0;
for(AttachDto attach : list) {
result += boardDao.insertAttach(attach);
}
}
return result;
}
@Override
public int updateIncreaseCount(int boardNo) {
return boardDao.updateIncreaseCount(boardNo);
}
@Override
public BoardDto selectBoard(int boardNo) {
return boardDao.selectBoard(boardNo);
}
@Override
public int deleteBoard(int boardNo) {
return boardDao.deleteBoard(boardNo);
}
@Override
public List<ReplyDto> selectReplyList(int boardNo) {
return boardDao.selectReplyList(boardNo);
}
@Override
public int insertReply(ReplyDto r) {
return boardDao.insertReply(r);
}
@Override
public List<AttachDto> selectDelAttach(String delFileNo[]) {
return delFileNo == null ? new ArrayList<>() : boardDao.selectDelAttach(delFileNo);
}
@Transactional
@Override
public int updateBoard(BoardDto b, String[] delFileNo) {
// 1) board 테이블에 update
int result1 = boardDao.updateBoard(b);
// 2) attachment 테이블에 delete
int result2 = 1; // delFileNo이 null일 때도 ~
if(result1 > 0 && delFileNo != null) {
result2 = boardDao.deleteAttach(delFileNo);
}
// 3) attachment 테이블에 insert
List<AttachDto> list = b.getAttachList();
int result3 = 0;
for(AttachDto at : list) {
result3 += boardDao.insertAttach(at);
}
// 성공에 대한 조건- result1이 1이어야 하고, result2가 0보다 커야 하고, result3가 list의 사이즈와 동일해야 한다.
return result1 == 1
&& result2 > 0
&& result3 == list.size()
? 1 : -1;
}
@Override
public int deleteReplyCompletely() {
return boardDao.deleteReplyCompletely();
}
}
- 트랜잭션 처리가 필요한 메소드 위에 @Transactional을 붙이면 된다. 2개 붙였다.
- 만약 이 클래스의 모든 메소드에 필요하면 클래스 상단에 @Transactional을 부이면 이 안의 모든 메소드가 다 트랜잭션 처리가 된다.
- 회사가면 서비스를 분리하는 경우도 있다.
트랜잭션 처리가 필요한 서비스 따로 필요하지 않은 서비스 따로 분리하는 경우가 있다.
이렇게 분리를해서 서비스 안의 모든 메소드에 트랜잭션 처리가 필요하면 클래스 상단에 @Transactional을 붙이면 된다.
ㅁ 마이그레이션은 끝났다.
ㅁ 부트프로젝트 작업은 끝.
'Spring' 카테고리의 다른 글
스프링 정리 - MVC (0) | 2024.11.13 |
---|---|
디비 (1) | 2024.11.06 |
[스프링부트] 9. 웹소켓 (2) | 2024.11.06 |
[스프링부트] 8. Scheduler (0) | 2024.11.06 |
[스프링부트] 7. Interceptor (0) | 2024.11.06 |