javascript - 정규표현식

Front-End/javascript 2019. 6. 11. 21:46

  -정규표현식-

 

  문자열에서 특정한 문자를 찾아내는 도구이다.

 

  이 도구를 이용하면 수십줄이 필요한 작업을 한 줄로 끝낼 수 있다.

 

 

 

  -정규표현식 생성-

 

  정규표현식은 두가지 단계로 이루어진다.

 

  하나는 컴파일 (compile) 다른 하나는 실행 (execution) 이다. 

 

 

 

  -컴파일-

 

  컴파일은 검출하고자 하는 패턴을 만드는 일이다.

 

  우선 정규표현식 객체를 만들어야 한다.

 

  객체를 만드는 방법은 두가지가 있다.

 

  a라는 텍스트를 찾아내는 정규표현식의 2가지 방법이다.

 

 

 



  -패턴을 만드는 방식-


  1. 정규표현식 리터럴


  var pattern = /a/    //  "/"와 "/" 사이의 문자열을 pattern에 넣는다. (이것을 사용해 문자 찾기 가능)


  2. 정규표현식 객체 생성자


  var pattern = new RegExp('a');     // RegExp 객체를 만들어서 찾고자 하는 문자 'a'를 넣어서 pattern에 넣는다.

 

 

 

  -실행-

 

  컴파일로 만든 패턴을 가지고 패턴을 실행해서 문자를 찾는것.

 

 

 

  -정규표현식 메소드 실행-

 

 

  
  RegExp.exec( ) 메소드 (해당 문자열 추출) : 해당하는 문자열이 있으면 그 문자열을 값으로 하는 배열을 리턴하고 없으면 null을 리턴한다.


  RegExp.test( ) 메소드 (해당 문자열 있는지 테스트) : 패턴에 해당되는 문자열이 있으면 true, 없으면 false를 리턴한다.

 

 

 

 -정규표현식 메소드 사용 예제-

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var pattern = /a/ //pattern 변수에 a라는 패턴을 넣음.
undefined
 
console.log(pattern.exec('sdfsdf')); //exec( ) 메소드를 사용해서 'sdfsdf' 안에는 'a'라는 문자열이 없기 때문에 null을 리턴한다.
VM1136:1 null
undefined
 
console.log(pattern.exec('basd')); //exec( ) 메소드를 사용해서 'basd' 안에는 'a'라는 문자열이 있기 때문에 ["a"] 배열을 리턴한다.
VM1211:1 ["a"index: 1input: "basd", groups: undefined]
undefined
 
console.log(pattern.test('bjxs')); //test( ) 메소드를 사용해서 'bjxs' 안에는 'a' 라는 문자열이 없기 때문에 false 를 리턴
VM1286:1 false
undefined
 
console.log(pattern.test('ards')); //test( ) 메소드를 사용해서 'ards' 안에는 'a' 라는 문자열이 있기 때문에 true 를 리턴
VM1340:1 true
 
cs

 

  

 

-정규표현식 (문자열) 메소드 사용 예제-

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
var a = /2/ //a라는 변수에 2라는 패턴을 넣는다.
undefined
 
console.log('asdj2'.match(a)); // 변수 a안에 있는 2라는 패턴이 'asdj2' 안에 있기 때문에 ["2"] 를 출력
VM1486:1 ["2", index: 4, input: "asdj2", groups: undefined]
undefined
 
console.log('sndqa'.match(a)); //변수 a안에 있는 2라는 패턴이 'sndga' 안에 없기 때문에 null을 출력
VM1521:1 null
undefined
 
console.log('asdfa22'.replace(a,'11')); //변수 a안에는 2라는 패턴이 1개 들어있기 때문에 'asdfa22'에서 앞에 있는 2만 '11'로 교체해준다.
VM1653:1 asdfa112
undefined
 
console.log('asdfa55'.replace(a,'11')); //변수 a안에 있는 2라는 패턴이 'asdfa55'에는 없기 때문에 'asdfa55' 가 그대로 출력된다.
VM1681:1 asdfa55
undefined
 
cs

 

 

-옵션-

 

정규표현식 패턴을 만들 때 옵션을 설정할 수 있다.

옵션에 따라서 검출되는 데이터가 달라진다.

 

i

 

i를 붙이면 대소문자를 구분하지 않는다.

 

 

 

g

 

g를 붙이면 검색된 모든 결과를 리턴한다.

 

 

또한 i와 g를 같이 사용할 수도 있다.

(대문자, 소문자 구분하지 않고 모든 문자를 리턴한다는 뜻)

 

 

 

-옵션 사용 예제-

 

1
2
3
4
5
6
7
8
9
10
11
12
var a = /a/i // 패턴에 'i'를 붙여서 대소문자 구분하지 않고 출력되게 함.
undefined
 
"Aadnsh".match(a); // 대소문자를 구분하지 않고 'a'가 한개이기때문에 가장 앞에있는 'A'를 배열에 담아 출력함
["A", index: 0, input: "Aadnsh", groups: undefined]
 
var b = /b/g // 패턴에 'g'를 붙여 검색된 모든 결과를 리턴 (즉, 모든 'b'를 검색해서 리턴한다는 뜻.. 개수에 관계없이)
undefined
 
"bBBASb".match(b); // 'b'가 들어간 것이 2개이므로 'b'가 2개 출력된다.
(2) ["b", "b"]
 
var c = /c/ig // 패턴에 'i'와 'g'를 붙여서 대소문자를 구분하지 않고, 'c'에 개수에 상관없이 모든 'c'를 리턴한다는 뜻.
undefined
 
"cCsjJDJcCc".match(c); //대문자 'c'와 소문자 'c' 가 모두 리턴되는것을 확인할 수 있다.
(5) ["c", "C", "c", "C", "c"]
 
cs

 

 

-캡처-

 

괄호안의 패턴은 마치 변수처럼 재사용할 수 있다. 이 때 기호 $를 사용하는데 순서를 역전시킬때도 사용한다.

 

 

-예제-

1
2
3
4
5
6
7
8
 
var a = /(\w+)\s(\w+)/; // \w는 한개의 문자열을 의미, // +는 그 문자열의 개수를 의미, //\s는 공백을 의미한다.
undefined
 
var str = "Java Spring"; //str변수에 문자열을 저장
undefined
 
var result = str.replace(a,'$2-$1'); //replace는 치환할때 사용하는 메소드, a변수에 담긴 패턴을 사용하고 $를 사용해 문자순서를 뒤바꾼다.
undefined //그리고 공백은 '-' 로 치환되서 출력 된다.
 
console.log(result); //result 변수에 담긴 값을 출력함
 
VM547:1 Spring-Java
 
cs

 

 

-치환-

 

URL을 링크 html 태그로 교체한다. (이건 나중에 정규표현식만 설명한 강의 따로봐야될듯. 어려움)

아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ

토비의 스프링 3.1 세트:스프링의 이해와 원리 + 스프링의 기술과, 에이콘출판

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

'Front-End > javascript' 카테고리의 다른 글

javascript - 함수와 콜백  (0) 2019.06.12
javascript - 유효범위 (전역변수, 지역변수)  (0) 2019.06.11
javascript - UI와 API  (0) 2019.06.10
javascript - 라이브러리 (jQuery)  (0) 2019.06.09
javascript - 모듈  (0) 2019.06.09
:

상품테이블 만들기, File Upload 테스트

Back-End/Spring 2019. 6. 11. 13:36

-파일업로드 방식의 종류-


1. 일반적인 방식

    (여기서는 일반적인 방식으로 테스트)


2. 비동기적인 방식 (ajax)




1. 상품 정보를 저장할 테이블 만들기


1
2
3
4
5
6
7
8
create table product(
product_id number,
product_name varchar2(50),
price number default 0,
description clob,
picture_url varchar2(500), //varchar2는 4000바이트 까지밖에 들어가지 않는다.
primary key(product_id)
);
cs


clob : 사이즈가 큰 데이터를 외부 파일로 저장하기 위한 데이터 타입


default : 기본값 설정 (예를들어 default 0 이면 기본값이 0부터 시작한다. 기본 번호가 0부터 시작하고 증가하는 식으로 생각하면 편함)



만든 테이블에 자료를 삽입한다.


1
2
3
4
5
6
insert into product values (1,'레몬',1500,'레몬에 포함된 구연산은 피로회복에 좋습니다. 비타민 C도 풍부합니다,','lemon.jpg');
insert into product values (2,'오렌지',2000,'비타민 C가 풍부합니다. 생과일 주스로 마시면 좋습니다.','orange.jpg');
insert into product values (3,'키위',3000,'비타민 C가 매우 풍부합니다. 다이어트나 미용에 좋습니다.','kiwi.jpg');
insert into product values (4,'포도',5000,'폴리페놀을 다량 함유하고 있어 항산화 작용을 합니다.','grape.jpg');
insert into product values (5,'딸기',8000,'비타민 C나 플라보노이드를 다량 함유하고 있습니다.','strawberry.jpg');
insert into product values (6,'귤',7000,'시네피린을 함유하고 있어 감기 예방에 좋다고 합니다.','tangerine.jpg');
cs



자료를 삽입한후 삽입한 자료가 반영되도록 커밋을 실시한다.


1
commit;
cs



상품이 등록될때마다 넘버를 증가시키기위해 시퀀스를 생성


(처음 시작은 10부터 하고, 1씩 증가시키는 시퀀스를 생성한다.)


1
2
3
create sequence seq_product
start with 10
increment by 1;
cs



insert로 아래 값을 삽입한다. seq_product.nextval은 아까 10번부터 시작한다고 설정해 놓았으므로 10으로 설정됨

다음에 다시 사용한다면 11이 된다.


1
2
insert into product values
(seq_product.nextval, '사과',1500,'맛있는 사과...','apple.jpg');
cs



2. 상품 이미지를 다운로드하여 views/images 디렉토리에 복사

   ( http://mannaedu.com/bbs/board.php?bo_table=pds&wr_id=37&page=3 )



3. pom.xml (라이브러리 추가)

   ( https://mvnrepository.com )

   groupID와  artifactID를 이용해서 파일업로드와 이미지 썸네일 관련 라이브러리를 검색해서 추가한다.




pom.xml (라이브러리들 추가)

1
2
3
4
5
6
7
8
9
10
11
12
13
    <!-- 파일업로드 관련 라이브러리 -->
    <dependency>
        <groupld>commons-fileupload</groupld>
        <artifactld>commons-fileupload</artifactld>
        <version>1.3.3</version>
    </dependency>
    
    <!-- 이미지 썸네일을 만들어주는 라이브러리 -->
    <dependency>
        <groupld>org.imgscalr</groupld>
        <artifactId>imgscalr-lib</artifactId>
        <version>4.2</version>
    </dependency>
cs



4. views 하위에 images 폴더를 만들고 아까 다운받은 상품 이미지를 폴더에 넣기



5.servlet-context에서 images파일의 리소스를 맵핑 할수 있도록 코드를 추가한다.


1
<resources location="/WEB-INF/views/images/" mapping= "images/**" />
cs



6. servlet-context.xml (파일업로드 관련 설정) 코드 추가

1
2
3
4
5
6
7
8
9
10
11
12

<!-- 파일업로드에 필요한 bean -->
<beans:bean id = "multipartResolver" //스프링 프레임 워크에 내장된 빈을 추가함
class = "org.springframework.web.multipart.commons.CommonsMultipartResolver">

 
<!-- 파일 업로드 최대 용량(byte단위로) -->
    <beans:property name = "maxUploadSize" value = "10485760" /> //value에 최대 용량 설정함
    </beans:bean>


<!-- 파일 업로드를 위한 디렉토리 설정 -->
<!-- String uploadPath = new String("d:/upload"); -->
<beans:bean id = "uploadPath" class = "java.lang.String">
    <beans:constructor-arg value = "d:/upload" /> //파일이 업로드 되는 디렉토리는 d:/upload 이다.
    </beans:bean>

cs



7. menu.jsp 업로드 테스트 링크를 추가함.

1
2
3
4
5
6
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<!-- 다른페이지에 include되는 페이지 -->
<a href = "${path }/memo/list.do">한줄메모장</a> ㅣ
<a href = "${path }/upload/uploadForm">업로드 테스트</a> ㅣ //업로드 테스트 링크를 추가
cs



8. controller 패키지 하위에 upload 패키지를 만들고 UploadController.java 클래스를 추가함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.example.spring02.controller.upload;
 
import java.io.File;
import java.util.UUID;
 
import javax.annotation.Resource;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
 
@Controller
public class UploadController {
    private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
    //이 클래스의 로그를 출력하기 위한 코드, 로그저장소에서 getLogger 메소드를 사용해서 호출
    // xml에 설정된 리소스를 참조
    // bean의 id가 uploadPath인 태그를 참조
    
    @Resource(name = "uploadPath"//servlet-conetext에 저장한 빈인 uploadPath를 호출한다.
    String uploadPath; //@Resource에서 받은 리소스 값인 uploadPath가 들어오게 된다.
    
    // menu 페이지에서 이 메소드를 거치고, 맵핑할때 "/upload/uploadForm"페이지로 포워딩 된다.
    // method방식을 정하지 않으면 get방식이다. (즉 get방식일때는 이 메소드를 거친다. post방식일때는 아님)
    @RequestMapping(value = "/upload/uploadForm", method = RequestMethod.GET)
    public void uploadForm() {
        //         upload / uploadForm.jsp 로 포워딩    
    }
    //그냥 화면을 바꿀때는 get 방식을 사용하고 파일을 업로드 할때는 POST방식을 사용한다.
    
    
    //업로드 버튼 => 임시 디렉토리에 업로드
    // => 파일정보가 file에 저장
    // => 지정된 디렉토리에 저장 =>
    
    // 파일을 업로드(내용을 채울때는) 할때는 POST방식을 사용하므로 이 메소드를 거친다.
    // 메소드 이름을 다르게 할 수도 있지만 method 방식을 POST와 GET방식으로 각각 지정해서 할 수도 있다.
    @RequestMapping(value = "/upload/uploadForm", method = RequestMethod.POST)
        public ModelAndView uploadForm (MultipartFile file, ModelAndView mav) throws Exception {
        
        logger.info("파일이름 : " + file.getOriginalFilename());
        String savedName = file.getOriginalFilename();
        logger.info("파일크기:" +file.getSize());
        logger.info("컨텐츠 타입:" +file.getContentType()); //파일이름과 크기와 파일의 종류를 로그로 출력함
        
        
        
        savedName = uploadFile(savedName, file.getBytes());
        //파일을 올리고 파일의 바이트를 올리고, 저장된 파일이름 가져와서 결과페이로 보낼예정
        
        mav.setViewName("upload/uploadResult");
        mav.addObject("savedName", savedName);
        return mav; //uploadResult.jsp로 포워딩
    }
    
    //파일 이름이 중복되지 않도록 처리
        private String uploadFile(String originalName, byte[] fileData) throws Exception{
            // uuid 생성 (Universal Unique IDentifier, 범용 고유 식별자)
            // uuid를 만드는 이유는 파일을 2개 올리게 되면 이름이 중복되는데 그러다 1개가 삭제 될 수 있기 때문에
            // uuid라는 고유한 식별자를 주어서 (랜덤으로 코드를 만들어냄) 이름이 중복되지 않게 해서 삭제되지 않게끔 하려는 것이다.
            // uuid를 생성해서 그것을 파일의 이름 앞에다 붙여서 중복을 방지한다.
            
            UUID uid = UUID.randomUUID();
            String savedName = uid.toString() + "_" +originalName;
            File targer = new File(uploadPath, savedName); //파일을 실제로 저장함
            // 임시 디렉토리에 저장된 업로드된 파일을
            // 지정된 디렉토리로 복사
            // FileCopyUtils.copy (바이트배열, 파일객체)
            FileCopyUtils.copy(fileData, targer); //파일을 복사
            return savedName; //복사한 파일이름을 되돌려 준다.
        }
}
cs




9. views에 upload폴더를 만들고, uploadForm.jsp 파일을 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv = "Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file = "../include/header.jsp" %>
<style>
iframe{
width : 400px;
height : 200px;
border : 1px;
border-style : solid;
}
</style>
</head>
<body>
<%@ include file = "../include/menu.jsp" %>
<!-- enctype = "multipart/form-data" 파일 업로드 필수 옵션 
enctype = "application/x-www-form-urlencoded" 기본 옵션-->
 
 
<!-- target = "iframe" 의 name => iframe으로 전송함 -->
<form id = "form1" action = "${path }/upload/uploadForm" method = "post"
enctype = "multipart/form-data"

target = "iframe1" > //파일을 업로드 하게 되면 원래 ${path }/upload/uploadForm 경로로 가게 되는데 현재 화면에서
//화면이 넘어가지 않게 해준다. (즉, iframe1페이지에 고정됨)

<input type = "file" name = "file"> //name의 파일이름 file와 UploadController에서 이 페이지를 맵핑받은 메소드의
//MultipartFile 타입의 변수 이름이 같아야 저장이 된다.

<input type = "submit" value = "업로드">
</form>
 
<iframe name="iframe1"></iframe>
 
</body>
</html>

cs




10. views폴더 하위에 upload 폴더 안에 uploadResult.jsp 파일을 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file = "../include/header.jsp" %>
</head>
<body>
<%@ include file = "../include/menu.jsp" %>
<!-- uploadResult.jsp -->
파일이 업로드 되었습니다. <br>
파일명 : ${savedName } //그리고 이 파일이 uploadForm의 iframe로 들어간다.
</body>
</html>
cs




11. D드라이브에 업로드된 파일이 들어갈 upload 폴더 만들기






:

javascript - UI와 API

Front-End/javascript 2019. 6. 10. 21:02

-UI (User Interface)-


사용자가 지정한 인터페이스 (화면)

 

 

-API (Application Programming Interface)-


응용 프로그램 프로그래밍 인터페이스)는 응용 프로그램에서 사용할 수 있도록, 운영 체제나

 

프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

 

 

-레퍼런스와 튜토리얼-

 

튜토리얼 : 언어의 문법을 설명

 

레퍼런스 : 명령어의 사전을 의미

 

 

-자바스크립트의 API-

 

자바스크립트의 API는 크게 자바스크립트 자체의 API와 자바스크립트가 동작하는 호스트 환경의

API로 구분된다.

 

 

자바스크립트 API 문서

 


* ECMAScript (표준문서)

 

* 자바스크립트 사전 (생활코딩)

 

* 자바스크립트 레퍼런스 (MDN)

 

* jscript 레퍼런스 (MSDN)

 

 

 

호스트 환경의 API 문서

 

 

* 웹브라우저 API

 

* Nods.js API

 

* Google Apps Script API

 

 

 

출처 (생활코딩)

https://opentutorials.org/module/532/6533

 

 

아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ

토비의 스프링 3.1 세트:스프링의 이해와 원리 + 스프링의 기술과, 에이콘출판

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

'Front-End > javascript' 카테고리의 다른 글

javascript - 유효범위 (전역변수, 지역변수)  (0) 2019.06.11
javascript - 정규표현식  (0) 2019.06.11
javascript - 라이브러리 (jQuery)  (0) 2019.06.09
javascript - 모듈  (0) 2019.06.09
javascript - 객체  (0) 2019.06.09
:

Oracle와 mybatis 연동 실습 (글수정, 글삭제 구현)

Back-End/Spring 2019. 6. 10. 11:32

MemoService.java : dao에 값만 전달해 주는 역할



-글 수정 구현-



글 상세보기 (View.java) 페이지 에서 시작


=> 수정 버튼 클릭 (글 수정을 위해 dto.idx (글번호) 를 매개변수로 넘기고, 마찬가지로 id값인 btnUpdate도 넘긴다.) 


=> view 파일 상부에 있는 javascript 구문 실행 (id을 $("")으로 받고, dto.idx (dto에 있는 글번호 값)도 $("")로 받는다.)

그리고, 함수(function)을 실행한다.


=> 받은 dto.idx(글번호 값을) controller에 넘긴다 (왜냐하면 그 쪽에 @RequestMapping으로 url이 맵핑되어 있기 때문에)


=> controller 안에 있는 메소드인 update메소드에 @PathVariable int idx (글번호)와 수정을 해야하기 때문에 

MemoDTO dto (이름값과 메모값이 담겨있음) 를 매개변수로 받는다.


=> update 메소드 안에 있는 memoService.update메소드 (memoServiceImpl.java 에서 구현되어 있음)를 실행한다. 

(이 update메소드는 DAO에서 @Update 어노테이션을 사용해서 쿼리문이 대입된 상태이다.


=> update 메소드에 있는 쿼리가 정상적으로 실행이 되면 글수정을 해서 최신화를 하고 list.do 페이지로 돌아가게 된다.




-글 삭제 구현-



글 삭제 (View.java) 페이지 에서 시작 


=> 삭제 버튼 클릭 (글 삭제를 위해 dto.idx (글번호) 를 매개변수로 넘기고, 마찬가지로 id값인 btnDelete도 넘긴다.) 


=> view 파일 상부에 있는 javascript 구문 실행 (id을 $("")으로 받고, dto.idx(dto에 있는 글번호 값)도 $("")로 받는다.)

     그리고, 함수(function)을 실행한다.


=>  받은 dto.idx(글번호 값을) controller에 넘긴다. 

(왜냐하면 그 쪽에 @RequestMapping으로 맵핑되어 있기 때문에)


=> controller 안에 있는 메소드인 delete메소드에 @PathVariable int idx (글번호)를 넘긴다.


=> delete 메소드 안에 있는 memoService.delete (memoServiceImpl.java에서 구현되어 있음) 메소드를 실행한다. 

(이 delete 메소드는 DAO에서 @Delete 어노테이션을 사용해서 쿼리문이 대입된 상태이다.


=> delete 메소드에 있는 쿼리가 정상적으로 실행이 되면 최신화를 하고 list.do 페이지로 돌아가게 된다.





view.jsp중 일부


1
2
3
4
5
6
7
8
9
    <tr align = "center">
        <td colspan = "2">
            <input type = "hidden" name = "idx" value = "${dto.idx }">
            <!--글 수정을 하기 위해 글번호를 hidden 타입의 매개변수로 넘긴다. -->
            <button type = "button" id = "btnUpdate">수정</button>
            <button type = "button" id = "btnDelete">삭제</button>
            <!-- button type을빼면 무조건 재출력버튼이 되기 때문에 타입을 button으로 한다. -->
        </td>
    </tr>
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
$(function() {//밑에서 작성한 id값이 넘어오면 click메소드 안에 들어있는 function()함수를 실행해서
            //수정하거나 삭제할때 각각 번호를 넘겨서 삭제한다.
            
    $("#btnUpdate").click(function(){//수정버튼을 누르면 밑에서 사용한 id값이 넘어오고 function()메소드를 실행해서
                                        //dto의 글번호 값을 넘겨준다.
        document.form1.action="${path}/memo/update/${dto.idx}";
        document.form1.submit();
    });
    $("#btnDelete").click(function(){ //삭제 버튼을 누르면 confirm메소드를 실행해서 확인창을 띄우고, dto의 글번호값을 넘겨준다.
        if(confirm("삭제하시겠습니까?")){
            location.href="${path}/memo/delete/${dto.idx}";    
        }
    });
});
</script>
cs




MemoController.java 중 일부


1
2
3
4
5
6
7
8
9
10
11
12
@RequestMapping("update/{idx}")
    public String update(@PathVariable int idx, MemoDTO dto) {
        memoService.update(dto);
        return "redirect:/memo/list.do";
    }
    
    @RequestMapping("delete/{idx}")
    public String delete(@PathVariable int idx) {
        memoService.delete(idx);
        return "redirect:/memo/list.do";
        
    }

cs



MemoDAO.java 중 일부


1
2
3
4
5
6
7
8
9
    @Update("update memo set writer=#{writer}, memo=#{memo} "
            + "where idx=#{idx}")
    public void memo_update (MemoDTO dto);
    //글번호를 매개변수로 받고 @Param을 사용하면 괄호 안에 값이 쿼리문의 #안쪽에 대입이된다.
    
    
    @Delete("delete memo where idx=#{idx}")
    public void memo_delete(@Param("idx") int idx);
    //글번호를 매개변수로 받고 @Param을 사용하면 괄호 안에 값이 쿼리문의 #안쪽에 대입이된다.
cs




MemoService.java (인터페이스) 중 일부


1
2
public void update(MemoDTO dto);//수정
public void delete(int idx);//삭제
cs




MemoServiceImpl.java (인터페이스 구현 클래스) 중 일부


1
2
3
4
5
6
7
8
9
    @Override
    public void update(MemoDTO dto) {
        memoDao.memo_update(dto); //memoDAO의 update 메소드를 실행
    }
 
    @Override
    public void delete(int idx) {
        memoDao.memo_delete(idx); //memoDAO의 delete 메소드를 실행
    }
cs





:

javascript - 라이브러리 (jQuery)

Front-End/javascript 2019. 6. 9. 20:37

-라이브러리-

 

라이브러리는 모듈과 비슷한 개념이다.

모듈이 프로그램을 구성하는 작은 부품으로서의 로직을 의미한다면 라이브러리는 자주 사용되는 로직을 재사용되기

편리하도록 잘 정리한 일련의 코드들의 집합을 의미한다고 할 수 있다.

 

라이브러리가 무엇인지를 보여주기 위해 jQuery를 잠깐 사용

 

jQuery 다운로드

http://jquery.com/

 

jQuery 메뉴얼을 이용해서 사용법을 파악한다.

http://api.jquery.com/

 

 

jQuery를 다운받고 jQuery에 자바스크립트 코드를 다운로드 받아서 그것을 읽어보면 된다.

 

 

1. 제이쿼리 홈페이지에 접속후 다운로드 버튼 클릭

 

 

 

2. 빨간색 네모부분 클릭

 

 

3. 클릭후 코드를 전체 복사

 

 

4. sublinetext에 복사한 코드를 jquery.js 파일을 만들고 그 안에 붙여넣기

 

5. jQuery.demo.html 파일 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="jquery.js"></script>
 
jquery.js 파일을 불러온다.
</head>
<body>
    <ul id="list">
        <li>empty</li>
        <li>empty</li>
        <li>empty</li>
        <li>empty</li>
        <li>empty</li>
    </ul>
    <script type="text/javascript">
    $('#list li').text('coding everybody');
 
$('#list li')는 id값이 list인 태그를 가리키고, li는 그 list태그 안에 있는 li태그를 가리킨다.
그리고 .text('coding everybody')는 그 li태그 안에 있는 문자열인 'empty'를 'coding everybody'로 바꾼다는 의미이다.
그래서 출력결과는 'coding everybody' 가 5번 출력되게 된다.
 
    </script>
</body>
</html>
 
 
cs

 

궂이 jQuery 코드를 사용하는 이유는 브라우저를 사용해서 <li>태그 안에 있는 값을 바꾸려면 너무 코드가 복잡해지기 때문에

보여주기 위해서 jQuery를 사용한 것이다.

아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ

토비의 스프링 3.1 세트:스프링의 이해와 원리 + 스프링의 기술과, 에이콘출판

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

'Front-End > javascript' 카테고리의 다른 글

javascript - 정규표현식  (0) 2019.06.11
javascript - UI와 API  (0) 2019.06.10
javascript - 모듈  (0) 2019.06.09
javascript - 객체  (0) 2019.06.09
javascript - 배열  (0) 2019.06.01
:

javascript - 모듈

Front-End/javascript 2019. 6. 9. 20:05

-모듈-

 

코드의 재활용성을 높이고, 유지보수를 쉽게 할 수 있는 기법

 

코드를 여러개의 파일로 분리하는 것. 

 

 

 

-모듈의 장점-

 

1. 자주 사용되는 코드를 별도의 파일로 만들어서 필요할 때마다 재활용 할 수 있다. (마치 함수처럼 여러군데에서 사용할 수 있음)

 

2. 코드를 개선하면 이를 사용하고 있는 모든 애플리케이션의 동작이 개선된다.

 

3. 코드 수정 시에 필요한 로직을 빠르게 찾을 수 있다.

 

4. 필요한 로직만을 로드해서 메모리의 낭비를 줄일 수 있다.

 

5. 한번 다운로드된 모듈은 웹 브라우저에 의해서 저장되기 때문에 동일한 로직을 로드 할 때

   시간과 네트워크 트래픽을 절약 할 수 있다. (브라우저에서만 해당)

 

 

 

-모듈이란?-

 

순수한 자바스크립트에서는 모듈이라는 개념이 분명하게 존재하지는 않지만, 자바스크립트가 구동되는 

 

호스트 환경에 따라서 서로 다른 모듈화 방법이 제공되고 있다. 

 

자바스크립트의 대표적인 호스트 환경인 웹브라우저에서 로직을 모듈화하는 방법이 있다.

 

 

  
  호스트 환경이란?




  호스트 환경이란 자바스크립트가 구동되는 환경을 의미한다.


  자바스크립트는 브라우저를 위한 언어로 시작했지만, 더 이상 브라우저만을 위한 언어가 아니다.


  예를들어 node.js는 서버 측에서 실행되는 자바스크립트다. 이 언어는 자바스크립트의


  문법을 따르지만 이 언어가 구동되는 환경은 브라우저가 아니라 서버측 환경이다.

 

 

 

<관련 예제>

 

호출할 함수를 별도의 파일로 분리시킴.

파일을 불러와서 그 파일안에 있는 함수를 호출해서 출력시킴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <script src="greeting.js"></script>
</head>
<body>
    <script>
        alert(welcome());
    </script>
</body>
</html>
cs 

 

 

greeting.js

1
2
3
function welcome(){
    return 'Hello world';
}
cs

 

 

웹브라우저가 화면에 출력될때 src속성이 있는지 없는지 확인하고 그 값이 있다면

 

그 값에 해당되는 파일이 있다면 "greeting.js" 를 <script>~</script>사이에 넣어서 출력한것과 같이 된다.

 

출력 결과는 greeting.js 파일의 welcom( ) 메소드가 호출이 되어서 "Hello world" 가 출력된다

 

이렇게 함으로써 코드가 간결해지고, main.html의 용량을 줄여준다.

 

 

sub.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="greeting.js"></script>
</head>
<body>
<script type="text/javascript">
    welcome();
</script>
</body>
</html>
cs

 

sub파일에서도 main.html 파일처럼 greeting.js 파일을 불러서 welcome() 메소드를 호출할 수 있다.

그리고 출력 결과는 "Hello world" 가 출력이 된다.

 

아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ

토비의 스프링 3.1 세트:스프링의 이해와 원리 + 스프링의 기술과, 에이콘출판

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

'Front-End > javascript' 카테고리의 다른 글

javascript - UI와 API  (0) 2019.06.10
javascript - 라이브러리 (jQuery)  (0) 2019.06.09
javascript - 객체  (0) 2019.06.09
javascript - 배열  (0) 2019.06.01
JavaScript - 함수  (0) 2019.06.01
:

javascript - 객체

Front-End/javascript 2019. 6. 9. 15:48

-객체란?-

 

배열은 안에 들어갈 값으로 숫자를 사용했지만, 인덱스로 문자를 사용할때는 객체(dictionary)를 사용해야한다.

다른 언어에서는 연관배열 (associative array) 또는 맵 (map), 딕셔너리(Dictionary) 라는 데이터 타입이 객체에 해당한다.

 

 

 

-객체의 문법-

 



  var grades = {'egoing' : 10, 'k8805' : 6, 'sorialgi' : 80};
 
  위의 예제에서 egoing는 key가 되고, 10은 value가 된다.
 

 

 

다른 방법

 



  var grades = { };   or   new object( );
 
  grades['egoing'] = 10;
 
  grades['k8805'] = 6;
 
  grades['sorialgi'] = 80;
 
  비어있는 객체를 만들고 대괄호 사이에 인덱스 값을 부여하고, 우항에 그 인덱스에 넣을 값을 부여한다.
  위의 예제에서 egoing는 key가 되고, 10은 value가 된다.

 

 

객체에서 값을 가져오고 싶을때는 ['인덱스값'] 또는 .인덱스값 으로 가져올수 있다

 



  ex - grades['egoing']      or      grades.egoing
     
        10이 출력됨

 

[ ]안에 들어가는 값은 문자열이기 때문에 ['ego+'ing'] 이런식으로도 가져올 수 있다.

대괄호만 가능하고 .grades.( )는 문법오류때문에 불가능 하다.

 

 

-객체와 반복문-

 

배열 내부에 있는 데이터는 순서가 있다.

 

for문을 사용해서 객체 안에 있는 반복문을 출력하는 방법

 



  var grades = {'egoing' : 10, 'k8805' : 6, 'sorialgi' : 80};
 
  for (key in grades) {
 
  document.write("key : "+key+" value : " +grades[key]+ "<br / >"); 
 
  }
 
새로운 형식의 for in문


grades 안에 있는 인덱스 값들은 for문이 한번 돌 때마다 key라는 변수에 하나씩 저장된다는 의미...


key는 변수의 이름이기 때문에 다른 이름으로 변경이 가능하다.

 

 

웹페이지 우클릭 -> 요소검사를 통해 웹페이지가 어떤 html로 이루어졌는지 알 수 있음

 

<ul>~ <li></li>~</ul> 문으로 리스트로 만들수 있음...

 

 

for in 문은 배열에서도 사용이 가능하다.

아래 형식은 인덱스 번호가 출력됨.

 



  var arr = ['a','b','c'];
 
  for (var name in arr) {
  console.log (arr[name]);
  }
 
  0
  1
  2 출력
 
 arr[ ]안에 name라는 변수를 담게되면
 인덱스에 해당하는 값들인
 a
 b
 c 출력

 

 

 

-객체지향 프로그래밍-

 



var grades = {
 
'list' : {'egoing' : 10, 'k8805' : 8, 'sorialgi' : 80}
 
'show' : function( ){
 
alert('Hello world');
}
 }
 
 elert (grades['list']['egoing']);
 
 list안에 있는 egoing의 값이 출력되서 10이 출력됨
 

 

 



 var grades = {
 
'list' : {'egoing' : 10, 'k8805' : 8, 'sorialgi' : 80}
 
'show' : function( ){
 
alert('Hello world');
}
 }
 
 grades['show']( );
 
 변수 grades에 담긴 함수 show에 값인 Hello world가 출력된다.
 

 

자바스크립트에서는 함수도 변수에 저장이 될수 있다.

 

 

this 사용 예제



  var grades = {
 
'list' : {'egoing' : 10, 'k8805' : 8, 'sorialgi' : 80}
 
'show' : function( ){
 
for(var name in this.list){
 
console.log(name, this.list[name]);
 
 }
 
      }
 
  }
 
 grades.show();  객체이름을 적고 변수이름인 show를 호출하면 그 변수에 담겨있는 함수인 function()가 실행되서 출력값이 출력된다.


 this는 다른 언어들의 this와 동일하다.
 출력값은 list의 값을 name에 넣은 name의 list의 값인 10 8 80 이 출력된다.
 

 

아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ

토비의 스프링 3.1 세트:스프링의 이해와 원리 + 스프링의 기술과, 에이콘출판

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

'Front-End > javascript' 카테고리의 다른 글

javascript - 라이브러리 (jQuery)  (0) 2019.06.09
javascript - 모듈  (0) 2019.06.09
javascript - 배열  (0) 2019.06.01
JavaScript - 함수  (0) 2019.06.01
javaScript 반복문  (0) 2019.05.25
:

PSA , 스프링에서 PSA형식으로 되어있는 것들(인강+블로그)

Back-End/Spring 2019. 6. 8. 12:57

-PSA란??-


잘 만든 인터페이스


이식가능한 서비스 추상화


PSA를 사용하면 확장성이 좋아지고 (테스트하기 편함)


기술자체를 유동적으로 바꿔서 사용할 수 있다.


스프링이 제공하는 거의 모든 API는 PSA이다.


@Transactional 을 예로 들면


어노테이션과 그 실행 aspect 클래스가 따로 존재한다.


그 aspect는 Transaction 기술과는 독립적인 PlatformTransactionManager라는 인터페이스가 사용된 코드


PlatformTransactionManager 인터페이스의 구현체가 바뀌더라도 TransactionAspect의 코드는 바뀌지 않는다.


구현체들 중에 여러가지가 bean으로 등록 되있는 것들이 있다 ex-JPA


aspect는 Platform TransactionManager를 사용하여 코딩했기 때문에


jpaTransactionManager에서 DatasourceManager로 바뀌더라도 Transaction을 처리하는 aspect 코드는 바뀌지 않는다.


(인터페이스가 가진 기본 기능, 기본 틀은 바뀌지 않는다는 뜻)





-스프링 트랜잭션-


스프링은 코드 기반의 트랜잭션 처리 뿐 아니라 선언적 트랜잭션 (Declarative Transaction)을 지원하고 있다.


스프링이 제공하는 트랜잭션 템플릿 클래스를 이용하거나 설정 파일, 어노테이션을 이용해서 트랜잭션의


범위 및 규칙을 정의할 수 있다.



선언적 트랜잭션 처리


ㄱ. 선언적 트랜잭션은 설정파일이나 어노테이션을 이용해서 트랜잭션의 범위, 롤백 규칙 등을 정의


ㄴ. 다음과 같은 2가지 방식으로 정의함


1. <tx:advice> 태그를 이용한 트랜잭션 처리


2. @Transactional 어노테이션을 이용한 트랜잭션 설정



-예  시-

/**

     * 사업부 정보 등록,수정

     * @param map

     * @return

     * @throws Exception

     */

    @Transactional

    public int saveDivisionData(Map<String, Object> map) throws Exception {

      int cnt = companyDAO.saveDivisionData(map);

       

      // 사업부 수정이 정상적으로 처리되면 대상 사업부를 확산대상으로 지정한다.

      if(cnt == 1){

        companyDAO.saveExtensionTarget(map);

      }

      

        return cnt;

    }



@Transactional을 써주는 이유??


companyDAO.saveDivisionData 에서 처리한 쿼리문이 정상적으로 완료가 되고, companyDAO.saveextensionTarget 에서 처리 도중


에러가 났을 때 companyDAO.saveDivisionData 에서 처리한 쿼리를 자동 rollback(작업 취소) 해주기 위해 사용된다.


만약 저 어노테이션을 써주지 않는다면, 위에꺼는 정상적으로 완료가 되었기 때문에 직접 save 한 division 데이터를


복구 시켜놔야한다.


-인터페이스를 구현한 클래스로 선언된 빈은 인터페이스 메소드에 한해서 트랜잭션이 적용됨


-인터페이스에 붙은 @Transactional 선언은 인터페이스 내의 모든 메소드에 적용됨


-동시에 메소드 레벨에도 @Transactional을 지정할 수 있다. 


-클래스의 @Transaction > 인터페이스의 @Transactional


-@Transactional 적용 대상은 미리 결정하고 애플리케이션 안에서 통일하는게 좋음. 인터페이스와 클래스 양쪽


  에 불규칙하게 @Transaction이 혼용되는건 바람직하지 못하다.



context-transaction.xml 파일에 아래와 같이 선언


<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

      <property name="dataSource" ref="dataSource"/>

    </bean>

    

    <tx:advice id="txAdvice" transaction-manager="txManager">

        <tx:attributes>

            <tx:method name="select*" read-only="true" />

            <tx:method name="list*" read-only="true" />

            <tx:method name="retrieve*" read-only="true" />

            <tx:method name="get*" read-only="true" />

            <tx:method name="find*" read-only="true" />

            <tx:method name="view*" read-only="true" />

            <tx:method name="*Move" read-only="true" />

            <tx:method name="insert*" propagation="REQUIRED" />

            <tx:method name="update*" propagation="REQUIRED" />

            <tx:method name="delete*" propagation="REQUIRED"/>

            <tx:method name="save*" propagation="REQUIRED"/>

            <tx:method name="create*" propagation="REQUIRED"/>

            <tx:method name="merge*" propagation="REQUIRED"/>

            <tx:method name="execute*" propagation="REQUIRED"/>

            <tx:method name="excel*" propagation="REQUIRED"/>

            <tx:method name="CALL" propagation="REQUIRED"/>

            <tx:method name="*" rollback-for="Exception"/>

        </tx:attributes>

    </tx:advice>

    

    <aop:config>

        <aop:pointcut id="requiredTx" expression="execution(* com.????.??..impl.*Impl.*(..))"/>

        <aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx" />

    </aop:config>


<tx:annotation-driven transaction-manager="txManager" />


// @Transactional을 사용할 때 필요한 설정은 다음 한 줄 뿐이다.


<tx:annotation-driven> 태그는 등록된 빈 중에서 @Transactional이 붙은 클래스나 인터페이스 또는 메소드를 찾아


트랜잭션 어드바이스를 적용해준다.


출처: https://crosstheline.tistory.com/96 [이거 알아영???ㅎㅎㅎ]




-스프링 캐시-


  캐시란?


  복잡한 계산, DB작업, 원격 처리 결과 등을 임시 저장소인 캐시에 저장해뒀다가 동일한 요청이 들어오면


  캐시에 보관해뒀던 기존의 결과를 그대로 돌려줌



  주의할점


  1. 반복적이고 동일한 작업에만 사용 가능


  2. 캐시의 유효성 검사


  ㄱ. 공지사항이 수정되서 DB가 바뀌었는데도 계속해서 캐시의 이전내용을 보여주면 곤란


  ㄴ. 캐시의 내용이 유효하지 않은 시점이 되면 캐시에서 해당 내용을 제거해주는 작업이 필요하다.


  ㄷ. 캐시의 제거는, 주기적으로 하거나 어떤 메소드가 실행될때 캐시를 제거하도록 어노테이션을 이용해서 설정할 수 있다.




출처

https://m.blog.naver.com/PostView.nhn?blogId=kbh3983&logNo=220952478803&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F




@EnableCaching 어노테이션을 사용하면 캐시 관련된 기능이 활성화 된다.


이게 활성화되면 @Cacheable나 @CacheEvict 같은 어노테이션들을 사용할 수 있다.


그렇게 사용할려면 CacheManager가 있어야한다.  


왜냐하면 @Cacheable나 @CacheEvict을 처리하는 aspect가 어딘가에 있기 때문... 그리고 그 aspect에서는 트랜잭션 매니저를 사용한다. 


이 빈에서는 JCacheManager를 사용하고 있고, 의존성에 ehCache(원래는 JCache 였는데 이름이 바뀐거같음) 가 있다.


이 빈을 ehCacheManagerCustomizer로 바꿔주면 ehCacheManager를 쓰게 될것이고,  


그럼에도 @Cacheable, @CacheEvict를 처리하는 cacheaspect코드는 바뀔일이 없다.




추상화 웹 MVC (@Controller 과 @RequestMapping)


지금은 @Controller과 @GerMapping를 사용해서 웹 mvc를 구현

메소드에서 뷰를 리턴하면 해당이 되는 뷰를 출력함


하지만 매핑하는 값이 서블릿일수도 있고 리액티브를 쓰는것일수도 있음.

의존성을 확인하기 전까진 알지 못한다.

그렇기 때문에 매핑하는 값도 추상화로 볼 수 있다.

(즉, 기술 (Servlet, Reactive)를 바꾸어도 코드의 변경이 일어나지 않는다

그리고 테스트 하기도 더 쉽다.)







: