Spring

반응형

시작하기에앞서 참고 자료

 

*ibatis 비교문 지원 태그

 

isNull : "널일경우"

isNotNull : "널이아닐경우"

isEmpty : "공백일경우"

isNotEmpty : "공백이아닐경우"

isGreaterTan : ">"

isGreaterEqual : ">="

isLessThan : "<"

isLessEqual : "<="

isEqual : "=="

isNotEqual : "!="

 


*ibatis : mybatis 버전


MyBatis 비교문 지원 태그

 

<if>  : 단일 조건문

<choose> <when> <otherwise> : 다중 조건문

 

*ibatis에는 isNull, isEmpty가 있었지만 MyBatis에는 없다.

 

 

문자열 비교


paraName1 이라는 파라미터가 null이 아니면서 값이 "test"와 동일한가?

 <if test='paraName1 != null  and(paraName1 eq "test".toString())'>

 </if>

paraName1 이라는 파라미터가 "all" 이라는 문자와 동일 하지 않은가?

<if test='!paraName1.equals("all")'>
   
</if>

 

대소문자 관계없이 비교


paraName1 이라는 파라미터가 null이 아니면서 값이 "test" or "TEST"와 동일한가?

<if test='paraName1 !=null  and paraName1.equalsIgnoreCase("test")'>

 </if>

 

특정 비교


paraName1 이라는 파라미터의 값이 "Y"인지 검사할 경우

<if test='paraName1== "Y"'></if>

 

paraName1 이라는 파라미터의 값이 공백인지 검사할 경우

<if test='paraName1 == " "'></if>

 

주의 : 작은 따옴표가 있어야 한다.

 

 

숫자 비교


paraName1 이라는 파라미터의 값이 3보다 큰가?

<if test='paraName1 > 3'></if>    

paraName1 이라는 파라미터의 값이 3보다 크거나 같은가?                                     

<if test='paraName1 >= 3'></if>

paraName1 이라는 파라미터의 값이 3보다 작은가?  

<if test='paraName1 < 3'></if>

paraName1 이라는 파라미터의 값이 3보다 작거나 같은가?

<if test='paraName1 <= 3'></if>

paraName1 이라는 파라미터의 값이 숫자로 문자열일 경우

<if test='paraName1 > "3"'></if>
//비교할 값을 쌍 따옴표로 묶어준다.

 

주의

요소 유형 "null"과(와) 연관된 "test" 속성의 값에는 '<' 문자가 포함되지 않아야 합니다.

이러한 예외가 발생하였다면?

 

원인

if 태그 안에 ">" 괄호를 인식하지 못하는 거다. 그렇다면 CDATA를 쓰면 어떨까? 역시 적용되지 않는다.

일단 원인은 ">" 괄호를 XML Parsing으로 인식한 건데, XML Parsing을 Text로 바꿔주는 CDATA 마저 적용되지 않는 현상

 

해결

기호

 대체식

예제

lt 

 <if test="paraName1 lt 0">

>

gt

<if test="paraName1 gt 0"> 

<= (또는 =<)

lte 

 <if test="paraName1 lte 0">

 >= (또는 =>)

gte

 <if test="paraName1 gte 0">

 

or


||가 아닌 or로 쓰셔야 합니다.

or (O)

|| (X)

 

paraName1 값이 Y이거나 paraName2의 값이 N인 경우

 

<if> 문

<if test='paraName1 == "Y" or paraName2 == "N"'></if>

<choose> 문

<choose>
<when test='paraName1 == "Y" or paraName2 == "N"'>
</choose>

 

굳이 || 사용하실 분들이 있다면 굳이!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

|amp;|amp;

<if test='paraName1 == "Y" |amp;|amp; paraName2 == "N"'></if>

 

and


&&가 아닌 and로 쓰셔야 합니다.

and (O)

&& (X)

 

paraName1 값이 Y이고 paraName2의 값이 N인 경우

 

<if> 문

<if test='paraName1 == "Y" and paraName2 == "N"'></if>

<choose> 문

<choose>
<when test='paraName1 == "Y" and paraName2 == "N"'>
</choose>

 

굳이 && 사용하실 분들이 있다면 굳이!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

&amp;&amp;

<if test='paraName1 == "Y" &amp;&amp; paraName2 == "N"'></if>

 

null,nullString 체크


<if test='paraName1 == null'></if>
<if test="paraName1 == null"></if>

<if test="!paraName1.equals('') and paraName1!=null">

</if>

<if test="paraName1!=null and !paraName1.equals('')">

</if>

 

정리

1.문자열 비교

2.특정 비교

3.숫자 비교

4.or

5.and

6.null 체크

JPA 쓰자!!!!!!!!!!!!!!!!!!!!!

 

 

MyBatis 속성

다음은 MyBatis에서 제공 해주는 속성들을 알아보겠습니다.

반응형
반응형

궁금은 했지만 알아보기 귀찮은 #{} ${} 개념과 차이점을 아주 명확하고 확실하게 알아보도록 하겠습니다.

 

먼저 PreparedStatement 와 Statement를 알아야 한다.

 

간단하게 할게요;;

 

 

PreparedStatement


String sqlstr = "SELECT name, memo FROM TABLE WHERE num = ? " 
PreparedStatement stmt = conn.prepareStatement(sqlstr); 
pstmt.setInt(1, num);
ResultSet rst = pstmt.executeQuerey(); 

메모리에 올라가게 되므로 동일한 쿼리의 경우 , 매번 컴파일 되지 않아도 된다는 이점 성능

 

Statement


String sqlstr = "SELECT name, memo FROM TABLE WHERE num = " + num 
Statement stmt = conn.credateStatement(); 
ResultSet rst = stmt.executeQuerey(sqlstr); 

executeQuerey() 마다 매번 컴파일함 성능

 

주인공 아니니까 여기까지 자세한건 검색~

 

#{}

 

사용 과정


1.#{} 사용시 PreparedStatement 생성

2.PreparedStatement 매개 변수 안전하게 설정

3. PreparedStatement 제공하는 set 계열의 메소드를 사용하여 물음표(?) 대체할 값을 지정.

4.들어오는 데이터 문자열로 인식하기 때문에 자동 따옴표 붙음

들어오는 데이터 문자열로 인식하기 때문에 자동 따옴표 붙음

들어오는 데이터 문자열로 인식하기 때문에 자동 따옴표 붙음

 

 

사용 이유


안전하고 빠르기 떄문에 선호

빠를까??

Prepared (준비)

여기서 말하는 준비는 컴파일(Parsing) 을 이야기하며, 컴파일이 미리 되어있는 녀석이기에 Statement 에 비해 성능상 이점

 

 

문법


SELECT count(*) FROM 
ExUSER_TB
WHERE USER_ID = #{id} AND USER_PW = #{pw}
SELECT count(*) FROM ExUSER_TB 
WHERE 
USER_ID = ? AND USER_PW = ?

 

${}

 

사용 과정


1.${} 사용시 Statement 생성

2.Statement 매개변수 그대로 전달

그 대 로

3.전달 하기 떄문에 문자열에 따옴표가 붙지 않는다.

예) select * from Extable where Statementparameter = 홍길동

4.테이블 컬럼 타입이 varchar여도 숫자 그대로 들어가기 떄문에

예) select * from Extable where Statementparameter(varchar 타입) = 1

 

사용 이유


다른 이유도 있겠지만 가장 이유는 이거인거 같다.

바로 ORDER BY 함수를 사용할 오히려 자동 따옴표가 붙으면

함수가 안먹기 때문에 ${} 써야한다.

 

 

문법


SELECT count(*) FROM 
ExUSER_TB 
WHERE USER_ID = "${id}" AND USER_PW = "${pw}"
ORDER BY $ {columnName}

굳이

굳이!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

 

단점


SQL Injection 같은 문제에 취약하다. 왜냐하면 문자열을 직접 삽입하기 때문이다.

 

 

*SQL Injection : 나쁜놈들이 DB 옆구리 찌르는 기술.

 

 

정리

1.#{} 자동으로 값에 따옴표가 붙고 성능 좋음

2.${} 그대로 전달 따옴표 안붙음 성능 좋지 않음 보안 취약

3.ORDER BY 아니면 #{} 쓰기.

 

반응형
반응형

오키에 어떤 멋진 선배님이 덧글로 남긴 거 퍼옵니다. 

 

사항들만 지켜도 오류(예외) 해결 됩니다.

하나하나 다시 되돌아보시기 바랍니다.

 

1. 에러 출력되는 부분은 없습니까?

 

2. 디비 설정이 디비명, 테이블명 칼럼명 등 대소문자 구분합니까?

 

  - 디비 설정에서 리눅스 혹은 다른 OS 마다 설정이 다를 수 있습니다.

 

3. 파라미터 타입이 Object 인지 String인지 Integer HashMap 등 적절하게 작성되어있습니까?

  - 잘 맵핑되지 않아서 로그 출력상에는 정상적이지만 mybatis 딴에는 문제가 있을 수 있습니다.

 

4. 파라메타 변수가 ${}와 #{}를 적절히 사용하셨습니까?

 

5. 마이 바티스 설정 시 드라이버나 파라미터 값은 정상적이게 기입되어있습니까?

 

  - MySQL / MariaDB 등 호환은 되지만 가끔 의문의 오류가 있을 때가 있습니다.

  - UTF-8 등 세팅을 정상적으로 하지 않으면 오류가 있을 수 있습니다.

 

6. 칼럼 타입은 문제가 없습니까?

 

7. 서버와 로컬 MySQL 버전이 틀리지는 않습니까?

  - 버전별로 쿼리문에 변화가 약간 있어야 합니다.(ex : inet6 같은 함수가 지원되는지 안되는지 등)

반응형
반응형

MariaDB Select문으로 여러 카운터 데이터를 받을 게 있어서 한번 쓸건대,

DTO 만들기 뭐해서 "HashMap으로 받자~" 했는데

겁나 삽질한 적이 있었다. 다음 사람은 그러지 말라고 글을 재빠르게 올리겠습니다.

 

이 글은 Spring MVC , MyBatis , MySQL(MariaDB) 기준으로 설명하는 글입니다.

 

문법


클라이언트 (ajax)

function getUserCount() {
$.ajax({
url : "/jquery/getUserCount.do",
success : function(data) {
var html = '';
html += '<span>'+data['DB 조회된 컬럼명']+'</span>';
html += '<span>'+data['DB 조회된 컬럼명']+'</span>';
$("#jspTagView").empty();
$("#jspTagView").append(html);
}

//데이터는 data['DB 조회된 컬럼명']으로 뽑으면 됩니다.

 

Controller

@RequestMapping("jquery/getUserCount.do")
public @ResponseBody HashMap<String, Object> getUserCount() {	
HashMap<String, Object> result = service.getUserCount();
return result;
}

Service

HashMap<String, Object> getUserCount();

ServiceImpl

@Override
public HashMap<String, Object> getUserCount() {
return dao.getUserCount();
}

DAO

public HashMap<String, Object> getUserCount() {
return sqlSession.selectOne(NS+"getUserCount");
}
//여러 줄의 DB 데이터를 받을꺼면 sqlSession.selectList();

MyBatis

<select id="getUserCount" resultType="hashmap">
	Query 작성
</select>

Select 문 여러 개 Count 조회하기 DB 쿼리

 

 

[Mysql || MariaDB] Select 문 한번에 여러 개 Count()카운트 조회

사용 이유 Select 문으로 다양한 Count 개수를 뽑아 낼 때 문법 및 예시 select count(CASE WHEN column=조건 THEN 1 END) as 별명(생략가능), count(CASE WHEN column=조건 THEN 1 END) as 별명(생략가능) from..

java119.tistory.com

 

반응형

[Spring] @Scheduled

2019. 10. 30. 19:18
반응형

@Scheduled Spring 3.1 이상부터 지원합니다.

 

1.Annotation 사용 방법

2.XML 사용 방법

 

글에서는 1.Annotation 사용 방법만 다루고 있습니다. 참고 바랍니다.

 

Annotation 설정

 

@Scheduled

 

개념


주기적인 작업이 있을 때 @Scheduled 애노테이션을 사용하면 쉽게 적용할 수 있다.

Linux 조금 배우신 분들이라면 Linux의 crontab이라고 생각하면 됩니.

 

 

사용 이유


특정시간 혹은 몇분 혹은 몇시간마다 동작해는 스케쥴러를 구현

주기적인 작업이 필요

 

문법


먼저 새로운 기술은 항상 그렇듯 XML 설정을 해줘야 한다.

 

새로운 XML 만들거나 기존에 쓰던 XML 다음과 같은 문구를 추가 한다.

 

1.새로운 XML 만들어 추가하는 방법

<!--?xml version="1.0" encoding="UTF-8"?-->
<beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:task="http://www.springframework.org/schema/task"
             xsi:schemalocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    <task:annotation-driven>
</task:annotation-driven>
</beans>

 

2.기존 XML 추가하는 방법

xmlns:task="http://www.springframework.org/schema/task"
 xsi:schemalocation="
 http://www.springframework.org/schema/task
 http://www.springframework.org/schema/task/spring-task-3.0.xsd">
 <task:annotation-driven>
</task:annotation-driven>

 

사용 예시

@Scheduled(fixedDelay=1000)
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

메소드 위에 @Scheduled 어노테이션을 붙여주면 끝이다.

 

cron은 CronTab에서의 설정과 같이 cron="0/10 * * * * ?" 과 같은 설정이 가능하고

 

fixedDelay은 이전에 실행된 Task의 종료시간으로 부터 정의된 시간만큼 지난 후 Task를 실행한다.

fixedRate은 이전에 실행된 Task의 시작시간으로 부터 정의된 시간만큼 지난 후 Task를 실행한다.

 

fixedDelay fixedRate 시간 단위는 밀리세컨드이다.

 

cron="0/10 * * * * ?" (리눅스 crontab 같은 설정방법)

람다식을 처음 마주한거같은 느낌은 뭘까?

 

cron 대해서 알아보자

 

 -초 0-59 , - * / 

 -분 0-59 , - * / 

 -시 0-23 , - * / 

 -일 1-31 , - * ? / L W

 -월 1-12 or JAN-DEC , - * / 

 -요일 1-7 or SUN-SAT , - * ? / L # (1:일, 2:월, 3:화, 4:수, 5:목, 6:금, 7:토)

 -년(옵션) 1970-2099 , - * /

 

* : 모든 값

? : 특정 값 없음

- : 범위 지정에 사용

, : 여러 값 지정 구분에 사용

/ : 초기값과 증가치 설정에 사용

L : 지정할 수 있는 범위의 마지막 값

W : 월~금요일 또는 가장 가까운 월/금요일

# : 몇 번째 무슨 요일 2#1 => 첫 번째 월요일

 

크론 표현식에서는 6~7 자리 가 사용됩니다.

cron = "* * * * * *"

 

왼쪽부터 작은 단위 [ 요일 (생략가능)]

왼쪽부터 작은 단위 [ 요일 (생략가능)]

왼쪽부터 작은 단위 [ 요일 (생략가능)]

 

가지 예시

 

[매일 오후 1시에 실행할 cron 만들기]

일단 0 0분이죠

@Scheduled(cron="0 0")

오후 1시래요 24 표기법이니까

@Scheduled(cron="0 0 13")

매일

@Scheduled(cron="0 0 13 * * ?")

 

[ 금요일 새벽5 30 실행할 cron 만들기]

0 30 새벽 5

@Scheduled(cron="0 30 05 ")

매주 금요일

@Scheduled(cron="0 30 05 * FRI ?")

 

자세한 문법 예시는 밑에

 

수많은 문법 예시

//1초 마다 실행
@Scheduled(fixedDelay=1000)
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }


//5초 마다 실행
@Scheduled(fixedDelay=5000)
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }


//10초 마다 실행
@Scheduled(fixedDelay=10000)
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }


//매일 5시에 실행
@Scheduled(cron="0 0 05 * * ?")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }


//매월 2일,20일 새벽2시에 실행
@Scheduled(cron="0 0 02 2,20 * ?")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }


//매월 마지막날 저녁 10시에 실행
@Scheduled(cron = "0 0 10 L * ?")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

//1시간 마다 실행 ex) 01:00, 02:00, 03:00....
@Scheduled(cron = "0 0 0/1 * * *")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }


//매일 오후 18시마다 실행 ex) 18:00
@Scheduled(cron = "0 0 18 * * *")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

//매일 오후 18시00분-18시55분 사이에 5분 간격으로 실행
@Scheduled(cron = "0 0/5 18 * * *")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }


//매일 오후 9시00분-9시55분, 18시00분-18시55분 사이에 5분 간격으로 실행
@Scheduled(cron = "0 0/5 9,18 * * *")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

//매일 오후 9시00분-18시55분 사이에 5분 간격으로 실행
@Scheduled(cron = "0 0/5 9-18 * * *")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

//매달 1일 00시에 실행
@Scheduled(cron = "0 0 0 1 * *")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");

    }

//매년 3월내 월-금요일 10시 30분에만 실행
@Scheduled(cron = "0 30 10 ? 3 MON-FRI")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

 

여기서 잠깐!

스케줄 돌릴 메소드에 리턴타입과 매개변수를 없다.

 

디테일한 설정들

cron : cron 표현식을 지원한다. "초 분 시 일 월 주 (년)"으로 표현한다. cron 표현식에 쓸 수 있는 것들(특수문자 활용 포함)이 많은데

 

fixedDelay : milliseconds 단위로, 이전 작업이 끝난 시점으로 부터 고정된 시간을 설정한다.

@Scheduled(fixedDelay=5000)
public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

fixedDelayString : fixedDelay와 같은데 property의 value만 문자열로 넣는 것이다.

@Scheduled(fixedDelay="5000")
public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

fixedRate : milliseconds 단위로, 이전 작업이 수행되기 시작한 시점으로 부터 고정된 시간을 설정한다.

@Scheduled(fixedRate = 3000)
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

fixedRateString : fixedDelay와 같은데 property의 value만 문자열로 넣는 것이다.

@Scheduled(fixedRate = "3000")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

initialDelay : 스케줄러에서 메서드가 등록되자마자 수행하는 것이 아닌 초기 지연시간을 설정하는 것이다.

@Scheduled(fixedDelay = 3000,initialDelay = 1000)
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

initialDelayString : 위와 마찬가지로 문자열로 값을 표현하겠다는 의미다.

@Scheduled(fixedDelay = 3000,initialDelay = "1000")
    public void testScheduler(){
        System.out.println("스케줄링 테스트");
    }

zone : cron표현식을 사용했을 때 사용할 time zone으로 따로 설정하지 않으면 기본적으로 서버의 time zone이다.

 

다음은 동적으로 스케줄러를 멈추고 시간주기를 바꾸는 법에 대해 포스팅 하겠습니다.

반응형
반응형

DTO(Data Transfer Object)

 

개념


이름과 같이 계층 간 데이터 교환을 위해 사용하는 객체다.

*여기서 말하는 계층이란, View - Controller - Service - DAO와 같은 각 계층을 말한다.

VO와 혼용되어 쓰이나, 이는 보통 DTO를 지칭하는 말이다.

데이터를 담을 private 변수와 그 변수를 조작할 수 있는 Getter, Setter 메서드로 구성돼있음..

 

데이터를 오브젝트로 변환하는 객체 Getter, Setter 메서드로 구성!

 

 

사용 이유


form, ajax에서 name 필드 값을 프로퍼티에 맞춰서 값을 다른 페이지로 넘겼을 시 ,

값을 받아야 할 페이지에서는 값을 하나씩 일일이 받는 것이 아니라 name 속성의 이름이랑 매칭 되는 프로퍼티에 자동적으로 DTO가 인스턴스화 되어 UserDTO를 자료형으로 값을 받을 수 있음

 

말이 어려워졌는데, 한 상황으로 정리하겠습니다.

DB : 데이터 줄게

DAO : 일일이 담기 귀찮다. 딱 맞는 바구니에 담을 수 없을까?

DAO : 아 유레카! 주는 데이터에 맞춰서 데이터 형식들을 만들어 놓은

클래스를 만들어야겠군 이름은 DTO라고 불러야겠다.

 

DB 값 → DAO Service DTO

 

문법


List<Company>  result = menuservice.getCompanyList();
//getCompanyList() == select * from Company;
//DB 컬럼 이름에 맞춘 Company 클래스(DTO)에 자동으로 데이터 삽입됨
//예시 DTO
public class Company {

private int id;

private String name;

private String address;

private String registration_number;

private String representative;

private String description;

private String created_on;

private String updated_on;

public int getId() {
return id;

}

public void setId(int id) {
this.id = id;

}

public String getName() {
return name;

}

public void setName(String name) {
this.name = name;

}

public String getAddress() {
return address;

}

public void setAddress(String address) {
this.address = address;

}

public String getRegistration_number() {
return registration_number;

}

public void setRegistration_number(String registration_number) {
this.registration_number = registration_number;

}

public String getRepresentative() {
return representative;

}

public void setRepresentative(String representative) {
this.representative = representative;

}

public String getDescription() {
return description;

}

public void setDescription(String description) {
this.description = description;

}

public String getCreated_on() {
return created_on;

}

public void setCreated_on(String created_on) {
this.created_on = created_on;

}

public String getUpdated_on() {
return updated_on;

}

public void setUpdated_on(String updated_on) {
this.updated_on = updated_on;
}

@Override
public String toString() {
return "Company [id=" + id + ", name=" + name + ", address=" + address + ", registration_number="
+ registration_number + ", representative=" + representative + ", description=" + description
+ ", created_on=" + created_on + ", updated_on=" + updated_on + "]";
}
}

VO(Value Object)

 

개념


값을 가진 객체

데이터만 가지고 있다는 것만 보면 DTO와 비슷한데,

가장 큰 특징은 value가 같으면 같은 객체라고 보는 거예요.

Company a = new Company("대기업");
Company b = new Company("대기업");

a.hashCode();
b.hashCode();

해쉬 값이 동일하다. 즉 같은 것으로 판단

 

그리고  read-only 값을 가지고 있음 즉, 변하지 않는 immutable 한 성질을 가지고 있음. 중간에 값을 바꿀 수가 없음.

 

 

문법


DTO와 VO를 구분할 수 있는 아주 좋은 형태

get/set = DTO

get = VO

 

setter는 없고 getter만 있는 형태!

public class BoardVO {
	
	private int id;
	private String subject;
	private String context;
	private String attachments;
	private int likes;
	private int views;
	private int writer;
	private Date create_time;
	public int getId() {
		return id;
	}
	public String getSubject() {
		return subject;
	}
	public String getContext() {
		return context;
	}
	public String getAttachments() {
		return attachments;
	}
	public int getLikes() {
		return likes;
	}
	public int getViews() {
		return views;
	}
	public int getWriter() {
		return writer;
	}
	public Date getCreate_time() {
		return create_time;
	}
	
	@Override
	public String toString() {
		return "BoardVO [id=" + id + ", subject=" + subject + ", context=" + context + ", attachments=" + attachments
				+ ", likes=" + likes + ", views=" + views + ", writer=" + writer + ", create_time=" + create_time + "]";
	}
	
}

DTO VS HashMap


DTO 쓰지 않고 HashMap을 쓰면 안 될까?

 

가장 큰 이유는 compile time 오류와 관련 있습니다.

HashMap은 컴파일 시에 오류를 잡아내질 못합니다.

 

DTO

dto.setName("gildong");
String name = dto.getName();

HashMap

map.put("name", "gildong");
String name = map.get("name");

정리


HashMap 단점

 

1. 해쉬 맵은 get이나 put에서의 key가 잘못돼도 컴파일 시에는 에러를 잡아내질 못함.

     즉, map.put("names")라고 해도 에러가 나질 않죠.

     반면에, dto.steNames() 나 dto.getNames()는 에러가 나서 컴파일조차 되지 않을 겁니다.

 

2. 데이터 타입에 대한 에러를 잡아내질 못합니다.

    String인지 Integer인지를 컴파일 시에는 모르죠.

 

3. 해쉬 맵은 프로그램 말고도 별도의 정보가 필요합니다.

    dto는 그 자체가 필요한 정보를 담고 있습니다.

    name, address, age 등 dto의 정의만 봐도 대충은 알 수 있는데 반하여,

    해쉬 맵은 이 데이터를 정의한 다른 문서가 필요합니다.

    이는 규모가 큰 프로그램일수록 더 필요하죠.

 

HashMap 장점 및 사용 이유

 

1. 데이터의 필드들이 가변적인 경우

2. 매우 복잡한 구조로 되어 있어 DTO로 규정하기는 곤란한 경우

3. DTO가 너무나 많아지는 경우

4. 한 select 문 쿼리에 여러 개의 count 정보를 담을 때

5. 한번 쓸건데, 이걸 위해 DTO를 만들기도 뭐할 때

 

반응형
반응형

 

개념


GET과 POST는 HTTP프로토콜을 이용해서 서버에 무언가를 전달할 때 사용하는 방식입니다.

 

전달하는 방식~ 전달하는 방식이에요 방식!

 

큰 차이점은 데이터가 어디에 위치하는가에 있습니다. POST 요청시에 URL에 파라미터가 보이지 않는 이유는 데이터가 요청 바디에 포함되기 때문입니다. 그렇기 때문에 GET과 POST에 따라 데이터를 URL에 추가해야할지 요청 바디에 추가해야할지를 알고 있어야만 합니다. 

 

 

GET 방식과 POST방식의 장단점 및 차이점


1.Select 기능을 원한다면 GET 메서드, Update 기능을 원한다면 POST 메서드  

2.검색 결과 등 고정적인 주소 및 링크 주소로 사용될 수 있다면 GET 메서드를 사용  

3.정보를 담을 URL길이(최대 2048자)는 한계가 있기 때문에 이를 해결하고 싶다면 POST 메소드를 사용

4.POST 메서드를 쓰면 정보를 숨길 수 있다. 하지만 SSL(Secure Sockets Layer)를 사용안하면 GET과 마찬가지

5.GET은 캐시가 남아있어 전송 속도가 빠르고 POST는 캐시가 남지 않아 보안적인 면에서 유리 

6.GET은 브라우저 히스토리에 파라미터가 남고 POST는 저장되지 않는다.  

 ) http://url/.javatis.com?id=22&pw=11 URL 중요 파라미터 노출

7.GET은 ASCII캐릭터만 허용하나 POST는 한계가 없다. POST는 바이너리 데이터가 허용된다. 따라서 파일 입출력을 위해 POST메소드가 이용된다

 

 

정리

사람 : 누구야 get post 차이가 뭐냐?

누구 : 두가지 모두 HTTP 전송 방식의 타입입니다.

GET 일단 SELECT 기능면에서 우수하여 SELECT 기능으로 많이 쓰고,캐시가 남아있어 보안적인 측면이 좋지 않으나, 전송속도가 우수하고 파라미터가 url 노출되는 점이 있습니다.

POST 주로 CREATE,UPDATE,DELETE 사용되며,캐시가 남지 않아 보안적인 면에서 좋고 요청 Request Body 데이터가 들어가기 때문에 파라미터가 노출 되지 않는점이 차이점입니다.


 

일단 이론은 대충 알겠고, 그래서 어떻게 어느 상황에 써야 하는거야?

 

HTTP 결국엔

클라이언트 -> 서버 요청 방식인데..

이걸 보낼때 전송방식 대표로 GET,POST 있답니다. 외에도 PUT, DELETE 나중에

 

GET(Read) 즉 SELECT 할때쓰는것이적당합니다.

SELECT

서버에 데이터를 가져와 보여주기 위함

 

POST(Create) INSERT 할때 쓰는것이 적당합니다.

INSERT,update,delete

서버의 ,상태를 바꾸기 위함

 

 

문법


공통

$(document).ready(function() {

signUp();

getUserList();

})

 

GET 방식


Client

function getUserList(){
$.ajax({
type : "GET",
data : { id : "gildong", pw : 119}),
url : "/jquery/signUp.do",
success:function(data){
console.log(data);
}
})
}

 

Server (Spring mvc Controller)

@RequestMapping(value="jquery/getUserListEx.do",method=RequestMethod.GET)

@ResponseBody

public List<Object> getUserListEx(SignUp signUp){

System.out.println("getUserListEx.do GET & id / PW : " + signUp.toString());

List<Object> list = null;

//list = service.getmethod();

return list;

}

GET 정보


 

POST JSON.stringify() 방식


VO Class

public class SignUp {

	private String id;
	private String pw;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPw() {
		return pw;
	}
	public void setPw(String pw) {
		this.pw = pw;
	}
	
	@Override
	public String toString() {
		return "SignUp [id=" + id + ", pw=" + pw + "]";
	}
	
}
//pom.xml dependency 추가

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

<version>2.9.5</version>

</dependency>

//이 라이브러리를 추가 안해주면 HTTP 415 에러를 만나게된다.

 

(Client 형식 JSON === Server 형식 JSON 맞춰줘야한다.)

 

Client

function signUp(){

$.ajax({
type : "POST",
dataType : 'json',
contentType : "application/json;charset=UTF-8",
data : JSON.stringify({
id : "gildong",
pw : 119,
}),
url : "/jquery/signUp.do",
success:function(data){
console.log(data);
}
})
}

(@ResponseBody @RequestBody 헷갈림 주의 부릅)

 

Server (Spring mvc Controller)

@RequestMapping(value="jquery/signUp.do",method=RequestMethod.POST,produces = "application/json;charset=UTF-8")
@ResponseBody
public SignUp signUp(@RequestBody SignUp signUp){
//menuservice.signUpMethod(signUp);
System.out.println("signUp.do POST & id : " + signUp.toString());
return signUp;
}

POST 정보

 

 

GET & POST 결과

 

 

외에도 $("#form").serialize() , $.get , $.post , 폼 파라미터 넘기기 방식이 있습니다.

 

대표로 자주 쓰이는 문법을 정리 해봤습니다.

반응형

[Spring] annotations 정리

2019. 10. 16. 14:15
반응형

Annotation(어노테이션 || 애너테이션 || 애노테이션)이란?

아하영어사전 - 애너테이션

http://aha-dic.com/View.asp?word=Annotation

대중적인 발음 - 어노테이션

여기선 어노테이션이라 칭하겠음

 

1.본래 주석이란 뜻으로 사용됨

2.인터페이스를 기반으로 문법

3.클래스에 특별한 의미 부여 || 기능 주입 가능

 

종류

1.built-in annotation

) Override

2.Meta annotation

) @Target

3.Custom annotation

)public @interface AnnotationName{}

 

쨋든 글에서 다루어볼것은 Spring 프레임워크에 들어있는 자주쓰이는 기본 어노테이션들을 다루어 보겠습니다.

 

[@Controller]

해당 클래스가 Controller임을 나타내기 위한 어노테이션

 

[@RequestParam]

Controller 메소드의 파라미터와 웹요청 파라미터와 맵핑하기 위한

어노테이션

 

[@ModelAttribute]

Controller 메소드의 파라미터나 리턴값을 Model 객체와 바인딩하기 위한 어노테이션

 

[@SessionAttributes]

Model 객체를 세션에 저장하고 사용하기 위한 어노테이션

 

[@RequestPart]

Multipart 요청의 경우, 웹요청 파라미터와 맵핑 가능한 어노테이션

 

[@CommandMap]

Controller메소드의 파라미터를 Map형태로 받을 때 웹요청 파라미터와 맵핑하기 위한 어노테이션(egov 3.0부터 추가)

 

[@ControllerAdvice]

Controller를 보조하는 어노테이션으로 Controller에서 쓰이는 공통기능들을 모듈화하여 전역으로 쓰기 위한 어노테이션(egov 3.0, Spring 3.2.X부터 추가)

 

[@RequestMapping]

 

이름

타입

설명

value

String[]

URL 값으로 매핑 조건을 부여 (default)

method

RequetMethod[]

HTTP Request 메소드 값을 매핑 조건으로 부여

사용 가능한 메소드는 GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE (7개)

params

String[]

HTTP Request 파라미터를 매핑 조건으로 부여

consumes

String[]

설정과 Content-Type request 헤더가 일치할 경우에만 URL이 호출됨

produces

String[]

설정과 Accept request 헤더가 일치할 경우에만 URL이 호출됨

 

 

[@ResponseBody

이 어노테이션이 붙으면 View Page를 리턴하는게 아니고 '데이터'를 리턴합니다.

즉, return type이 String이며 "home"이라는 문자열을 되돌려준다고 가정해볼께요.

@ResponseBody 어노테이션을  안붙이면 "home.jsp" 페이지를 보여주지만

어노테이션을 붙이게되면 "home"이라는 문자열 자체를 보여주게됩니다. 

 

[@RequestBody]

보통 AJAX + JSON을 사용할때 사용하는 어노테이션

요청받은 데이터의 Body(내용)의 전체내용을 파라메터로 받습니다.

 

View페이지의 AJAX요청의 contentType이 "application/json"이면 @RequestBody 어노테이션을 통해서만

웹서버에서 내용을 받을 수 있어요.

 

※주의 ResponseBody,RequestBody 문법 헷갈림 

 

[@RestController]

 

스프링 4 부터 @RestController 애노테이션의 경우 기존의 특정한 JSP 같은 뷰를 만들어 내는 것이 아닌REST

  식의 데이터 자체를 서비스하는 것을 말한다.

  - 스프링 3에는 해당 메소드의 리턴 타입에 @ResponseBody 애노테이션을 추가하는 형태로 작성되었다.

  - 기능은 달라진것이 없지만컨트롤러 자체의 용도를 지정한다는 점에서 변화가 있다고   있다.

  - URI 원하는 리소스를 의미한다.(복수형으로 작성)

  - URI에는 식별할  있는 데이터를 같이 전달하는 것이 일반적이다.

 

  // 컨트롤러 위에 어노테이션을 붙혀서 사용한다.

 import org.springframework.web.bind.annotation.RequestMapping;

 import org.springframework.web.bind.annotation.RestController;

 

 @RestController

 @RequestMapping("/sample")

 public class RestControllerExampleController {

 

 }

 

 만약 import 오류가 발생하면 maven webmvc 버전을 확인하라.

 

 @RestController JSP 같은 뷰를 만들어 내지 않는 대신에 데이터 자체를 반환하는데이때 주로 사용되는 것은 단순 문자열과 JSON, XML, 등으로 나누어   있다.

 

 

이상 글을 마칩니다. 글은 계속해서 공부하고 싶은 어노테이션들이 추가될 예정입니다.

반응형

+ Recent posts