Ex) 로그인 시 아이디 정보를 저장 checkbox 표현 시

 

1. 세션에 저장된 login정보 가져오기

(Spring 에서 세션으로 저장하기 : @SessionAttributes + Model 객체 방식으로도 가능하다)

 

받아올 때 @ModelAttribute 객체로 받아오고 + 클래스에 @SessionAttributes({객체명}) 선언으로

model 객체를 session으로 사용한다.

 

2. 쿠키 생성

Cookie cookie = new Cookie("saveId" , 객체.getId() );

 

3. 쿠키 유효기간 설정 + 사용될 경로 설정

				if(아이디저장 체크박스 value !=null) {
					//아이디 저장 체크 시
					cookie.setMaxAge(60*60*24*30);
				}
				else {
					cookie.setMaxAge(0);
                    //체크 해제 시 유효기간 = 0
                    // 가지고 있던 쿠키가 사라진다
				}
				cookie.setPath(req.getContextPath());
                (HttpServletRequest 객체로 루트를 가져온다
                
                (HttpServletResponse 객체로 전송한다)
				resp.addCookie(cookie);

AOP란? -> 관점 지향 프로그래밍의 약자

=공통되는 부분을 따로 빼내어 필요한 시점에 해당코드를 추가해주는 기술

ex)컨트롤러 -> 서비스 이동시마다 println 을 실행한다면?

 

1. Advice : 공통되는 부분을 따로 빼내어 작성하는 메소드

2. JoinPoint : Advice가 적용될 수 있는 모든 관점(시점) -> 매우많음

3. Pointcut : JoinPoint 중 실제 Advice를 적용할 부분

4. Weaving : 그 시점에 공통 코드를 끼워넣는 작업

(컴파일 시 , 클래스 로딩 시 , 런타임 시 ) 가능

 

*Aspect = Advice + Pointcut : 실제동작코드 + 실제 적용된 부분 을 작성한클래스

=> 부가기능(로깅, 보안, 트랜잭션 등)을 나타내는 공통 관심사에 대한 추상적인 명칭)

=> 여러 객체에 공통으로 적용되는 부가기능을 작성한 클래스를 나타냄

=> 독립적인 요소로 구분해 내서 부가기능을 런타임 시 필요한 위치에 동적으로 참여하게 할 수 있다

 

Advice 시점에 따라

Before Advice JoinPoint 앞에서 실행
Around Advice JoinPoint  앞과 뒤에서 실행
After Advice JoinPoint  호출이 리턴되기 직전에 실행
After Returning Advice JoinPoint  메소드 호출이 정상적으로 종료된 후에 실행
After Throwing Advice 예외가 발생했을 때 실행

 

*Proxy : 대상 객체에 Advice가 적용된 후 생성되는 객체

*Target Object : Advice를 삽입할 대상 객체

 

스프링은 대상 객체에 대한 프록시를 만들어 감싸서 대상 객체를 호출할 때 먼저 호출되서

Advice 로직을 처리한 후 대상 객체를 다시 호출한다.

 

[ AOP 구현 ] - *애너테이션 방식*

Spring pom.xml에 이미 aspectj 가 포함되어있음

+ 좀 더 쉬운 구현을 위한 Weaver 추가

***MVN Repository => Aspectj Weaver 추가

 

1. 해당 클래스에 @Aspect -> 공통 관심사가 작성된 클래스임을 명시

+(Advice, Pointcut 작성되어 있어야 함)

+@Conmonent 추가해 런타임 중 Advice코드가 동적으로 추가될 수 있도록 bean 등록

 

***servlet-context에서 namespace - aop 체크 + <aop:aspectj-autoproxy/> 작성 필요 ***

 

2. 수행할 메소드 + @Before / @After ...

*@Before("Pointcut")  :  Pointcut으로 지정된 메소드가 수행되기 전에 Advice 수행

**Pointcut 작성법 3가지

1) 직접

@Before("execution( * a.b.c..*Controller.*(..))")

작성식 : execution [접근제한자] +리턴타입 + 패키지경로명 + 클래스(*C : 모든 컨트롤러) + 메서드( *(..) : 모든 메서드)

-접근제한자는 생략가능/ *: 모든 리턴타입 의미 / .. :  하위 모든 패키지 or 0개 이상의 매개변수-

 

2) Pointcut이 작성된 메소드명을 작성

 

 

 

3) 타 클래스에 작성된 Pointcut 메소드를 작성

 

3. 메소드 작성

//@Before(직접작성)
@Before("PointcutCollection.controllerPointcut()")
public void controllerLog(JoinPoint jp) {

	logger.info("테스트");
    
    jp.getArgs() : 수행되는 메소드의 모든 매개변수를 배열로 얻어옴
    jp.getTarget() : 타겟이 된 객체를 얻어온다
    jp.getSignature() : 수행되려는 메소드 선언부를 얻어옴
{

-매개변수로 입력한 JoinPoint : 부가 기능 메소드를 제공하는 인터페이스

 

3-1 Pointcut을 모아둘 클래스

public class PointcutCollection {

	@Pointcut("execution(  식 작성 )
    public void controllerPointcut(){}
    
    @Pointcut("execution(  식 작성2 )
    public void servicePointcut(){}
}

 

 

 

 

++ Around 사용 -- 앞뒤 모두 아우르는 관점 ex) 러닝타임계산

@Aspect // Advice + Pointcut 공통 관심사가 작성된 클래스임을 명시
@Component
public class AroundAspect {
	
	//slf4j import
	private Logger logger = LoggerFactory.getLogger(AroundAspect.class);
	
	
	//Around : 전처리, 후처리를 모두 해결하고자 할 때 
	//ProceedingJoinPoint를 매개변수 필수 사용 
	//(Proceeding: 진행)
	//-> proceed() 메소드 사용 가능: 해당 메소드를 기준으로 Before, After 나뉨
	
	
	@Around("PointcutCollection.serviceImplPointcut()")
	public Object aroundLog(ProceedingJoinPoint pp) throws Throwable {
		
		  // 클래스명
		  String className = pp.getTarget().getClass().getSimpleName(); // 대상 객체의 간단한 클래스명(패키지명 제외)
		  
		  // 메소드명
		  String methodName = pp.getSignature().getName(); // 대상 객체 메소드의 정보 중 메소드명을 반환. 
		  String str = "";
		  
		  str += "[Service]" +  className + "-" + methodName + "()";
		  
		  long startMs = System.currentTimeMillis(); // 서비스 시작 시의 ms 값
		  
		  //구분기준
		  Object obj = pp.proceed();
		  long endMs = System.currentTimeMillis(); // 서비스 종료 시의 ms 값
		  
		  //걸린시간
		  str+= "[Running Time]" +(endMs-startMs) + "ms";
		  
		  //서비스 수행 시 사용된 파라미터
		  str+= "[Param]" + Arrays.toString(pp.getArgs());
		  
		  logger.debug(str);
		  
		  //proceed 반환값을 무조건 리턴
		  return obj;
	}
}

 

 

스프링 스케쥴러 : 스프링이 알아서 때에 맞춰 코드 수행해 줌

-> 코드를 수행하려면 해당 클래스가 객체 형대로 존재해야함

-> Bean 필요 -> @Component

 

@Scheduled : Spring 에서 제공하는 스케쥴러 : 시간에 따른 특정 잡업의 순서를 지정하는 방법

 

설정방법 

1. servlet-context.xml -> Namespaces 탭 -> task 체크 후 저장

2. servlet-context.xml -> Source 탭 -> <task:annotation-driven/> 추가

 

@Scheduled 속성

  - fixedDelay : 이전 작업이 끝난 시점으로 부터 고정된 시간(ms)을 설정.
  - fixedRate  : 이전 작업이 수행되기 시작한 시점으로 부터 고정된 시간(ms)을 설정.

  -cron 속성 : UNIX계열 잡 스케쥴러 표현식으로 작성 - cron="초 분 시 일 월 요일 [년도]" - 요일 : 1(SUN) ~ 7(SAT) 

    * - 특수문자 * : 모든 수. 
    * - : 두 수 사이의 값. ex) 10-15 -> 10이상 15이하 
    * , : 특정 값 지정. ex) 3,4,7 -> 3,4,7 지정 
    * / : 값의 증가. ex) 0/5 -> 0부터 시작하여 5마다 
    * ? : 특별한 값이 없음. (월, 요일만 해당) 
    * L : 마지막. (월, 요일만 해당)

 

* 주의사항 - @Scheduled 어노테이션은 매개변수가 없는 메소드에만 적용 가능.

 

@Scheduled(fixedDelay = 3000) : 3초마다

@Scheduled(cron = "0 * * * * *")//모든 년월일시분, 요일 0 초 마다: 매분 0초마다 라는 뜻(매분마다) 

@Scheduled(cron ="( 0 0 * * .. == 0분 0초 == 정시 마다) 

@Scheduled(cron ="( 0 0 0 * .. == 0시 0분 0초 == 자정 마다)

 

 

// +스케쥴러를 이용한 가비지 파일 삭제

String serverPath = servletContext.getRealPath("/resources/images/board");
		//이미지가 저장되어있는 실제 경로
		//위에서 DI로 ServletConetx를 받아놓는다
        
		File[] imgArr = new File(serverPath).listFiles();
		//지정된 경로에 있는 모든 파일 리스트를 File배열로 반환
		//File객체 : 파일을 참조할 수 있는 객체
		
		//배열을 리스트로 변환
		List<File> serverImgList = Arrays.asList(imgArr);
		
		//이미지가 저장된 폴더에 있는 파일 목록을 잘 가져왔는지 확인
		/*
		 * for(File img : serverImgList) { System.out.println(img); }
		 */
		
		//DB에서 파일명 목록 조회
		List<String> dbImgList = boardService.selectImgList();
		System.out.println(dbImgList);
		//serverImgList : 서버에 저장된 파일 목록
		//dbImgList : DB에 저장된 파일명 목록
		
		//서버 DB 모두 비어있지 않은 경우
		if(!serverImgList.isEmpty() &&!dbImgList.isEmpty() ) {
			for(File img : serverImgList) {
				
				String serverImgName = 
						img.toString().substring(img.toString().lastIndexOf("\\")+1);
					
						//img.toString : 경로 + 파일명
						//.substring -> 문자열 시작부터 지정된 index 이전까지 문자열을 모두 삭제
				if(dbImgList.indexOf(serverImgName) == -1) {
					//DB파일명 목록에 서버 파일명과 같은 이름이 없다면
					System.out.println(serverImgName+"삭제");
					img.delete();
				}
			}
		}

 

(1) <resultMap> 태그를 이용한 VO 연결

 

<resultMap type="VO클래스명" id="별칭">

    <id property="PK변수명" column="PK컬럼명"/>

   <result property="일반변수명" column="일반컬럼명"/>

    .....

    <collection property="컬렉션변수명" column="컬럼명"

      javaType="java.util.ArrayList"   ofType="VO클래스명"   select="selectBoardImageList" >

</resultMap>

 

%% <collection> 태그 : 서브쿼리 형식으로 데이터를 가지고오고 싶을때 사용하며 자바 컬렉션 객체에 담아준다

 

(2) ![CDATA[ SQL문 ]  ] 

 

내부에 작성된 태그 문자를 일반 문자 자체로 인식하게 해준다

ex) SQL문 안에 < 같은 기호를 사용할때 태그로 인식되는 등의 문제 방지

 

 

(3) <selectKey>태그 : insert, update 시 사용된 시퀀스 값을 반환하는 태그

 

   <selectKey order="BEFORE" resultType="_int" keyProperty="boardNo">
   SELECT SEQ_BOARD_NO.NEXTVAL FROM DUAL
   </selectKey>

 

-keyProperty : selectKey구문의 결과가 셋팅될 대상 프로퍼티

-keyColumn : 리턴되는 결과셋의 컬럼명은 프로퍼티에 일치한다.

-order : BEFORE 또는 AFTER로 셋팅할 수 있다.

BEFORE( 키를 먼저 조회하고 셋팅 후 실행)

AFTER(실행을 먼저 한 뒤 키를 반환)

 

(4) 동적 SQL : 마이바티스의 핵심 기능으로 SQL 수행 중 조건 ,반복 ,특정 구문 추가 등을 동적으로 수행할 수 있음

 

<forEach> 태그 

 

<foreach collection="list" item="img" 
open="(" close=") A"  separator=" UNION ALL ">

</foreach>

 

   - collection : 반복 접근할 컬렉션 형태의 파라미터
   - item : collection에서 반복 시 마다 순차적으로 하나씩 접근한 요소
   - index : 현재 반복 인덱스 
   - open : forEach 시작 전 추가할 구문
   - close : forEach 종료 후 추가할 구문
   - separator : 반복 시 마다 SQL 사이에 추가할 구분자

 

<if> 문 또는 <choose> 태그 

 

<if test="sv != null">

   <bind name="val" value="'%'+sv+'%'" />  --반복되는 문장 정의
<choose>

  <when test="sk == 'title'">

   

  </when>

</choose>
</if>

 

 

 

 

 

스프링에서는 MultipartFile 객체를 제공한다

 

1. 라이브러리 설정

- 파일 업로드를 위한 MultipartResolver 구현체 라이브러리 등록

 

-> maven repository에서 라이브러리
( commons-fileupload ) 검색 후 아파치 pom 추가

 

2. Bean 등록 + 설정

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize"  value="104857600" />
<property name="maxUploadSizePerFile"  value="104857600" />
<property name="maxInMemorySize"  value="104857600" />
</bean>

 

 

/*

maxUploadSize : 한 요청당 허용되는 최대 용량(byte 단위) - 무제한은 -1
maxUploadSizePerFile : 한 파일당 허용되는 최대 용량(byte단위) , 무제한은 -1

maxInMemorySize : 디스크에 저장되지 않고 메모리에 유지하도록 허용하는 바이트 단위
지정된 용량을 초과할 경우 자동으로 파일이 저장된다
메모리가 파일을 기억해놨다가 mULTIPARTrESOLVER 이용해서 DB 수행하고 와도
메모리에 파일이 있음, DB삽입 성공 시 메모리에서 꺼내서 파일로 저장
기본값 : 10240 byte (10KB)
104857600 = 100MB

*/

 

3.  파라미터로 받기

 

List<MultipartFile> "input태그 name"

으로 리스트로 받아낼 수 있다

 

(servers 에서 module 체크해야 서버와 실제 경로가 일치한다)

--> 파일이 업로드 안됐어도 모두 전송되므로 파일 존재 여부를 체크하고 존재하는 파일만 다시 list를 담아야한다

 

--list 새로 생성해서 MutipartResolver에서
 실제 이미지 담겨있는것만 분별+ DB에 필요한 것만 for문으로 추출

 

!imgList.isEmpry()  = true 면 이미지 삽입 [Mybatis 반복삽입진행 ]

 

4. 이미지 리스드 DB 삽입

 

String webPath 

= "/resources/images/board/"; //DB에 저장되는 경로

String reaPath

= session.getServletContext().getRealPath(WebPath); // 실제 물리경로

 

< mapper >

<insert id="insertImgList" parameterType="list">
INSERT INTO BOARD_IMG
SELECT SEQ_IMG_NO.NEXTVAL, A.* FROM 

<foreach collection="list" item="img" 
open="(" close=") A"  separator=" UNION ALL ">
SELECT 

#{img.imgPath} IMG_PATH , 

#{img.imgName} IMG_NM,
#{img.imgOriginal} IMG_ORIGINAL, 

#{img.imgLevel} IMG_LEVEL, 

#{img.boardNo} BOARD_NO 
FROM DUAL
</foreach>


</insert>

 

  <!-- 동적 SQL : 마이바티스의  기능으로 SQL 수행 중 조건, 반복, 특정 구문 추가 등을 동적으로 수행할 수 있음. -->
  <!-- <forEach>  태그 
   - collection : 반복 접근할 컬렉션 형태의 파라미터
   - item : collection에서 반복 시 마다 순차적으로 하나씩 접근한 요소
   - index : 현재 반복 인덱스 
   - open : forEach 시작 전 추가할 구문
   - close : forEach 종료 후 추가할 구문
   - separator : 반복 시 마다 SQL 사이에 추가할 구분자
   -->

 

+ 5. 이미지 업로드시 미리보기 출력 (JS)

	//파일 올라가있는지 check
	const filecheck = [0 , 0 , 0 , 0 , 0];
	
	//이미지 영역 클릭시 파일첨부창 뜨도록
	$(".images").on("click", function(){
		var index = $(".images").index(this);
		if(filecheck[index]==0){
			$("input[name=images]").eq(index).click()
		}
		else{
			if(confirm("이미지를 삭제하시겠습니까?")){
				$(this).children("img").removeAttr("src");
				$(this).children("img").css("display","none");
				$("input[name=images]").eq(index).val("");
				filecheck[index]=0;
			}
		}
	})
	
	//이미지 첨부되면 미리보기 뜨도록
	$("input[name=images]").on("input",function(){
		var index = $("input[name=images]").index(this);
		
		if(this.files[0]){
			console.log("done"+index);
			filecheck[index]=1;
			console.log(filecheck[index]);
			var reader = new FileReader();
			reader.readAsDataURL(this.files[0]);
			reader.onload = function(e){
				$(".images").eq(index).children("img").attr("src", e.target.result);
				$(".images").eq(index).children("img").css("display", "block");
			}
		}
	})

 

 

 

스프링에서 트랜잭션을 처리하는 방법

 

1. 코드 기반 처리 방법 (기존 commit, rollback 을 이용)

 

2. 선언적 트랜잭션 처리방법 ( <tx: advice> xml 방식 / @Transactional 어노테이션 방식 ) 

※ 어노테이션 방식은 조건이 있다

2-1 트랜잭션 매니저가 Bean으로 등록 됨

2-2 <tx:annotation-driven /> 태그가 존재

@Transactional 어노테이션은 rollback을 위한 어노테이션이다 

(커넥션 반환 시 아무 트랜잭션 처리가 되어있지 않다면 자동 commit이기 때문이다)

- 기본적으로 스프링은 SQLException 을 unChecked Exception ( 명시적으로 예외처리 안해도 됨 )

으로 바꿔놨기 떄문에 예외처리를 해놓지 않고 Exception 발생시 트랜잭션으로 rollback을 수행한다는 개념이다

 

2-1, 2-2 ->

root-context에 가서

1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
   </bean>

 <!-- 스프링에서 사용하는 proxy를 이용한 트랜잭션 제어가 안될 경우 추가적인 트랜잭션 매니저를 추가해서 문제 해결 -->

2. namespace - tx 체크 후

<tx:annotation-driven /> 작성

 

=> @Transactional(rollbackFor = Exception.class)

rollbackFor  속성 : 어떤 예외 발생 시 롤백 수행할 지 지정

스프링에서 예외처리하는 방법

 

1. 메소드별 try-catch /throws 예외 처리

 

2. 컨트롤러 별로 예외 처리 -@ExceptionHandler

 

3. 전역(모든 클래스) 에서 발생하는 예외를 하나의 클래스에서 처리

 

 

[  Mybatis  ]
데이터의 CRUD를 보다 편하게 하기 위해 xml로 구조화한 Mapper 설정 파일을 통해
 JDBC를 구현한 영속성 프레임워크

 

=> SQL 내부에 값을 직접 작성 가능 (? 안쓰고 바로 가능)
=> 조회 rs -> VO 객체로 옮겨담기 과정 축소됨
=> stmt, pstmt 기호화 (생성 X , 섞어서 사용)
=> 동적 SQL (SQL 내부에 if, for 등을 사용 가능)

 

<설정>

1. pom.xml 에 OJDBC 라이브러리 추가

 

<!-- mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>21.1.0.0</version>
</dependency>

 

2. spring - jdbc 추가

<!-- mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

3. mybatis 추가

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.9</version>
</dependency>

 

4. mybatis Spring 추가

<!-- mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.6</version>
</dependency>

 

4. DBCP 사용 추가

<!-- mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.9.0</version>
</dependency>

 

5. mybatis.config 설정하기 

<동작구조>

--> SqlSession 동작을 살펴보면 됨

SqlSession Factory Bean => SqlSessionTemplate  => 실행

(mybatis.config.xml에 설정)       (mapper.xml에 설정)

 

1. Mybatis 설정용 xml파일 DTD(Document Type Definition 추가 

 

(경로) Window - Preferences - XML Catalog - User Specified Entries -add

 

<Config>

[ location 작성] = http://mybatis.org/dtd/mybatis-3-config.dtd (빈칸없이 그대로)

 

[Key 작성] = -//mybatis.org//DTD Config 3.0//EN

 

<Mapper>

[ location 작성] = http://mybatis.org/dtd/mybatis-3-mapper.dtd (빈칸없이 그대로)

 

[Key 작성] = -//mybatis.org//DTD Mapper 3.0//EN

 

 

2. resources에 mybatis-config.xml 생성 후 설정하기

<settings>

     <setting name="jdbcTypeForNull" value="NULL"/>
</settings>

// insert update 에 사용되는 값 중 null 이 있을 경우 NULL을 대입하도록 함 (NOT NULL제약이 없는 경우만 가능)

 

<!-- mapper(SQL이 작성된 파일) 위치 등록 부분 -->
<mappers>
       <mapper resource="/mappers/member-mapper.xml" />
</mappers>

 

<!-- mapper에서 사용되는 VO를 간단히 부르기 위한 별칭 지정 -->
<typeAliases>
       <typeAlias alias="Member" type="edu.kh.fin.member.model.vo.Member"></typeAlias>
</typeAliases>

 

3. root-context.xml 설정 추가

 

<!-- Root Context: defines shared resources visible to all other web components -->
<!-- root-context.xml
web.xml 파일이 가장 먼저 읽어 들이는 설정 파일.
프로젝트 전체에 공유되는 자원(DB연결, 트랜잭션처리, 파일업로드 등)
설정 내용을 작성
 -->
 
<!-- DBCP 사용을 위한 DataSource를 Bean으로 등록!! -->
   <!-- DataSource란? : java에서 Connection Pool을 지원하기 위한 인터페이스 -->
   <!-- BasicDataSource : DataSource인터페이스를 구현한 클래스, 아파치 commons.dbcp에서 제공 -->
   <!-- destroy-method="close" : 주어진 세션을 자동으로 반환(close)하라는 설정 -->
   <bean id="dataSource"
      class="org.apache.commons.dbcp2.BasicDataSource"
      destroy-method="close">

      <property name="driverClassName"
         value="oracle.jdbc.driver.OracleDriver" />
      <property name="url"
         value="jdbc:oracle:thin:@  주소  :xe" />
      <property name="username" value=" DB아이디 "/>
      <property name="password" value=" DB비밀번호 " />

      <!-- defaultAutoCommit: SQL 수행 후 자동 COMMIT 설정. (기본값 : true) -->
      <property name="defaultAutoCommit" value="false" />

      <!-- 커넥션 풀 설정 -->
      <property name="initialSize" value="10" /> <!-- 초기 커넥션 수, 기본 0 -->
      <property name="maxTotal" value="500" /> <!-- 최대 커넥션 수, 기본 8 -->
      <property name="maxIdle" value="100" /> <!-- 유휴 상태로 존재할 수 있는 커넥션 최대 수, 기본 8 -->
      <property name="minIdle" value="10" /> <!-- 유휴 상태로 존재할 수 있는 커넥션 최소 수, 기본 0 -->
      <property name="maxWaitMillis" value="-1" /> <!-- 예외 발생 전 커넥션이 반환 될 떄 까지 대기하는 최대 시간(ms), 기본 -1(무기한) -->
   </bean>
   
      <!-- SqlSession : sql구문을 DB에 전달, 실행하는 객체 (Connection 역할)
      SqlSessionFactory : SqlSession을 만드는 객체 
      sqlSessionFactoryBean : mybatis 설정 파일(mybatis-config.xml)과 Connection Pool 정보를 이용하여 SqlSessionFactory를 만드는 객체 
      sqlSessionTemplate : SqlSession 객체에 트랜잭션 처리 역할이 가능하도록 하는 객체 -->
   <!-- 마이바티스 SqlSession 등록하기 (xml 방식으로 bean 등록) -->
   <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
      <!-- mybatis-config.xml 설정 불러오기 -->
      <property name="configLocation" value="classpath:mybatis-config.xml" />
      <property name="dataSource" ref="dataSource" />
   </bean>
   <!-- SqlSessionTemplate : 기본 SQL 실행 + 트랜잭션 관리 역할을 하는 SqlSession을 생성할 수 있게 하는 객체(Spring bean으로 등록해야함.) -->
   <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
      <constructor-arg ref="sqlSessionFactoryBean" />
   </bean>
   <!-- 스프링에서 사용하는 proxy를 이용한 트랜잭션 제어가 안될 경우 추가적인 트랜잭션 매니저를 추가해서 문제 해결 -->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
   </bean>

 

5. mapper 설정하기

 

resources’폴더에 ‘mappers’ 폴더 생성 후 mapper.xml 파일 생성

 

[ 사용 ] 

---- 최상단 : 마이바티스 매퍼 설정임을 선언 & namespace 선언 ----

<?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="memberMapper">

    <!-- 내용 -->

</mapper>

 

---- <resultMap> 태그 ----

 

-> SELECT 조회 결과(ResultSet)의 컬럼명과 VO객체의 필드명이 일치하지 않을 때 어떤 컬럼과 필드가

매칭되어야 하는지 지정하는 태그

 

->resultMap의 type 속성은 실제로 구현해 놓은 자바 POJO 객체를 사용해야 하며, mybatis-config.xml에서 typeAlias를 지정하지 않은 경우, 패키지 명부터 클래스 명 까지 모두 기술해야 됨

 

---- <insert> <update> <delete> 태그로 SQL문 작성 ----

(개별로 id , parameterType , resultType 등 속성 작성)

 

 

서블릿에서 일일이 getParameter로 받아내던 것과 달리 스프링에서는 더 쉽게 파라미터들을 받아올 수 있다!

 

파라미터 받는 방법 5

 

1. HttpServletRequest

-> 서블릿 방식

2. @RequestParam

-> value / required / defaultValue 속성을 가지고 있음

-> value : input태그 name

-> required : 파라미터 필수 여부 ( 기본값 : true)

-> defaultValue : 전달 받은 파라미터 값이 없을 때 기본 값

3. @RequestParam을 생략

-> ("태그명==매개변수명") 일때

4. @ModelAttribute == 커맨드객체

-> 요청 시 전달 받은 파라미터를 객체 형태로 매핑하는 역할을 해줌

-> 해당 객체 클래스에 기본생성자 getter setter등 생성 

-> 해당 객체 멤버 변수명과 input 태그 name 일치

5. @ModelAttribute을 생략

 

 

 

1. 모듈 설정

 

1-1) 메이븐 레포지토리 -> spring security 검색

-Spring Security Core 

-Spring Security Config

두 가지를 사용하며 pom.xml에 추가

 

=====properties : 메이븐이 적용된 프로젝트에서 공통적으로 
사용할 버전 또는 설정값 정보를 작성하는 태그=========
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.2.10.RELEASE</org.springframework-version>
<org.aspectj-version>1.9.4</org.aspectj-version>
<org.slf4j-version>1.7.25</org.slf4j-version>
</properties>

 

별 이슈없으면 properties로 적용해놓은것과 일치하도록  모듈 버젼에도 ${org.springframework-version} 입력한다.

 

----메이븐에서 설정 문제가 자주 나므로 혹시 모르니 추가----

         <!-- 메이븐 구성 문제로 인한 pom.xml 문제 해결 -->
         <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.2.2</version>
         </plugin>

 

 

1-2) pom.xml 추가 후 설정 관련 resource 폴더에 spring-security.xml 생성

 

---생성 후 namespace 탭에서 security 체크한다

---beans 내부에 작성한다

<bean id="bCryptPasswordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

(BCrypt클래스의 경로이다)

 

1-3) web.xml로 이동해서 구문을 추가한다

<context-param> 에 <param-value>안에 classpath:spring/appServlet/spring-security.xml

 

서버가 시작하면 web.xml 제일먼저 -> 그중 param-value 읽어들임

-> spring-security를 등록했으므로 그 안의 bean 읽어 스프링이 객체 관리 -> DI 사용 가능해짐

 

 

2. 사용

2-1 객체 DI

@Autowired
private BCryptPasswordEncoder encoder;
//Bean으로 등록된 BCryptPasswordEncoder 객체를 의존성 주입(DI)

 

2-2 암호화 진행

encoder.encode(문자열) => 암호화 문자열 반환

encoder.matches(원본 문자열 , 암호화 된 문자열 ) => 원본과 암호화문자가 일치하는지 true / false

 

 

SHA-512는 매번 같은 암호화 문자열이 반환되는 문자가 생성되는 문제가 있는데 반해

Bcrypt 암호화는 매번 다른 문자열이 반환되고 확인해낼 수 있다

 

이클립스 설치 + STS for Eclipse 로 구축해본다

 

STS 압축 해제 후 contents 압축파일 해제 -> sts4.exe 실행

 

STS4 는 스프링 부트 환경을 제공하므로 추가 플러그인 설치 필요

 

이클립스- Help - Eclipse MarketPlace =>

1. sts3 검색 후 Tool Install

2. Eclipse Enterprise Java and Web Developer Tools 플러그인 설치

 

+이클립스  문자 인코딩 설정

+서버 런타임 환경설정 (톰캣)

 

[  Maven Framework 설정파일 다운로드  ]

Maven – Download Apache Maven

 

Maven – Download Apache Maven

Downloading Apache Maven 3.8.4 Apache Maven 3.8.4 is the latest release and recommended version for all users. The currently selected download mirror is https://dlcdn.apache.org/. If you encounter a problem with this mirror, please select another mirror. I

maven.apache.org

1. 다운 => 압축풀기 -> 폴더안에 repository라는 폴더를 하나 만든다

(기본 라이브러리 저장 경로가 너무 깊숙이있어 초기화시 어려우므로 변경을 위해)

conf -> settings 들어가서 수정

주석 처리된 란 부분을 찾아 아래에

<localRepository>생성한 repository 폴더의 경로 </localRepository> 입력

 

2. preferences -> maven 검색 -> User Settings browse클릭 ->  conf -> settings 선택

 

---Maven이란??-------------------------------------------------------------------

아파치에서 제공.

자바용 프로젝트 관리 도구로 POM xml

(POM : 하나의 프로젝트에서 사용하는 자바 버전, 라이브러리, 플러그인 구성을 통합하여 관리할 수 있게 각 설정 정보를 XML로 문서화 한 것을 말한다)

문서를 통해 

해당 프로젝트의 버전 정보 및 라이브러리 정보들을 통합하여 관리하는 프레임워크

일반적 프로젝트는 가발자가 필요한 라이브러리를 직접 찾아서 추가해야 하지만

Maven을 사용하면 pom.xml 문서에 등록하여 자동 추가되게 하면서 라이브러리 관리 편리성을 제공

--------------------------------------------------------------------------------------

 

 

+ Recent posts