Java/Spring MVC

[20.10.08 SpMVC_ReadBook2,오라클 9/25 독서록] PathVariable, @SessionAttribute(), @ModelAttribute(), Spring form taglib를 연동한 write(입력 form) 구현, 다중 INSERT

우롱차 2020. 10. 8. 14:54
728x90

여기서 BooksController와 MemberController가 중요하다

MemberController는 Security와 관련이 없지만 CRUD때문에!

 

Spring Security만 가지고 와도

security-context.xml

이걸 사용할 수 있다.

 

이 세가지는 security와 관련되어있음

 

jasypt는 암호를 암호화시키고 복호화시키고 DB에 연동할때 사용했던거임

 

실제로는 xml파일에서 거의썼지 나머지부분들에 설정하지 않았음.


pathVariable은 ?seq= + seq를 사용 x

>> book-detail.jsp


@ResponseBody
@RequestMapping(value = "/user_info", method=RequestMethod.GET)
public UserDetailsVO userInfo(Principal principal, Authentication authentication,
			@AuthenticationPrincipal @ModelAttribute("memberVO") UserDetailsVO userVO,
            Model model) {
  // Spring Security 프로젝트에서 로그인한 사용자 정보를 추출하는 여러가지 방법
  // 1. UserDetailsServiceImplV1에서 공급받는 방법 (보안상 좋지 않음)
  // 서버의 Session memory에 직접 접근하여 사용자 정보를 추출하는 방법으로
  // 보안에 상당히 취약해서 사용을 지양하는 방법
  // UsernamePasswordAuthenticationToken upa= (UsernamePasswordAuthenticationToken) principal;
  // userVO = (UserDetailsVO) upa.getPrincipal();

  // 이것도 오래된 코드
  // 2. SecurityContextHolder로 부터 추출하는 방법
  // userVO = (UserDetailsVO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

  // 3. Authentication 클래스를 매개변수로 설정하는 방법 (이렇게 사용하자)
  // @ AuthenticationPrincipal이 작동이 안되는 관계로
  // 매개변수에 Authentication 클래스를 객체로 선언하고
  // authentication.getPrincipal() method를 호출하여 userVO를 추출하는 방법
  userVO = (UserDetailsVO) authentication.getPrincipal();
  return userVO;
}

>> MemberController


BooksCotnroller
book-write.jsp

이 세개의 변수명이 같아야하기때문에 소문자로 적어준것임.

 

@SessionAttribute(), @ModelAttribute(), Spring form taglib를 연동한 write(입력 form) 구현

Controller 클래스에 @SessionAttribute("bookVO")를 설정하고

각 method에 매개변수로 @ModelAttribute("bookVO") BookVO bookVO를 선언하고

Controller class의 멤버영역에 @ModelAttribute("bookVO") public BookVo newBookVO() { } method를 선언하고

Spring form taglib를 이용한 write form에 <form:form modelAttribute="bookVO"를 선언하여 프로젝트를 구현하면

 

id, seq 값등 실제 사용자에게 입력받거나 보여줄 필요가 없는 VO의 변수들을

<input type="hidden">으로 설정한 후 Controller로 전송하던 HTML5표준 방식을 사용하지 않아도

VO에 설정된 변수들을 Controller와 JSP가 서로 공유하여 사용할 수 있다.

@SessionAttribute()에 담긴 VO객체는 서버의 메모리에 보관되며

HTTP 프로토콜에 비연결지향(상태가 없는 통신) 통신 상태에서도

데이터를 서로 자유롭게 공유하여 구현할 수 있는 장점이 있다.

 

그럼에도 경우에 따라 입력 form을 사용자에게 보여주었을 때

최종 마지막에 입력했던 데이터들이 form에 나타나서, 불편한 경우가 있다.

이러한 현상을 방지하기 위해 form에 입력되었던 데이터사용이 끝나면(insert, update 완료 후)

SessionStatus.setComplete() method를 호출하여 데이터를 clear 시켜줘야한다.

 

>> book-write.jsp


<sec:authorize access="isAnonymous()"> 아무도 로그인 안했을때

<sec:authorize access="isAuthenticated()"> 로그인을 했을때

<sec:authorize access="hasRole('ADMIN')"> anmin권한을 가지고 있는 사람만 보이는

 

>> security-context.xml


테이블 두개이상이 insert나이런게 실행될 때

마이바티스에 기본적으로 트랜잭션이 실행되어야한다

그래서 transactional을 붙여주는 거

memberServiceImpl 참고

 

userDao의 insert가 수행되기 전에 authDao.insert가 수행되서 insert가 될것이고

userDao insert에 문법오류가 나도록 했기때문에

sql실행이 중단될 것이다.

authDao에는 insert가 되고 userDao는 insert가 안되는 상황이 되었다.

이 상황에서 정상적으로 Transaction이 작동된다면

authDao insert가 취소되어야 한다.

>> MemberServiceImpl

 

이런식으로 자동화 되어서 rollback을 해주었다

인서트가 성공됐다!


오라클의 다중 INSERT문을 마이바티스로 변환 시켜줌

위의 두개의 코드가 같은거!

 

오라클에서 SEQ.NEXTVAL이 오류를 범해서 이런식으로 만들어준거임.

이렇게 한꺼번에 업데이트 됌! JDBC를 닫았다 오픈했다 안해도 되는 효율적인 코드!!

 

<!-- oracle과 mybatis 연동했을 때 seq PK가 없는 table에 다중  insert를 수행하는 코드 -->
<insert id="insertAll_1" parameterType="Authority">
	<foreach collection="list"
		item="vo"
		open="INSERT ALL"
		close="SELECT * FROM DUAL"
		separator=" ">
		INTO tbl_authority (m_userid, m_role)
		VALUES (#{vo.username}, #{vo.authority})
	</foreach>
</insert>

pk가 seq가 아닌거는 이걸 사용해주면된다!

 >> authority-mapper.xml , 9/25독서록 오라클 dbms확인

 

MySQL은 이게 가능하다.

		// List에 담겨있는 값을 DB insert할 때
		// 가장 쉽게 할 수 있는 방법이 List를 for 반복문으로 감싸고
		// VO 한개씩을 insert 에 보내는 방법 (굉장히 촌스러운 방법)
		// jdbc를 오픈하고 보낸다음에 닫고 다시 또 열고 닫고 비효율적이게 될 수 있다.
//		for(AuthorityVO vo : authList) {
//			authDao.insert(vo);
//		}
	
		authDao.insertAll(authList);

>> MemberServiceImplV1

for문을 사용하면 비효율적인 코드가 되어 mapper에다가 sql문으로 바로 생성해줬음

user-mapper.xml, authority-mapper.xml 참조!

728x90