Spring

[Spring] SqlSession, 트랜잭션

삶_ 2022. 10. 4. 09:41

 

 

RootApplicationContext

  • 먼저 실행됨
  • <context-param> 내에 있는 xml 파일들이 먼저 읽힘
  • bean 들이 들어있음. 서로 참고 가능.

 

WebApplicationContext

  • RootApplicationContext 다음 실행됨
  • DispatcherServlet
  • <load-on-startup>1<..
  • ----servlet.xml 파일들 인식
  • bean들이 들어있음. 서로 참고 가능.

 

 

 

mybatis 연결

 

파일 목록

 

SqlMapConfig.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 : 객체들 별칭 정해놓는 곳 -->
	<!-- 재사용 가능성이 높은 VO의 별칭 정해놓기 -->
	<typeAliases>
		<typeAlias type="com.spring.ex01.MemberVO" alias="memberVO" />
	</typeAliases>
	
	<!-- environments : DB에 연결할 설정 정보들 -->
	<!-- 여러개의 environments 설정 가능하다는 뜻 -->
	<!-- default="아이디" : 기본으로 연결할 설정 정보 아이디 -->
	<environments default="development">
		<!-- 설정 정보 시작 -->
		<environment id="development">
			<!-- 트랜잭션 제어를 누가 할것인가 -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- 실제 DB 접속에 관한 정보 -->
			<!-- type : 커넥션을 사용할건지에 대한 여부 -->
			<!-- POOLED : 최초 Connection객체를 생성 시, 그 정보를 풀 영역에 저장.(이후 재사용 가능) -->
			<dataSource type="POOLED">
				<property name="driver" value="oracle.jdbc.driver.OracleDriver"></property>
				<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
				<property name="username" value="scott"></property>
				<property name="password" value="tiger"></property>
			</dataSource>
		</environment>
	</environments>

	<!-- DB에 사용되는 쿼리문을 담은 mapper 파일 등록 -->
	<mappers>
		<mapper resource="mybatis/mapper/member.xml" />
	</mappers>

</configuration>

 

member.xml

<mapper>
	<!-- property : get메서드 이름 -->
    <resultMap id="memResult" type="memberVO">
		<result property="id" column="id" />
		<result property="pwd" column="pwd" />
		<result property="name" column="name" />
		<result property="email" column="email" />
		<result property="joinDate" column="joinDate" />
	</resultMap>
	
	<select id="selectAllMemberList" resultMap="memResult">
		<!-- ![CDATA[문장]] : 태그로 오해하지 말라는 뜻. SQL 문의 일부라는 뜻으로 알려주기 위해 작성. -->
		<![CDATA[
			select * from t_member order by joinDate desc
			]]>
	</select>
    
    <!-- parameterType : 아래 SQL문 호출시 전달되는 매개변수의 데이터 타입 지정 -->
	<!-- 예시 : ...selectOne("mapper.member.selectMemberById", id) 로 호출했을 때 -->
	<select id="selectMemberById" resultMap="memResult" parameterType="String">
		<![CDATA[
			select * from t_member
			where id = #{id}
			]]>
	</select>
</mapper>

 

 

 

 

SqlSession 의 메서드

  • selectList(query_id) : id에 대한 select 문 실행, 여러 레코드를 List로 반환
  • selectList(query_id, 조건) : id에 대한 select 문 실행, 사용되는 조건도 전달
  • selectOne(query_id) : id에 대한 select 문 실행, 지정 타입으로 한개의 레코드 반환
  • selectOne(query_id, 조건) : id에 대한 select 문 실행, 사용되는 조건도 전달.
  • insert(query_id, obj) : id에 대한 insert문을 실행. obj 객체의 값을 테이블에 추가
  • update(query_id, obj) : obj 객체의 값을 조건문의 수정 값으로 사용. id에 대한 update문 실행
  • delete(query_id, obj) : obj 객체의 값을 조건문의 수정 값으로 사용. id에 대한 delete문 실행

 

 

 

 

동적 SQL 문 만들기


 

<if>

<where>
	<if test="조건식">
		추가할 구문
	</if>
</where>

이런 식이고,

<select id="searchMember" parameterType="memberVO" resultMap="memResult">
	<![CDATA[
		select * from t_member
	]]>
	<!-- SQL 문의 where 절을 의미 -->
	<where>
		<!-- name이 공백, null이 아닐 때 -->
		<if test="name != '' and name != null">
			name = #{name}
		</if>
		<!-- email이 공백, null이 아닐 때 -->
		<if test="email != '' and email != null">
			email = #{email}
		</if>
	</where>
	order by joinDate desc
</select>

 

 

<choose>

<!-- 자바의 switch문 같은 것 -->
<choose>
	<when test="조건식">
	 	구문...
	</when>
	<when test="조건식">
	 	구문...
	</when>
	..
	<!-- 아래는 생략 가능 -->
	<!-- 그 외 -->
	<otherwise>
		구문...
	</otherwise>
</choose>

 

 

 

<foreach>

<!-- 한번에 여러개 데이터를 처리할 때 -->
<!-- 설명 시작
collection : 전달받은 인자값. array와 list 값을 전달 가능.
index : foreach문이 반복될 때 마다 1씩 증가. 접근하는 값의 위치를 나타냄
item : 반복문이 실행될 때마다 collection 속성에 지정된 값에 접근하여 차례대로 사용
open : 해당 구문이 시작될 때 붙힐 기호
close : 해당 구문이 끝날 때 붙일 기호
separator : 한번이상 반복될 때, 반복되는 사이에 지정한 기호 추가
설명 끝  -->
<foreach item="item" collection="list" index="index" open="(" close=")" separator=",">
	#{item}
</foreach>


<!-- 여러명 insert 할 때 -->
<!-- before -->
<insert id="foreachInsert" parameterType="java.util.Map">
	INSERT INTO t_member (id, pwd, name, email)
	VALUES
	<foreach item="item" collection="list">
		(#{item.id},
		#{item.pwd},
		#{item.name},
		#{item.email}
		)
	</foreach>
</insert>


<!-- after -->
<insert id="foreachInsert" parameterType="java.util.Map">
	<!-- 반복 작업시, INSERT ALL 사용 -->
	<foreach item="item" collection="list" open="INSERT ALL" separator=" "
	close="SELECT * FROM DUAL">
	INTO t_member (id, pwd, name, email)
	VALUES
		(#{item.id},
		#{item.pwd},
		#{item.name},
		#{item.email}
		)
	</foreach>
</insert>

 

 

 

 

 

트랜잭션

  • 여러개의 DML 명령문을 하나의 논리적인 작업 단위로 묶어서 관리하는 것
  • SQL 명령문이 정상 처리 → 모든 작업 결과를 DB에 영구 반영
  • 하나라도 잘못된 것 발견 → 모두 취소됨

 

스프링의 트랜잭션 속성들

  • propagation : 트랜잭션 전파 규칙 설정
    • REQUIRED
      • 트랜잭션 필요. 진행 중인 트랜잭션이 있는 경우, 해당 트랜잭션 사용
      • 트랜잭션이 없으면 새로운 트랜잭션 생성.
      • 디폴트 값임.
  • isolation : 트랜잭션 격리 레벨 설정
  • readonly : 읽기 전용 여부 설정
  • rollbackFor : 트랜잭션을 롤백할 예외 타입 설정
  • norollbackFor : 트랜잭션을 롤백하지 않을 예외 타입 설정
  • timeout : 트랜잭션 타임아웃 시간 설정

 

 

 

트랜잭션 활용

  • 보통 sql문이 들어간 메서드를 실행하면 변경된 사항이 그대로 남아있지만,
  • 트랜잭션을 이용하면 중간에 변경 후 사이트 오류 발생시
  • 다시 원본 값으로 돌아오게 만든다
// TestService 클래스의 모든 메서드에 트랜잭션을 적용함
@Transactional(propagation=Propagation.REQUIRED)
public class TestService() {
	private TestDAO dao;
	public void setDao (TestDAo dao){
		this.dao = dao;
	}
	
	public void testMethod() throws Exception {
		// 아래는 sql 문(update)이라고 가정
		dao.updateSql1();
		dao.updateSql2();
	}
}

 

 

 

 

 

스프링 애너테이션 제공 클래스

  • DefaultAnnotationHandlerMapping : 클래스 레벨에서 @RequestMapping 을 처리
  • AnnotationMethodHandlerAdapter : 메서드 레벨에서 @RequestMapping 을 처리

 

context:component-scan

  • <context:component-scan base-package=”패키지 이름”>
  • 애너테이션
    • @Controller : 스프링 컨테이너가 component-scan에 의해 지정한 클래스를 컨트롤러 빈으로 자동 변환
      • 클래스 이름이 TestController 라면
      • <bean id=’testController’ class=’TestController’> 와 의미가 같음
    • @Service : 위와 같고 서비스 빈으로 자동 변환
    • @Repository : 위와 같고 DAO 빈으로 자동 변환
    • @Component : 위와 같고 빈으로 자동 변환

 

 

 

 

 

 

참고

자바 웹을 다루는 기술