반응형
반응형

Javascript SE6 공부 참고용으로 퍼왔습니다~


출처: http://itstory.tk/entry/JavaScript-ES6-문법-정리 [덕's IT Story]


ECMAScript 6

이 문서는 https://github.com/lukehoban/es6features 를 번역한 내용입니다. 번역 문서를 읽는 중, 오타나 어색한 문장이 있으면 이슈를 등록해주세요!

Introduction

ECMAScript 2015로도 알려져 있는 ECMAScript 6는 ECMAScript 표준의 가장 최신 버전입니다. ES6는 새로운 언어 기능이 포함된 주요 업데이트이며, 2009년도에 표준화된 ES5 이후로 언어 기능에 대한 첫 업데이트이기도 합니다. 현재 주요 JavaScript 엔진들에서 ES6 기능들을 구현 중에 있습니다.

ECMAScript 6 언어의 전체 스펙을 확인하시려면 ES6 Standard를 확인하세요.

ES6는 아래의 새로운 기능들을 포함하고 있습니다.

ECMAScript 6 에 추가된 기능

Arrows

Arrows(화살표) 함수는 => 문법을 사용하는 축약형 함수입니다. C#, Java 8, CoffeeScript의 해당 기능과 문법적으로 유사합니다. Arrows는 표현식의 결과 값을 반환하는 표현식 본문(expression bodies)뿐만 아니라 상태 블럭 본문(statement block bodies)도 지원합니다. 하지만 일반 함수의 자신을 호출하는 객체를 가리키는 dynamic this와 달리 arrows 함수는 코드의 상위 스코프(lexical scope)를 가리키는 lexical this를 가집니다.

var evens = [2, 4, 6, 8,];

// Expression bodies (표현식의 결과가 반환됨)
var odds = evens.map(v => v + 1);   // [3, 5, 7, 9]
var nums = evens.map((v, i) => v + i);  // [2, 5, 8, 11]
var pairs = evens.map(v => ({even: v, odd: v + 1})); // [{even: 2, odd: 3}, ...]

// Statement bodies (블럭 내부를 실행만 함, 반환을 위해선 return을 명시)
nums.forEach(v => {
  if (v % 5 === 0)
    fives.push(v);
});

// Lexical this
// 출력결과 : Bob knows John, Brian
var bob = {
  _name: "Bob",
  _friends: ["John, Brian"],
  printFriends() {
    this._friends.forEach(f =>
      console.log(this._name + " knows " + f));
  }
}

printFriends() 함수의 서브루틴은 다음과 문법상 동일하게 동작합니다.

this._friends.forEach(function (f) {
    console.log(this._name + " knows " + f));
}.bind(this));

화살표 함수의 더 자세한 설명은 MDN Arrow Functions를 참고하세요. printFriends() 함수의 선언 표기법이 궁금하시면 MDN Object Initializer를 참고하세요.

Classes

ES6 클래스는 포로토타입 기반 객체지향 패턴을 더 쉽게 사용할 수 있는 대체재입니다. 클래스 패턴 생성을 더 쉽고 단순하게 생성할 수 있어서 사용하기도 편하고 상호운용성도 증가됩니다.

class SkinnedMesh extends THREE.Mesh {
  constructor(geometry, materials) {
    super(geometry, materials);

    this.idMatrix = SkinnedMesh.defaultMatrix();
    this.bones = [];
    this.boneMatrices = [];
    //...
  }
  update(camera) {
    //...
    super.update();
  }
  get boneCount() {
    return this.bones.length;
  }
  set matrixType(matrixType) {
    this.idMatrix = SkinnedMesh[matrixType]();
  }
  static defaultMatrix() {
    return new THREE.Matrix4();
  }
}

더 자세한 설명은 MDN Classes를 참고하세요.

Enhanced Object Literals

ES6에서 객체 리터럴은 선언문에서 프로토타입 설정, foo: foo 선언을 위한 단축 표기법, 메서드 정의, super 클래스 호출 및 동적 속성명을 지원하도록 향상 되었습니다. 그에 따라 객체 리터럴 및 클래스 선언이 더 밀접되어져, 객체기반 설계가 더 편리해졌습니다.

var obj = {
    // __proto__
    __proto__: theProtoObj,

    // ‘handler: handler’의 단축 표기
    handler,

    // Methods
    toString() {
     // Super calls
     return "d " + super.toString();
    },

    // Computed (dynamic) property names
    [ 'prop_' + (() => 42)() ]: 42
};

더 자세한 설명은 MDN Grammar and types: Object literals를 참고하세요.

Template Strings

Template Strings(ES6 부터는 Template literals라 부름)는 문법적으로 더 편하게 string을 생성할 수 있게 합니다. 이는 Perl, Python 등의 문자열 보간(string interpolation)과 유사합니다. Tagged template literals는 인젝션 공격 방어 혹은 문자열로 부터 상위 데이터 구조체 재조립 등을 위해 string 생성을 커스터마이징이 가능하게끔 해줍니다.

// Basic literal string creation
`In JavaScript '\n' is a line-feed.`

// Multiline strings
`In JavaScript this is
 not legal.`

// String interpolation
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

// Construct an HTTP request prefix is used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
     Content-Type: application/json
     X-Credentials: ${credentials}
     { "foo": ${foo},
       "bar": ${bar}}`(myOnReadyStateChangeHandler);

더 자세한 설명은 MDN Template literals를 참고하세요.

Destructuring

Destructuring는 배열과 객체에 패턴 매칭을 통한 데이터 바인딩을 제공합니다. Destructuring는 할당 실패에 유연하며, 실패 시 undefined 값이 자동할당 됩니다. 또한 foo["bar"]와 같이 객체의 속성 값도 자동으로 검색하여 바인딩해줍니다.

// list matching
var [a, , b] = [1,2,3];

// object matching
var { op: a, lhs: { op: b }, rhs: c }
       = getASTNode()

// object matching 단축 표기
// binds `op`, `lhs` and `rhs` in scope
var {op, lhs, rhs} = getASTNode()

// parameter에서도 사용 가능
function g({name: x}) {
  console.log(x);
}
g({name: 5})

// Fail-soft destructuring
var [a] = [];
a === undefined;

// Fail-soft destructuring with defaults
var [a = 1] = [];
a === 1;

더 자세한 설명은 MDN Destructuring assignment를 참고하세요.

Default + Rest + Spread

파라미터에 기본 값을 설정할 수 있습니다.

function f(x, y=12) {
  // y is 12 if not passed (or passed as undefined)
  return x + y;
}
f(3) // 15

가변인자를 사용가능하며, 배열로 치환시켜 줍니다. Rest parameters는 arguments 보다 직관성을 제공합니다.

function f(x, ...y) {
  // y is an Array ["hello", true]
  return x * y.length;
}
f(3, "hello", true) // 6

함수 호출 시 배열을 일련의 인자에 나누어 주입시켜 줍니다.

function f(x, y, z) {
  return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) // 6

더 자세한 설명은 Default parametersRest parametersSpread Operator를 참고하세요.

Let + Const

블록 유효 범위를 갖는 새로운 변수 선언 방법을 지원합니다. let은 var와 유사하게 동작합니다. const는 재할당 및 재선언이 불가능합니다.

function f() {
  {
    let x;
    {
      // okay, block scoped name
      const x = "sneaky";
      // error, const
      x = "foo";
    }
    // error, already declared in block
    let x = "inner";
  }
}

var의 유효 범위는 전체 외부 함수까지이지만 let은 변수를 선언한 블록과 그 내부 블록들에서 유효합니다.

function varTest() {
    var x = 31;
    if (true) {
        var x = 71;  // same variable!
        console.log(x);  // 71
    }
    console.log(x);  // 71
}

function letTest() {
    let x = 31;
    if (true) {
        let x = 71;  // different variable
        console.log(x);  // 71
    }
    console.log(x);  // 31
}
function varTest() {
    if (true) {
        var x = 71;
        console.log(x);  // 71
    }
    console.log(x);  // 71
}

function varTest() {
    let x = 71;
    if (true) {
        console.log(x);  // 71
    }
    console.log(x);  // 71
}

function varTest() {
    if (true) {
        let x = 71;
        console.log(x);  // 71
    }
    console.log(x);  // Uncaught ReferenceError: x is not defined
}

더 자세한 설명은 let statementconst statement를 참고하세요.

Iterators + For..Of

Iterator 객체는 CLR의 IEnumerable 혹은 Java의 Iterable처럼 사용자 정의의 반복을 가능하게 해줍니다. for..of 반복문이 ES6에서 추가 되었으며 for..in 반복문과 달리 iterator 기반의 컬렉션 전용 반복문입니다. for in 반복문과의 차이점은 for in vs for of를 참고하세요.

let fibonacci = {
    [Symbol.iterator]() {
        let pre = 0, cur = 1;

        return {
            next() {
                [pre, cur] = [cur, pre + cur];
                return { done: false, value: cur }
            }
        }
    }
}

for (var n of fibonacci) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    console.log(n); // 1, 2, 3, 5, 8, ...987
}

Iteration은 아래의 duck-type 인터페이스를 기반으로 합니다. (설명을 위해 TypeScript의 타입 문법을 사용하였습니다)

interface IteratorResult {
    done: boolean;
    value: any;
}
interface Iterator {
    next(): IteratorResult;
}
interface Iterable {
    [Symbol.iterator](): Iterator
}

더 자세한 설명은 MDN for…of를 참고하세요.

Generators

Generators는 function*와 yield 키워드를 이용하여 iterator 선언을 단순하게 작성할 수 있게 도와줍니다. function*로 선언한 함수는 Generator 객체를 반환합니다. Generators는 iterator의 하위 타입이며 next와 throw 메서드를 가지고 있습니다. 이 메서드들로 인해 yield 키워드로 반환된 값은 다시 generator에 주입거나 예외처리를 할 수 있게 되었습니다.

참고: 해당 키워드는 비동기 프로그래밍의 ‘await’ 같은 기능이 가능하게끔 기반이 되었습니다. ES7의 await 제안서를 참고하세요.

var fibonacci = {
    [Symbol.iterator]: function*() {
        var pre = 0, cur = 1;
        for (;;) {
            [pre, cur] = [cur, pre + cur];
            yield cur;
        }
    }
}

for (var n of fibonacci) {
    // truncate the sequence at 20
    if (n > 20)
        break;
    console.log(n); // 1, 2, 3, 5, 8, 13
}
function* gen(){
  yield* ["a", "b", "c"];
}

var a = gen();

a.next(); // { value: "a", done: false }
a.next(); // { value: "b", done: false }
a.next(); // { value: "c", done: false }
a.next(); // { value: undefined, done: true }

generator 인터페이스는 다음과 같습니다. (설명을 위해 TypeScript의 타입 문법을 사용하였습니다)

interface Generator extends Iterator {
    next(value?: any): IteratorResult;
    throw(exception: any);
}

더 자세한 설명은 MDN Iteration protocols를 참고하세요.

Unicode

완전한 유니코드를 지원하기 위해 문자열에 새로운 유니코드 리터럴과 정규표현식에 u 모드가 추가되었습니다. 또한 21비트 형식까지 처리하기 위한 신규 API가 추가되었습니다. 이 추가된 기능은 JavaScript로 글로벌 앱을 만들 수 있도록 지원합니다.

// same as ES5.1
"𠮷".length == 2

// new RegExp behaviour, opt-in ‘u’
"𠮷".match(/./u)[0].length == 2

// new form
"\u{20BB7}" == "𠮷"  == "\uD842\uDFB7"

// new String ops
"𠮷".codePointAt(0) == 0x20BB7

// for-of iterates code points
for(var c of "𠮷") {
    console.log(c); // 𠮷
}

더 자세한 설명은 MDN RegExp.prototype.unicode를 참고하세요.

Modules

언어 차원에서 컴포넌트 정의를 위한 모듈을 지원합니다. 유명한 JavaScript 모듈 로더들(AMD, CommonJS)의 패턴을 적용시켰습니다. 런타임 동작은 호스트에 정의된 기본 로더에 의해 정의됩니다. 묵시적 비동기 형태로 요구되는 모듈들이 정상적으로 로드되기 전까지 코드가 실행되지 않습니다.

// lib/math.js
export function sum(x, y) {
    return x + y;
}
export var pi = 3.141593;
// app.js
import * as math from "lib/math";
console.log("2π = " + math.sum(math.pi, math.pi)); // 2π = 6.283186
// otherApp.js
import {sum, pi} from "lib/math";
console.log("2π = " + sum(pi, pi)); // 2π = 6.283186

export default와 export * 문법도 제공합니다.

// lib/mathplusplus.js
export * from "lib/math";
export var e = 2.71828182846;
export default function(x) {
    return Math.log(x);
}
// app.js
import ln, {pi, e} from "lib/mathplusplus";
console.log("2π = " + ln(e)*pi*2);

더 자세한 내용은 import statementexport statement를 참고하세요.

Module Loaders

Module Loaders는 다음을 지원합니다.

  • 동적 로딍(Dynamic loading)
  • 상태 격리(State isolation)
  • 전역 네임스페이스 격리(Global namespace isolation)
  • 컴파일 훅(Compilation hooks)
  • 중첩 가상화(Nested virtualization)

기본으로 사용할 모듈 로더를 설정할 수 있으며, 로더를 새로 생성하여 격리되거나 제한된 맥락에서 코드를 로드할 수 있습니다.

// 동적 로딩 – ‘System’ is default loader
System.import('lib/math').then(function(m) {
    console.log("2π = " + m.sum(m.pi, m.pi));
});

// 실행 샌드박스 생성 – new Loaders
var loader = new Loader({
    global: fixup(window) // replace ‘console.log’
});
loader.eval("console.log('hello world!');");

// 모듈 캐시 직접 조작
System.get('jquery');
System.set('jquery', Module({$: $})); // WARNING: not yet finalized

Map + Set + WeakMap + WeakSet

일반 알고리즘을 위한 효율적인 데이터 구조를 제공합니다. WeakMap과 WeakSet는 메모리 누수로 부터 자유롭게 해줍니다. 이들 내 저장된 객체에 다른 참조가 없는 경우, garbage collection 될 수 있습니다.

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size // undefined (사용된 곳이 없기 때문)

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
wm.size // undefined (사용된 곳이 없기 때문)

더 자세한 내용은 MDN MapSetWeakMapWeakSet를 참고하세요.

Proxies

프록시(Proxy)를 사용하면 호스트 객체에 다양한 기능을 추가하여 객체를 생성할 수 있습니다. interception, 객체 추상화, 로깅/수집, 값 검증 등에 사용될 수 있습니다.

// Proxying a normal object
var target = {};
var handler = {
  get: function (receiver, name) {
    return `Hello, ${name}!`;
  }
};

var p = new Proxy(target, handler);
p.world // 'Hello, world!';
// Proxying a function object
var target = function () { return 'I am the target'; };
var handler = {
  apply: function (receiver, ...args) {
    return 'I am the proxy';
  }
};

var p = new Proxy(target, handler);
p() // 'I am the proxy';
let validator = {
    set: function(obj, prop, value) {
        if (prop === 'age') {
            if (!Number.isInteger(value)) {
                throw new TypeError('The age is not an integer');
            }
            if (value > 200) {
                throw new RangeError('The age seems invalid');
            }
        }

        // The default behavior to store the value 
        obj[prop] = value;
    }
};

let person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception

proxy의 handler가 가질 수 있는 트랩(trap)들입니다.

var handler =
{
  get:...,
  set:...,
  has:...,
  deleteProperty:...,
  apply:...,
  construct:...,
  getOwnPropertyDescriptor:...,
  defineProperty:...,
  getPrototypeOf:...,
  setPrototypeOf:...,
  enumerate:...,
  ownKeys:...,
  preventExtensions:...,
  isExtensible:...
}

더 자세한 내용은 MDN Proxy를 참고하세요.

Symbols

심볼(Symbol)은 객체 상태의 접근 제어를 가능하게 합니다. Symbol은 새로운 원시 타입으로 이름 충돌의 위험 없이 속성(property)의 키(key)로 사용할 수 있습니다. 옵션 파라미터인 description는 디버깅 용도로 사용되며 식별 용도는 아닙니다. Symbol은 고유(unique)하며, Object.getOwnPropertySymbols와 같은 reflection 기능들로 접근할 수 있기 때문에 private 하진 않습니다(for in나 Object.keys()로는 접근 불가).

var map = {};
var a = Symbol('a');

map[a] = 123;
map["b"] = 456;

console.log(map[a]); // 123
console.log(map["b"]); // 456

for (let key in map) {
    console.log(key); // b
}

Object.keys(map); // ["b"]

더 자세한 내용은 ES6 In Depth: 심볼 (Symbol)를 참고하세요.

Subclassable Built-ins

ES6에서 ArrayDate, DOM Element 같이 내장 객체들은 상속이 가능합니다. 객체 생성 시 호출되는 Ctor 함수는 다음의 2단계를 가집니다.(둘다 가상적으로 실행)

  • 객체 할당을 위해 Ctor[@@create] 호출하여
  • 새로운 인스턴스의 생성자를 호출해 초기화 진행

아시다싶이 @@create 심볼은 Symbol.create를 통해 만들어졌습니다.

// Pseudo-code of Array
class Array {
    constructor(...args) { /* ... */ }
    static [Symbol.create]() {
        // Install special [[DefineOwnProperty]]
        // to magically update 'length'
    }
}

// User code of Array subclass
class MyArray extends Array {
    constructor(...args) { super(...args); }
}

// Two-phase 'new':
// 1) Call @@create to allocate object
// 2) Invoke constructor on new instance
var arr = new MyArray();
arr[1] = 12;
arr.length == 2

Math + Number + String + Array + Object APIs

core Math 라이브러리, Array 생성 helper, String helper, 복사를 위한 Object.assign 등 많은 라이브러리들이 추가되었습니다.

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2

"abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc"

Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(7, 1) // [0,7,7]
[1, 2, 3].find(x => x == 3) // 3
[1, 2, 3].findIndex(x => x == 2) // 1
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"

Object.assign(Point, { origin: new Point(0,0) })

더 자세한 내용은 NumberMathArray.fromArray.ofArray.prototype.copyWithinObject.assign를 참고하세요.

Binary and Octal

2진법 (b), 8진법 (o) numeric 리터럴 형식이 추가되었습니다.

0b111110111 === 503 // true
0o767 === 503 // true

Promises

Promise는 비동기 프로그래밍을 위한 라이브러리입니다. Promise는 미래에 생성되는 값을 나타내는 일급 객체입니다. Promise는 현존하는 많은 JavaScript 라이브러리에 사용되고 있습니다.

function timeout(duration = 0) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, duration);
    })
}

var p = timeout(1000).then(() => {
    return timeout(2000);
}).then(() => {
    throw new Error("hmm");
}).catch(err => {
    return Promise.all([timeout(100), timeout(200)]);
})

더 자세한 내용은 MDN Promise를 참고하세요.

Reflect API

Reflection API는 런타임 시 객체에 대해 작업을 수행할 수 있습니다. 프록시 트랩(proxy traps)와 같은 메타 함수들을 가지고 있습니다. Reflection은 프록시를 구현하는데 유용합니다.

class Greeting {
    constructor(name) {
        this.name = name;
    }

    greet() {
      return `Hello ${name}`;
    }
}

function greetingFactory(name) {
    return Reflect.construct(Greeting, [name], Greeting);
}

greetingFactory('a'); // Greeting {name: "a"}

더 자세한 내용은 MDN Reflect를 참고하세요.

Tail Calls

마지막에 호출되는 함수가 호출 스택이 초과되게 하지 않습니다. 재귀 알고리즘을 매우 큰 입력 값에서도 안전하게 만듭니다.

function factorial(n, acc = 1) {
    'use strict';
    if (n <= 1) return acc;
    return factorial(n - 1, n * acc);
}

// 현재 대부분의 자바스크립트 엔진에서 스택 오버플로우가 일어나지만,
// ES6에서는 입력 값이 커도 안전하다
factorial(100000);



이외에


개발 문서 링크 참조해서 나중에 봐야겠습니다


http://es6-features.org/#Constants




반응형
반응형

SVN을 사용한 프로젝트를 하다보면 각각 다른 버전을 사용할때

해당 버전파일을 커밋해버려서 골치아플때가 있다

그럴때 해당파일을 제외하는 설정을 사용해 커밋을 피할수있다

두가지 방법이있다


1. 전체적인 셋팅

   

   Window > Preperences > Ignored Resources 


   이곳에서 Add Pattern을 통해 제외할 파일들을 추가하면된다

  

   예시를 들자면 이런 패턴들을 추가할수있다


      .project       //프로젝트 설정이 다를경우 제외

.classpath   // 톰캣버전명이 다를경우때문에 제외
.settings     //  Project Facet 버전이 다를 경우 제외

*/target/**           <-- 메이븐 빌드디렉토리

   

    


2. 해당 파일에서 셋팅


Project Explorer -> 파일선택후 우클릭 -> Team -> Add to svn:ignore..

또는 우클릭 후 Synchronize 탭에 들어가면 변경할 파일을 우클릭해보면 Add to svn:ignore 탭이 활성화된 경우가 있다

 

Add to svn:ignore.. 메뉴가 없거나 비활성화되는경우는 이미 대상파일/디렉토리가 소스관리를 받고있는 상황이기 때문에 이경우에는 ignored 설정이 불가능하다

이경우에는 두가지 선택이 있을 수 있다

 

가) 위의 전역 키워드를 추가하는 방법을 사용하는것과

나) 대상을 백업후 svn에서 대상을 삭제한상태에서 svn에 커밋해서 형상관리에서 삭제한뒤 대상을 복구하고 Add to svn:ignore 활성화된걸 확인후에 ignored 설정완료를 하면된다




SVN 개요



1.    SVN 개요
1.1    버전 관리 시스템의 필요성
# 개발 버전과 릴리즈 버전이 섞이지 않고 쉽게 관리 할 수 있다.
# 소스를 잘못 수정 했더라도 기록이 남으며, 되돌리기가 쉽다.
# 수정, 추가, 삭제 등의 기록이 모두 남고 변경 사항을 추적하기 쉽다.
# 개발자들이 따로 따로 백업을 하지 않아도 된다.

1.2    버전 관리 시스템 선택
1.2.1    VSS 와 SVN (어느 개발자의 두 버전관리 시스템의 평가)
VSS는 유료이며, VSS의 큰 문제는 깨지는 저장소이다. CS구조가 아닌 NFS 방식으로 파일을 공유하기 때문에 그런 문제가 있었던 것으로 보인다. 안정성이 가장 중요한 요소 중 하나인 SCM에서 자주 깨지는 저장소는 신뢰성을 떨어트린다.

매일 백업을 받고 있었으므로 몇 시간 분량의 손실만 있을 뿐 복구는 할 수 있었지만, 개발 시간을 낭비하게 만드는 것은 아주 짜증나는 일이다. 그리고 허약한 Branch기능은 부족한 기능 중에 하나였다.

SVN은 일단 무료이며, 어느 개발자는 그 오랫동안 사용하면서 저장소는 단 한번도 깨진 적이 없다고 한다. 그리고 빠르다. 아무리 큰 디렉터리를 태깅하거나 브랜치를 해도 시간은 몇 십초 안 걸린다.

CVS에서 엄청나게 큰 디렉터리 태깅하면서 기다려보신 분은 알것이다. 그렇게 빠른 이유는 SVN은 기존의 SCM의 파일 시스템과 완전히 다른 방식을 사용하고 있기 때문이다. 기존의 대부분의 SCM들이 RCS(Revision Control System)에서 기초한 파일시스템을 사용하는데 반해서 SVN의 파일시스템은 기존의 단점을 없애고 새로 만들었다 즉 각 Revision의 Diff만 저장하는 방식이다. 따라서 태그나 브랜치를 만들 때는 Diff가 없으므로 순식간에 이루어진다.

그리고 SVN의 VSS와 비교한 장점 중의 하나가 협업이 훨씬 쉬워졌다는 것이다. SVN도 Lock기능이 있지만, 이걸 사용하지 않고도 협업에 문제가 없다. 왜냐하면 하나의 파일을 동시에 수정할 경우에는 Merge를 해주기 때문이다. 기존에 VSS를 사용할 때는 물론 Multi-lock 기능이 있기는 하지만, 며칠씩 Lock을 걸어 놓고 풀지 않는 사람 때문에 보통 귀찮은 게 아니었다. SVN을 사용하면서 이런 문제는 사라졌다.

결국 SVN의 빠른 속도, 안전한 저장소, 뛰어는 브랜치 기능, 머지기능 등은 저와 저희 팀이 즐겁게, 제대로 일하는데 많은 도움을 주었다. (* 출처 : http://allofsoftware.net/50)
 
1.2.2    CVS 와 SVN
# 커밋 단위가 파일이 아니라 체인지셋이라는 점이다. CVS에서라면 여러 개의 파일을 한꺼번에 커밋하더라도 각각의 파일마다. 리비전이 따로 붙는다. 반면 Subversion에서는 파일별 리비전이 없고 한번 커밋할 때마다 변경 사항별로 리비전이 하나씩 증가한다.
# CVS에 비해 엄청나게 빠른 업데이트/브랜칭/태깅 시간.
# CVS와 거의 동일한 사용법. CVS 사용자라면 누구나 어려움 없이 금방 배울 수 있다.
# 파일 이름변경, 이동, 디렉토리 버전 관리도 지원.
# 원자적(atomic) 커밋. CVS에서는 여러 파일을 커밋하다가 어느 한 파일에서 커밋이 실패했을 경우 앞의 파일만 커밋이 적용되고 뒤의 파일들은 그대로 남아있게 된다. Subversion은 여러개의 파일을 커밋하더라도 커밋이 실패하면 모두 이전 상태로 되돌아 간다.
# 양방향 데이터 전송으로 네트워크 소통량(트래픽) 최소화.
# 트리별, 파일별 접근 제어 리스트. 저장소 쓰기 접근을 가진 개발자라도 아무 소스나 수정하지 못하게 조절할 수 있다.
# 저장소/프로젝트별 환경 설정 가능
# 확장성을 염두에 둔 구조, 깔끔한 소스
(* 출처: http://www.pyrasis.com/main/Subversion-HOWTO)

1.2.3    SVN 관련 용어 설명
저장소 : 리포지토리(Repository)라고도 하며 모든 프로젝트의 프로그램 소스들은 이 저장소 안에 저장이 된다. 그리고 소스뿐만이 아니라 소스의 변경 사항도 모두 저장된다. 네트워크를 통해서 여러 사람이 접근 할 수 있다. 

체크아웃 : 저장소에서 소스를 받아오는 작업. 

커밋(Commit) : 체크아웃 한 소스를 수정, 파일 추가, 삭제 등을 한 뒤 저장소에 저장하여 갱신 하는 것입니다. 커밋을 하면 CVS의 경우 수정한 파일의 리비전이 증가하고 Subversion의 경우 전체 리비전이 1 증가하게 된다.

업데이트(Update) : 체크아웃을 해서 소스를 가져 왔더라도 다른 사람이 커밋을 하였다면 소스가 달라졌을 것입니다. 이럴 경우 업데이트를 하여 저장소에 있는 최신 버전의 소스를 가져온다.

리비전(Revision) : 소스 파일등을 수정하여 커밋하게 되면 일정한 규칙에 의해 숫자가 증가 한다. 저장소에 저장된 각각의 파일 버전이라 할 수 있다. Subversion의 경우 파일별로 리비전이 매겨지지 않고 한번 커밋 한 것으로 전체 리비전이 매겨 진다. 리비전을 보고 프로젝트 진행 상황을 알 수 있다.

임포트(Import) : 아무것도 들어있지 않은 저장소에 맨 처음 소스를 넣는 작업이다.

익스포트(Export) : 체크아웃과는 달리 버전 관리 파일들을 뺀 순수한 소스 파일을 받아올 수 있다. 오픈소스 프로젝트의 경우 소스를 압축하여 릴리즈 할 때 사용한다.
(* 출처: http://www.pyrasis.com/main/Subversion-HOWTO)
 

2.    SVN과 VSS의 차이점
A팀의 VSS 사용 방법을 보니 이제 새로 사용할 SVN과는 다소 차이점이 있어 그 차이점을 간략하게 설명한다.

2.1    SVN은 하나의 프로젝트를 하나의 저장소에 저장한다.
VSS를 보니 여러 A팀 프로젝트를 하나의 저장소에서 조회하고 저장소에서 직접 등록/수정/삭제도 하는 것 같다.물론  SVN도 여러 A팀 프로젝트를 하나의 저장소에서 조회하는 것이 가능하다. 

그러나 그 수많은 프로젝트를 하나의 저장소에서 관리하면 1. 저장소가 비대해지는 등의 이유로 관리하기 어려움점이 있다.(이점은 VSS도 동일한 문제라고 생각함) 2. SVN을 잘 사용하려면 사용 방법에 대해 묵시적인 관례를 따라야 하는데 SVN 관례중 하나는 프로젝트 단위별로 저장소를 관리하는 것이다. 

2.2    여러 프로젝트에서 공통적으로 SVN을 사용하는 관례는 처음 한번 모든 프로젝트를 로컬에 다운받는 것이다. 
SVN이던 CVS던 버전관리 저장소의 프로젝트를 개발자가 사용하려면 일단 개발자 로컬에 모든 소스를 다운로드 받고 로컬에서 작업하고 저장소로 동기화 하는 구조로 되어 있다. 

그래서 최초에 한번은 저장소의 모든 소스를 로컬에 다운로드 받아야 한다. 그 다음부터는 변경된 건에 대해서만 저장소로부터 update 받고 로컬의 소스를 commit 할 수 있다. 

만약 개발자가 아닌 단순 ‘조회(View)’ 목적으로 저장소의 파일을 보길 원한다면, SVN 클라이언트의 저장소 뷰 기능을 통해 VSS처럼 저장소의 최신 소스를 조회 할 수 있다.

2.3    SVN 클라이언트 프로그램은 여러 종류가 있는데 그중 우리가 사용할 클라이언트는 탐색기에 Add 된 형태로 사용한다. 

SVN 클라이언트는 여러 종류가 있는데 우리가 사용하는 클라이언트 툴은 그림 파일을 보면 알 수 있겠지만, 탐색기에 Add된 형태로 사용한다. 

 
3.    SVN 설치방법
3.1    SVN 클라이언트를 설치한다.
http://tortoisesvn.net/downloads 에서 TortoiseSVN-1.6.5.16974-win32-svn-1.6.5.msi 를 다운로드 받는다. 

TortoiseSVN-1.6.5.16974-win32-svn-1.6.5.msi 을 실행하여 설치한다.

설치 후 restart는 굳이 할 필요 없다.

설치가 완료된후 탐색기 오른쪽 마우스를 클릭하면 다음의 메뉴가 추가되었다.


3.2    프로젝트 체크아웃(다운로드 받기)
1. 자신의 컴퓨터에서 프로젝트 용도의 폴더를 생성한다.
예) c:\source1 <- 이 폴더명은 사용자 임의로 정할 수 있다. 

2. c:\source1 폴더로 들어가서 마우스 우측 버튼 > SVN Checkout 을 클릭한다.


3. 저장소 URL을 타이핑한다. 예) svn://192.24.7.241/AMLUI/trunk 


4. 체크아웃 다 받을때까지 기다린다.


3.3    프로젝트 최초 등록
1. 체크아웃 받은 폴더에, 등록하고자 하는 프로젝트 소스를 복사/붙여넣기 한다.

2. 마우스 우측버튼 > SVN Commit을 누른다. 

3. Commit 리스트 전체 소스를 ‘체크’ 표시하고 확인버튼을 누른다. (이해안되면 4.4 설명 참고) 


4.    SVN  사용 방법 및 관례
일단 아래 설명이 복잡하게 느껴지면 이것만 기억해도 좋다. 수시로 저장소의 최신 소스를 update 받고 수시로 자신이 수정한 파일을 commit 하는 것이 SVN등의 버전 관리 시스템을 가장 잘 사용하는 방법이다. 

4.1    출근후 처음 작업하기 전에 전체 Update를 한다.
만약 현재 프로젝트를 여러명이 같이 진행하고 있으면, 출근후 첫 작업하기 전에, 프로젝트 전체 Update를 한번 받아 저장소와 로컬간 전체 동기화를 시킨다.
 
4.2    파일을 commit 할때, commit 하기 전에 관련 파일을 한번 update 받고 commit 한다.
만약 현재 프로젝트를 여러명이 같이 진행하고 있고, 해당 파일 수정 작업을 오래하고 있으면, 작업된 파일을 commit 하기전에 한번 관련 파일을 update받아  저장소와 로컬간에 소스 동기화를 한 다음, 다시 commit 한다. 

4.3    파일을 delete 할때, 로컬에서 파일을 지웠으면 그 지운 내용도 commit을 한다. 
쓸모 없는 파일이 발견되어 파일을 delete 하면, 지운 내역도 저장소에 commit을 하여 저장소의 쓸모없는 파일을 지울 수 있다. (CVS등에서는 제공되지 않는 기능)

4.4    파일을 add 할때, commit 버튼을 누른 후 새로 add할 파일의 체크박스를 체크 하고 올린다.
파일을 add할때는, 해당 폴더에서 commit버튼을 누르면 새로 add할 파일 목록이 나온다. 그런데 이때 체크박스에 표시를 하고 등록을 해야 새로운 파일이 저장소에 등록이 된다.
 
4.5    만약 commit, udpate중 충돌이 발생했을때
1. commit 할때 에러가나면 대부분 마지막으로 update받은 이후에, 누군가 저장소로 새로 파일을 commit 한 상태에서 발생한다. 이말은 commit을 하기전에 마지막으로 update 받은 파일이 저장소의 최신 버전과 일치해야 한다는 것이다. 

2. update 받을때 에러가나면 대부분 현재 작업한 파일과 저장소의 마지막으로 변경된 파일이 다를 때 주로 발생한다. 1.과 비슷한 상황이다. 이때는 diff를 이용하여 틀린 부분을 맞춰준다음 다시 commit 한다.

3. 기타 여러가지 이유로 svn 관련 에러가 발생할수 있다. 이럴 경우 마우스 우측버튼 하여 Clean up을 한다. 그래도 안될 경우에도 여러 해결방법이 있는데..
 
4.6    퇴근할때는 현재까지 작업한 소스를 전체 commit 한다.
소스 동기화를 자주 하는것이야 말로 SVN을 잘 활용하는 방법이다. 마치 사람없는 집은 금방 폐허가 되는 경우와 비슷하다. SVN 사용 관례상 지속적인 소스 동기화를 위해 퇴근할 때 현재까지 작업한 소스를 전체 commit하는 습관을 가진다. 


5.    SVN 관련 유익한 사이트
http://www.pyrasis.com/main/Subversion-HOWTO
SVN에 대한 전반적인 설명이 매우 잘 되어있다.

http://allofsoftware.net/50
VSS,SVN,CVS 등의 비교 에 대한 설명이 잘 되어있다.

http://blog.naver.com/ccw3435?Redirect=Log&logNo=100043063029
SVN의 일반적인 사용법




출처:http://mckdh.net/413

반응형
반응형

Spring Maven Bootstrap Mysql Mybatis 를 이용하여 개인프로젝트를 만드는 중입니다


일단 틀만 만들고 주제를 정하려고하는데


-w3schools 처럼 예제 모아놓은 사이트


-간단한 가상ERP 사이트


이정도 를 생각하고있습니다


현재는 기본 커뮤니티 게시판 , 사이드 메뉴, 로그인 로직 등이 적용된 상태입니다


참고했던 곳을 적어보고 간단한 후기도 적어보겠습니다



-스프링 


일단 스프링 프로젝트로 틀을 만들고 디비를 태워야합니다


하지만 관련 예제 사이트를 찾기가 만만치 않습니다


저는 예전부터 봐왔고 기록해둔 곳이 몇개 있어서 어렵지는 않았습니다




http://addio3305.tistory.com/32?category=772645


매우 유명한 사이트입니다 2014년도에 포스팅된 글인데 현재도 많이 이용해서 스프링 프로젝트를 적용해보고 계신분들이


많을거라고 생각합니다 그만큼 예제가 심플하면서도 필요한 내용들을 전부 담고있습니다


다만 저는 Mysql을 사용했기때문에 부분적으로 수정할 부분이 많았고 이게 또 많은 공부가 되었습니다


여기서 참고한 부분들은 게시판의 정수들이라고 할수있는 것들이죠


- CRUD 게시판


- 파일 업로드


- 전자정부 페이징


이렇게 해서 게시판 돌아가는것을 하나 만들었습니다.


-css/디자인 


사실 디자인은 잼병이고 실제 사이트들처럼 심플하고 고급스럽게 만들자신은 절대없습니다


그래서 개발하는분들이 그렇듯 부트스트랩테마를 가져다썻습니다 무료테마중에서 심플하고 괜찮은것들이 많습니다


   https://blackrockdigital.github.io/startbootstrap-sb-admin-2/pages/index.html


저는 SB 2 어드민 테마를 가져다썻습니다


이외에 참고할 사이트는 아래에 소개해 드립니다.


출처 : https://www.cmsfactory.net/node/10674

https://startbootstrap.com/

30개 이상의 템플릿이 있습니다. Apache License v2.0을 따르고 있습니다. 스폰서라 하여 유료 템플릿도 있습니다.

https://www.bootstrapzero.com/

70개 이상의 템플릿이 있고, MIT License를 따르고 있습니다.

http://bootswatch.com/

현재 15개의 템플릿이 있습니다. 라이센스는 MIT License입니다.

Created on 2014-05-22 16:59 | Updated on 2017-10-18 21:36





-스프링 타일즈 


스프링 타일즈는 일단 사용해 본적이 없었다가 구글검색을 통해 적용해본건데


일단 제가 원하는 예제를 보여주는 사이트가 많이 없었어서 이곳저곳을 찾아보면서 취합해야했었습니다


이 블로그에도 포스팅을 한적이있는데 참고하셔도 될것같습니다



http://epthffh.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%83%80%EC%9D%BC%EC%A6%88-Spring-Tile-%EC%84%A4%EC%A0%95%ED%95%B4%EB%B3%B4%EA%B8%B0?category=687611



참고했던 블로그 주소도 올립니다


http://pentode.tistory.com/49 


http://derveljunit.tistory.com/228


http://blog.naver.com/PostView.nhn?blogId=estern&logNo=110135537022




-스프링 시큐리티 



개인플젝에서 제일 적용해보고싶었던 것중에 하나였는데


적용도 까다롭고 보안도 완전하게 구성하기 힘들다고 들었지만 일단 적용은 해놓은 상태입니다


보통 스프링 시큐리티를 소개하는 블로그에선


메인을 로그인으로 하고 로그인 이외의 페이지는 전부 들어가는 설정의 예제를 구성했는데


개인프로젝트는 로그인을 하던안하든 대부분 페이지를 들어갈수 있으면서


관리자 페이지만 제한(Access Denied)을 두도록 설정했습니다


처음부터 프로젝트를 만들어 적용하는 예제는 따라가기 쉬웠지만


기존 로그인 로직이 적용되어있던 프로젝트에 시큐리티를 따로 적용하기가 까다로운 점이 있었습니다


로그인이 성공해도 실패해도 계속 로그인 페이지만 리다이렉트 되는 문제가 있었는데


method="post" 이 코드 한줄이 빠져있어서 4시간 삽질했던적도 있고


이후엔 수월하게 적용했던것같습니다


참고 사이트 : http://niees.tistory.com/category/spring-security 



-이후에 해봐야할것들 


아직도 거의 틀정도이지만 틀만 완성되면 나머지 페이지는 로직적인건 빼고 비슷하게 찍어낼수있겠다 생각이 듭니다


오키에도 질문한적이있지만 해보고 싶은것들을 정리해봤습니다


https://okky.kr/article/429496


스프링 메시지로 다국어처리

배치처리

메일보내기

문자보내기

코드로배우는 스프링에 있는 에러페이지 처리 적용

무한댓글

파일 zip 일괄다운(이건 해놓은게 있어서 가져다 쓰면될듯)

세션처리

암호화

달력/일정


에디터


autocomplete


엑셀 export


PDF export


그래프




해당 조건들을 모두 만족할수있는 사이트가 무었인지도 고민해봐야할것같습니다


반응형
반응형

웹페이지에서 선택박스 일명 셀렉트박스(SelectBox) 를 클릭할때마다 검색조건이 바뀌거나


페이지가 바뀌거나 하는걸 보셨을겁니다


기본적인 것이지만 경험해본적이 없으면 어떤방식으로 하는지 알기힘든부분입니다


간단하게 예제 몇가지를 통하여 알아보겠습니다


1. Question


선택을 할 수 있도록 셀렉트 박스를 만들었습니다.

샐랙트 박스에서 년도를 선택하면 바로 화면이 년도에 맞춰서 바로바로 바꿔주고 싶습니다. 

function으로 하는거 같은 어찌해야 할가요?


1
2
3
4
5
<select name="searchYear" id="searchYear">
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
</select>
cs


2. Example1


1
2
3
4
5
<select name="searchYear" id="searchYear" onchange="펑션명()">
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
</select>
cs



3. Example2


1
2
3
$("#searchYear").change(function(){
    var yearVal =  $(this).val();
})
cs

w

두가지 방법이 있는데

예제1 처럼 onchange 이벤트에 함수를 걸어주거나

change 이벤트를 태우는 방법이있습니다

방법은 여러가지이지만 개발시에는 둘중 한가지만으로 통일해서 개발하는것이 가독성에 좋습니다

적용해보시길 바랍니다






[javascript] selectbox 선택에 따라 두번째 selectbox 값 변화


selectbox의 선택에 따라 두번째 selectbox의 값이 변해야하는 경우가 있습니다.

지역 선택을 해야할 때나 품목 선택을 해야할 때가 그런 경우죠.

이때 사용하게 되는 것이, 해당하는 객체 값이 변할 때 발생하는 이벤트 함수인 onchange라는 함수입니다.

예제를 먼저 살펴볼까요. 먼저  html 부분에 해당 예제소스를 넣어주세요. 



1
2
3
4
5
6
7
8
9
10
<select onchange="categoryChange(this)">
  <option>걸그룹을 선택해주세요</option>
  <option value="a">블랙핑크</option>
  <option value="b">에프엑스</option>
  <option value="c">EXID</option>
</select>
 
<select id="good">
<option>좋아하는 멤버를 선택해주세요</option>
</select>


지극히 개인취향적인 걸그룹이 담긴 selectbox에 내용을 담고 다음에 javascript 스크립트를 넣어주면 완성입니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function categoryChange(e) {
  var good_a = ["지수", "제니", "로제", "리사"];
  var good_b = ["빅토리아", "엠버", "루나", "크리스탈"];
  var good_c = ["LE", "하니", "정화", "혜린", "솔지"];
  var target = document.getElementById("good");
 
  if(e.value == "a") var d = good_a;
  else if(e.value == "b") var d = good_b;
  else if(e.value == "c") var d = good_c;
 
  target.options.length = 0;
 
  for (x in d) {
    var opt = document.createElement("option");
    opt.value = d[x];
    opt.innerHTML = d[x];
    target.appendChild(opt);
  }
}





단지 value값만을 가져온다면 단순히 document.getElementByName("selBox").value   <---이렇게만 해줘도 된다.
그렇지만 "한국","미국","중국"처럼 내용값을 가져오려면

ex) 
<select name="selBox">
  <option value="1">한국</option>    <--0번째값
  <option value="2">미국</option>    <--1번째값  
  <option value="3">중국</option>    <--2번째값

</select>


document.getElementByName("selBox")[document.getElementByName("selBox").selelctedIndex].text
*만약2번을 선택한경우 selBox[1]번째의 text값을 가져오는것이다.



출처: http://sepiroth11.tistory.com/entry/자바스크립트select박스의-valuetext값을-얻어오기 [세피로스's 이야기]




반응형

'IT > Javascript|Jquery' 카테고리의 다른 글

비밀번호 /이메일/전화번호/핸드폰 정규식  (5) 2018.01.09
[JavaScript] ES6 문법 정리  (0) 2018.01.08
ajax 로딩시 새로고침 문제  (6) 2018.01.03
promise 패턴 예제  (0) 2018.01.02
ajax 배열전송  (0) 2018.01.02
반응형

마이바티스에서는 CDATA 구문을 많이 씁니다


이유는 쿼리문에 문자열 비교연산자나 부등호를 처리할 때가있습니다


그러면 < 와 같은 기호를 괄호인지 아니면 비교연산자 인지 확인이 되지않아요


이외에도 특수문자 사용하는데 제한이있습니다


그런이유에서 하나의 규칙같이 부등호가 없는 쿼리문에도 전부CDATA를 쓰는곳도 많습니다


CDATA는 태그안에서는 전부 문자열로 치환시켜버리기 때문입니다


하나의 예시를 보자면


1.CDATA 를 사용하지 않은쿼리


1
2
3
4
5
6
7
8
9
<select id="findAll" resultMap="MemberResultMap">
 
    select *
 
    from employees
 
    where salary > 100
 
</select>
cs



해당 쿼리는 에러가 납니다


부등호 '>' 가 닫힘 태그로 인식이 되어버리기 때문이죠


그래서 CDATA 태그를 사용해서 감싸준다면


2.CDATA 를 사용한 쿼리


1
2
3
4
5
6
7
8
9
<select id="findAll" resultMap="MemberResultMap">
    <![CDATA[
    select *
 
    from employees
 
    where salary > 100
    ]]>
</select>
cs


이런식으로사용이 가능합니다 하지만 중간에 조건문 태그를 감싸면 곤란합니다

태그가 인식을 못하기 때문입니다



3.조건 태그에서의 CDATA 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<select id="findAll" resultMap="MemberResultMap">
    <![CDATA[
    select *
 
    from employees
 
    where  1=1
    ]]>
    <choose>
        <when test='user_type != null and user_type =="1"'>
            <![CDATA[
                salary > 100
            ]]>
        </when>
 
        <otherwise>
            <![CDATA[
                salary < 100
            ]]>
        </otherwise>
    </choose>
</select>
cs



이런식으로 사용하시면 되겠습니다




검색해보면 

reg_date는 datetime형이고, 인덱스가 걸려있다고 가정한다.

1
2
3
4
5
6
7
SELECT *
FROM    Test
WHERE   date_format(reg_date, '%Y-%m-%d') BETWEEN '2013-01-01' AND '2013-01-31';
 
SELECT *
FROM    Test
WHERE   date(reg_date) BETWEEN '2013-01-01' AND '2013-01-31';
cs


이렇게 하라고 많이 써있는데,

좋은 글 발견

http://egloos.zum.com/tiger5net/v/5751776


1
2
3
4
SELECT *
from tb_user_logs
where log_time >= '2016-07-29'
and log_time < '2016-08-01'
cs


이렇게 짜면 검색속도가 엄청 빠르다고 한다.


분명 pgAdmin에서 쿼리 돌렸을 땐 잘 돌아갔는데?

왜 어? 이클립스에서 오류나지?


Mybatis는 XML에 정의하기 때문에 부등로를 그냥 쓰면 오류가 난다고,

태그에 존재하는 <tag> 꺽쇠랑 동일하여, 파싱에러가 난다고 한다.


<![CDATA[ ]]> 로 감싸주면 해결!


1
2
3
4
5
6
7
8
9
10
11
SELECT
    USER_ID,
    LOG_LEVEL,
    LOG_MSG,
    coalesce(to_char(LOG_TIME,'YYYY-MM-DD HH24:MI'),'') LOG_TIME
FROM JDN.TB_USER_LOGS
    <![CDATA[
        WHERE LOG_TIME >='2016-07-29' AND LOG_TIME < '2016-08-01'
    ]]>
ORDER BY LOG_TIME DESC
 
cs


http://tost.tistory.com/144


이제 입력받은 날짜로 제한되어 결과 값이

나와야 하는데 그러면 파라미터를 넘겨받아야겠다.


그때에 이코드가 유용할듯 


1
2
3
4
<![CDATA[
    attendance_date >=to_date(#{start_date}, 'YYYY-MM-DD' )
    and attendance_date < to_date(#{finish_date}, 'YYYY-MM-DD')
]]>
cs


참조: http://kmckmc.tistory.com/entry/MyBatis-%EC%82%AC%EC%9A%A9-%EA%B8%B0%EA%B0%84%EA%B2%80%EC%83%89




#@!@$%#$#@!!그런데!

왜 안나와???????????????

내문제다. 내가 잘 몰라서~~~~

나는 기본 초기값을 오늘날짜부터 오늘날짜까지 해서 하루치 리스트를 초기상태로 뿌리고 싶었는데.

저렇게 했을 때 '2016-07-29' 가 시작데이터고, '2016-07-29' 가 끝 데이터 일때 count 가 0으로 나와 리스트가 나오지 않는 문제가 발생했다.


DB에 찍히는 시간 값은 timestamp값이고, VO로 만들어 보내는 값은 String이고 

첨에 형이 다르다고 해서 형변환을 했다.


1
2
3
<![CDATA[
    WHERE CAST(LOG_TIME AS CHARACTER VARYING) >= #{fromDate} AND CAST(LOG_TIME AS CHARACTER VARYING)<= #{toDate}
]]>
cs


근데도 안되

왜????????

봤더니 , DB timestamp에서는 시간 분 초 그이후까지 나오는데, 강제적으로 char형으로 변환시켜놓은것이고

fromDate값으로 들어오는 '2016-07-29' 가  날짜만 가지고 비교를 하니까 기본적으로 000000으로 시간을 임의로 넣었기 때문에

값비교가 안되었던 것이다.(제기랄)


그리고 date format인 컬럼을 to_char(컬럼,'YYYY-MM-DD") 변환 후 변수와 비교할 경우 매 컬럼마다 to_char함수가 

실행되기에 컬럼건수가 많을 경우 performence에 영향을 미치게 된다.

차라리 다음과 같은 방법으로 처리하도록 하자.

1. 변수를 to_date함수를 통하여 날짜 형식으로 변환 후 비교한다.

2. Date가 아닌 VARCHAR형식의 컬럼을 추가하고 해당 컬럼에 인덱스를 추가한 다음 변수와 비교하도록 한다.


1
2
3
4
<![CDATA[
    WHERE CAST(LOG_TIME AS CHARACTER VARYING) >= (#{fromDate}||'00:00:00'
    AND CAST(LOG_TIME AS CHARACTER VARYING)<=    ( #{toDate}||'23:59:59')
]]>
cs



출처: http://daydreamer-92.tistory.com/33 [아는게1도없다]

반응형

'IT > Mybatis' 카테고리의 다른 글

mybatis , 멀티 파라메터 전달 ,anotation parameter injection  (0) 2018.02.21
반응형

원글

  • http://noritersand.tistory.com/156

관련 문서

목차


이 글은 스프링 2.x 기준으로 작성되었음.

사용빈도가 높은 어노테이션 위주로 정리.

목차에 없는 항목은 API 문서를 참고할 것. 구글링하는게속편한건함정

@Component

패키지: org.springframework.stereotype

버전: spring 2.5

설정 위치: 클래스 선언부 앞

<context:component-scan> 태그를 설정파일에 추가하면 해당 어노테이션이 적용된 클래스를 빈으로 등록하게 된다. 범위는 디폴트로 singleton이며 @Scope를 사용하여 지정할 수 있다.

사용하려면 XML 설정파일에 <context:component-scan>을 정의하고 적용할 기본  패키지를 base-package 속성으로 등록한다.

context:annotation-config 태그는 어노테이션과 관련해서 다음의 BeanPostProcessor를 함께 등록 한다.

  • @Required(RequiedAnnotationBeanPostProcessor)
  • @Autowired(AutowiredAnnotationBeanPostProcessor)
  • @Resource, @PostConstruct, @PreDestory(CommonAnnotationBeanPostProcessor)
  • @Configuration(ConfigurationClassPostProcessor)
  • 그 외 Repository, Service, Controller 포함

예를 들어 다음처럼 설정하면:

<context:component-scan base-package="xxx"/>

xxx 패키지 하위에 @Component로 선언된 클래스를 bean으로 자동 등록한다. bean의 이름은 해당 클래스명(첫글자는 소문자)이 사용된다.

<context:component-scan /> 요소에는 scoped-proxy 속성이 존재 한다. scoped-proxy는 <aop:scoped-poxy/>처럼 WebApplicationContext 에서만 유효하며 "session", "globalSession", "request" 이외의 scope는 무시 되며 아래의 3가지 값을 설정 할 수 있다.

  • no: proxy를 생성하지 않는다.(기본값)
  • interfaces: JDK Dynamic Proxy를 이용한 Proxy 생성
  • targetClass: 클래스에 대해 프록시를 생성(CGLIB를 이용한 Proxy 생성)
@Component
@Scope("prototype")   // 생략하면 싱글톤
public class Test {
       .....
}

CGLIB

기존의 자바 클래스파일로부터 자바의 소스코드를 동적으로 생성하는 라이브러리(자바 소스 변경)

http://sourceforge.net/projects/cglib/

스캔 대상 클래스 범위 지정하기

<context:include-filter> 태그와 <context:exclude-filter> 태그를 사용하면 자동 스캔 대상에 포함시킬 클래스와 포함시키지 않을 클래스를 구체적으로 명시할 수 있다.

<context:component-scan base-package="spring.demo" scoped-proxy="no">
   <context:include-filter type="regex" expression="*HibernateRepository"/>
   <context:exclude-filter type="aspectj" expression="..*IBatisRepository"/>
</context:component-scan>

위와 같이 <context:include-filter> 태그와 <context:exclude-filter> 태그는 각각 type 속성과 expresseion 속성을 갖는데, type 속성에 따라 expression 속성에 올 수 있는 값이 달라진다. type 속성에 입력가능한 값은 다음과 같다:

  • annotation: 클랙스에 지정한 어노테이션이 적용됐는지의 여부. expression 속성에서는 "org.example.SomeAnnotation"와 같은 어노테이션 이름을 입력한다.
  • assignable: 클래스가 지정한 타입으로 할당 가능한지의 여부.  expression 속성에는 "org.exampleSomeClass" 와 같은 타입 이름을 입력한다.
  • regex: 클래스 이름이 정규 표현식에 매칭되는 지의 여부.  expression 속성에는 "org\.example\.Default.*" 와 같이 정규표현식을 입력한다.
  • aspectj: 클래스 이름이 AspectJ 의 표현식에 매칭되는 지의 여부.  expression 속성에는 "org.example..*Service+" 와 같이 AspectJ 의 표현식을 입력한다.

@Required

패키지: org.springframework.beans.factory.annotation

버전: spring 2.0

설정 위치: setter 메서드 앞

Required 어노테이션은 필수 프로퍼티임을 명시하는 것으로 필수 프로퍼티를 설정하지 않을 경우 빈 생성시 예외를 발생시킨다.

import org.springframework.beans.factory.annotation.Required

public class TestBean {
    @Required
    private TestDao testDao;

    public void setTestDao(TestDao testDao) {
        this.testDao = testDao;
    }
}
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanpostProcessor"/>
<bean name="testBean"  class="han.test.TestBean">
    <property name="testDao" ref="testDao"/>
    <!-- @Required 어노테이션을 적용하였으므로 설정하지 않으면 예외를 발생시킨다. -->
</bean>

RequiredAnnotationBeanPostProcessor 클래스는 스프링 컨테이너에 등록된 bean 객체를 조사하여 @Required 어노테이션으로 설정되어 있는 프로퍼티의 값이 설정되어 있는지 검사한다.

사용하려면 <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 하지만 이를 대신하여 <context:annotation-config> 태그를 사용해도 된다:

<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    <context:annotation-config/>
</beans>

@Autowired

패키지: org.springframework.beans.factory.annotation

버전: spring 2.5

설정 위치: 생성자, 필드, 메서드(setter메서드가 아니여도 된다) 앞

의존관계를 자동설정할 때 사용하며 타입을 이용하여 의존하는 객체를 삽입해 준다. 그러므로 해당 타입의 빈객체가 존재하지 않거나 또는 2개 이상 존재할 경우 스프링은 예외를 발생시키게 된다.

options:

  • required: Autowired 어노테이션을 적용한 프로퍼티 중 반드시 설정할 필요가 없는 경우에 false값을 주어 프로퍼티가 존재하지 않더라도 스프링이 예외를 발생하지 않도록 한다. 기본값은 TRUE. ex) @Autowired(required=false)

사용하려면 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.

@Autowired를 적용할 때 같은 타입의 빈이 2개 이상 존재하게 되면 예외가 발생하는데, Autowired도 이러한 문제가 발생한다. 이럴 때 @Qualifier를 사용하면 동일한 타입의 빈 중 특정 빈을 사용하도록 하여 문제를 해결할 수 있다.

@Autowired
@Qualifier("test")
private Test test;

@Qualifier

패키지: org.springframework.beans.factory.annotation

버전: spring 2.5

설정 위치: @Autowired 어노테이션과 함께 사용된다.

qualifier 어노테이션은 @Autowired의 목적에서 동일 타입의 빈객체가 존재시 특정빈을 삽입할 수 있게 설정한다. @Qualifier("mainBean")의 형태로 @Autowired와 같이 사용하며 해당 <bean>태그에 <qualifire value="mainBean" /> 태그를 선언해주어야 한다. 메서드에서 두개이상의 파라미터를 사용할 경우는 파라미터 앞에 선언해야한다.

options:

  • name: alias명

사용하려면 동일타입의 빈객체 설정에서 <qualifier value="[alias명]" />를 추가해 준다.

<bean id="user2" class="com.sp4.UserImpl">
    <property name="name" value="스프링"/>
    <property name="age" value="20"/>
    <property name="tel" value="000-0000-0000"/>
</bean>

<bean id="userService1" class="com.sp4.UserService"/>
public class UserService {
    @Autowired
    @Qualifier("user2")
    private User user;

    public String result() {
        return user.getData();
    }
}

@Resource

자바 6 및 JEE5에 추가된 것으로 어플리케이션에서 필요로 하는 자원을 자동 연결할 때 사용 한다. 스프링 2.5 부터 지원하는 어노테이션으로 스프링에서는 의존하는 빈 객체를 전달할 때 사용한다.

@Autowired와 흡사하지만 @Autowired는 타입으로(by type), @Resource는 이름으로(by name)으로 연결한다는 점이 다르다.

options:

  • name: 자동으로 연결될 빈객체의 이름을 입력한다. ex) @Resource(name="testDao")

사용하려면 <bean class="org.springframework.beans.factory.annotation.CommonAnnotationBeanPostProcessor"/> 클래스를 빈으로 등록시켜줘야 한다. 해당 설정 대신에 <context:annotation-config> 태그를 사용해도 된다.

<beans>
    <!-- 기타 설정 생략 -->
    <context:annotation-config/>

    <bean id="user2" class="com.test.UserImpl" p:data="65536"/>
</beans>
public class UserService {
    @Resource(name="user2")
    private User user;
    //UserImpl user2 = new UserImpl();
    //User user = user2;

    public void setUser(User user) {
        this.user = user;
    }
    public String result() {
        return user.getData();
    }
}

@Scope

패키지: org.springframework.beans.factory.annotation

설정: prototype, singleton, request, session, globalSession

스프링은 기본적으로 빈의 범위를 "singleton" 으로 설정한다. "singleton" 이 아닌 다른범위를 지정하고 싶다면 @Scope 어노테이션을 이용하여 범위를 지정한다.

@Component
@Scope(value="prototype")
public class Worker {}
@Component
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class Worker {}

@PostConstruct

패키지: javax.annotation

버전: jdk1.6, spring 2.5

설정 위치: 초기화 작업 수행 메서드 앞

의존하는 객체를 설정한 이후에 초기화 작업을 수행하기 위해 사용한다. 스프링에 의해 인스턴스가 생성된 후 어노테이션이 적용된 메서드가 호출된다. 사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.

@PostConstruct
public void init() {
    System.out.println("객체 생성 후 내가 먼저 실행된다.");
}

@PreDestroy

패키지: javax.annotation

버전: jdk1.6, spring 2.5

설정 위치: 해당 작업 메서드 앞

컨테이너에서 객체를 제거하기 전에 해야할 작업을 수행하기 위해 사용한다.

사용하려면 CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시켜줘야 한다. <context:annotation-config> 태그로 대신할 수 있다.

@Inject

SR-330 표준 Annotation으로 Spring 3 부터 지원하는 Annotation이다. 특정 Framework에 종속되지 않은 어플리케이션을 구성하기 위해서는 @Inject를 사용할 것을 권장한다. @Inject를 사용하기 위해서는 클래스 패스 내에 JSR-330 라이브러리인 javax.inject-x.x.x.jar 파일이 추가되어야 함에 유의해야 한다. 

@Service

@Service를 적용한 Class는 비지니스 로직이 들어가는 Service로 등록이 된다. Controller에 있는 @Autowired는 @Service("xxxService")에 등록된 xxxService와 변수명이 같아야 하며 Service에 있는 @Autowired는 @Repository("xxxDao")에 등록된 xxDao와 변수명이 같아야 한다.

@Service("helloService")
public class HelloServiceImpl implements HelloService {
    @Autowired
    private HelloDao helloDao;

    public void hello() {
        System.out.println("HelloServiceImpl :: hello()");
        helloDao.selectHello();
    }
}

helloDao.selectHello(); 와 같이 @Autowired를 이용한 객체를 이용하여 Dao 객체를 호출한다:

@Service("test2.testService")
//괄호 속 문자열은 식별자를 의미한다.
//괄호를 생략할 경우 클래스명 그대로 사용한다.
//따라서 ,같은 클래스명이 존재 할 시 같은 식별자가 생성되기때문에 에러가 발생한다.
public class TestService {
    public String result(int num1, int num2, String oper) {
        String str = null;

        if (oper.equals("+")) {
            //...
            return str;
        }
    }
}

@Resouce로 연결

@Resource(name="test2.testService")
//name에 필요한 것은 @Service("test2.testService") <- 여기서 괄호 속 문자열, 즉 식별자

private TestService service;
//TestService service = new TestService(); 라고 하는것과 같은 식

@RequestMapping(value="/test2/oper.action", method={RequestMethod.GET})
public String form() throws Exception {
    return "test2/write";
}

@Repository

패키지: org.springframework.stereotype

버전: spring 2.0

@Repository는 일반적으로 DAO에 사용되며 DB Exception을 DataAccessException으로 변환한다.

@Repository("bbs.boardDAO")
public class BoardDAO {
    private SqlSession sqlSession;

    public int insertBoard(Board dto) throws Exception {
        ...
    }
}
public class BoardServiceImpl implements BoardService {
    @Resource(name="bbs.boardDAO")
    private BoardDAO dao;

    public int insertBoard(Board dto){}
}

@Controller

http://noritersand.tistory.com/474

@RequestMapping

http://noritersand.tistory.com/475

@RequestParam

http://noritersand.tistory.com/357

@SessionAttributes

SessionAttribute annotation은 세션상에서 model의 정보를 유지하고 싶을 경우 사용한다.

@Controller
@SessionAttributes("blog")
public class BlogController {
    // 중간생략

    @RequestMapping("/createBlog")
    public ModelMap createBlogHandler() {
        blog = new Blog();
        blog.setRegDate(new Date());
        return new ModelMap(blog);
    }

    // 중간생략
}

@SessionAttributes는 model로 할당된 객체 중 지정된 이름과 일치하는 객체를 세션 속성에도 추가한다.

@SessionAttributes("someSessionAttr")
class ExampleController2 {
	@RequestMapping("/test")
	public ModelAndView drawTest(ModelAndView view, @ModelAttribute("someSessionAttr") String someSessionAttr) {
		view.addObject("someSessionAttr", someSessionAttr);
		return view;
	}
}

@RequestBody

@RequestBody 어노테이션이 적용된 파라미터는 HTTP Request body의 내용이 전달된다.

참고: http://java.ihoney.pe.kr/283

@RequestMapping(value="/test")
public void penaltyInfoDtlUpdate(@RequestBody String body,
        HttpServletRequest req, HttpServletResponse res,
        Model model, HttpSession session) throws Exception  {

    System.out.println(body);
}

@ResponseBody

참고: http://ismydream.tistory.com/140

클라이언트에 JSON 형식의 값을 응답할 때 유용하다. 메서드에 @ResponseBody를 적용한 후 문자열을 리턴하면 그 값은 HTTP response header가 아니라 HTTP response body에 쓰여진다. 객체를 넘길경우 스프링에 내장된 JACKSON에 의해 문자열로 변환될 것이다.

또한 @ResponseBody가 적용된 컨트롤러는 context에 설정된 resolver를 무시한다.

@RequestMapping("/getVocTypeList")
@ResponseBody
public ArrayList<Object> getVocTypeList() throws Exception {
    HashMap<String, Object> vocData = gvocInf.searchVocTypeList();
    return (ArrayList<Object>) vocData.get("data");
}

@PathVariable

URL의 일부를 파라미터 혹은 변수로 사용한다.

package com.sp.ex;

@Controller("ex.exController")
public class ExController{
    @RequestMapping(value="/blog/{userId}/main.action", method=RequestMethod.GET)
    public String main(HttpServletRequest req
                       , @PathVariable String userId) throws Exception    {

        req.setAttribute("userId", userId);
        return "restful/result";
    }
}


반응형
반응형

원글 : https://okky.kr/article/432665


실무 개발중 Javascript 와 JSTL의 사용법을 헷갈려 해서 도움을 청하신분에게 답변을 해드렸습니다

잘못된 코드를 먼저 보겠습니다


-잘못된 코드1


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$.each(data.list, function(key, value){
       if( key == data.list.length-1)
         {
            var rankWeek = value.RANK_WEEK;
            var rankItem = value.RANK_ITEM;
 
            $("#RANK_WEEK").val(rankWeek);
            $("#RANK_ITEM").val(rankItem);
            
            str  =         
                "<tr style='background-color:#ffef96;'>"                 +  
                        "<th> 구분      </th>"                                         +
                        "<th> 세부분류   </th>"                                          +
                            "<c:forEach var='i' begin='1' end='4' step='1'>"     +
                                "<th>${i}주</th>"                                  +
                            "</c:forEach>"                                          +
                        "<th>총계</th>"                                              +
                        "<th>" + value.RANK_WEEK + "</th>"                        +
                        "</tr>"     ;
         }    
});
cs


여기서보면 $.each() 내부에서 <c:forEach> 를 사용하는 부분이 보입니다

개발을하다보면 당연히 혼동될수있는 부분입니다

이건 웹 의 동작방식을 알아야하는데


JAVA>JSTL>HTML>Javascript 


로 기본적으로 이렇게만 알아두시면 될거같습니다

이 작동시점을 알고 확인해보면

보여야할 부분이 Jquery 를 반복문의 시작으로 두고 JSTL을 이중반복문의 시작으로 두고있다

이부분을 확인하실수있습니다

작동순서를 1,2,3,4 순서대로의 숫자로 본다면

4(Jquery)를 먼저두고 2(JSTL)를 그다음에둬서

1,4,2,3 의 순서로 실행시키는거죠 


두번째 잘못된 코드를 확인해보겠습니다

-잘못된 코드2


1
2
3
4
5
6
7
8
9
+ 추가질문
 
input type hidden에 rankWeek 값을 저장하였습니다. 
 
<c:forEach end='4'> 대신 RANK_WEEK값을 넣어야하는데..;
다음과 작성 작성하니
"<c:forEach var='i' end='$('#RANK_WEEK').val()' >"
 
에러가 발생하네요......  어떻게 수정해야하나요... 초보라서 간단한 것도 응용이 잘 안되네요...
cs


이부분도 마찬가지로 Jquery 값 $('#RANK_WEEK').val() 을 사용한 동작 순서의 에러로 이해하시면되고

단정적으로 외워버리자면


- JSTL에선 Javascript 값을 받을수없다.

- Javascript 에선 JSTL 값을 받을수있다.



이전에 혼용사용의 포스팅을 읽어보신분이라면 두번째 문장은 이해가 가실겁니다


-올바른 사용예제

1
2
3
4
5
6
7
8
<c:forEach items="${map_list.email}" var="item2">
    list.push("${item2}");
</c:forEach>
 
 
<c:forEach var="code" items="${loc_type}">
    if(retObj.LOC_TYPE == "${code.cd_id}")        loc_type="${code.cd_nm}";
</c:forEach>
cs


Javascript와 JSTL 을 혼재해서 사용할수있는 예제입니다 참고하시면 되겠습니다

두가지에 모두 사용될수있는 el태그를 적절히 활용하는것이 중요합니다 

el태그는 ${} 이런 형식의 서버데이터 태그를 말합니다


아래는 추가 정보를 가져왔습니다


출처:

http://defacto-standard.tistory.com/entry/java-jstl-html-javascript-%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%A1%9C%EB%94%A9-%EC%88%9C%EC%84%9C-JSTL%EA%B3%BC-EL-%EA%B0%99%EC%9D%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0



간혹 가다가 웹 페이지가 예상대로 돌아가지 않을 떄가 있다.


예를 들면, JQuery를 사용해서 태그를 숨겼는데 그대로 보이는 경우이다.


이는 페이지가 로드되면서 실행되는 순서가 다르기 때문이다.

<html>
    <head>
        <script src="jquery.js" type="text/javascript"></script>
        <script src="abc.js" type="text/javascript"></script>
        <link rel="stylesheets" type="text/css" href="abc.css"></link>
        <style>h2{font-wight:bold;}</style>
        <script>
            $(document).ready(function(){
                $("#img").attr("src", "kkk.png");
            });
        </script>
    </head>
 
    <body>
        <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
        <script src="kkk.js" type="text/javascript"></script>
    </body>
</html>

 

위와 같은 소스에서 실행 순서는 다음과 같다.


1. HTML 문서 다운로드

2. HTML 문서 파싱 시작

3. HTML 파싱이 3번 라인에 도달

4. jquery.js 가 다운로드 되고 파싱된다.

5. HTML 파싱이 4번 라인에 도달

6. abc.js가 다운로드되고 파싱되고 실행된다.

7. HTML 파싱이 5번 라인에 도달

8. abc.css가 다운로드 되고 파싱된다.

9. HTML 파싱이 6번 라인에 도달

10. <style>태그 내부 CSS 규칙이 파싱되고 정의된다.

11. HTML 파싱이 7번 라인에 도달

12. 내부 Javascript다 파싱되고 실행된다.

13. HTML 파싱이 15번 라인에 도달

14. abc.jpg가 다운로드 되고 보여진다.

15. HTML 파싱이 16번 라인에 도달

16. kkk.js가 다운로드 되고 파싱된 후 실행된다.

17. 페이지 로딩이 끝났으므로 kkk.png그림이 보인다.

18. 끝


* onload함수는 페이지 로딩이 끝나는 이후 바로 실행


* Java, JSLT, HTML, Javascript가 모두 섞여있을 경우, 보기 순서대로 실행된다.

이때, 먼저 실행되는 쪽에서 뒤쪽에서 실행되는 쪽의 값을 읽을 수 없다. 준비가 안됐기 때문.


* 하나의 jsp파일 내에 작성된 소스라 하더라도,

Scriptlet이나 jstl, el 등은 서버단에서 실행되며

Javascript는 브라우저에서 실행되기 때문에 두 언어 간 변수를 직접 주고받을 수 없다.


예를 들어, 다음과 같은 방법으로 직접적으로 변수를 쓸 수 없다. 

var list = new Array();
 
list = "${TestList}";
 
alert( list[0].name );

 

쓰려면 다음과 같이 해야한다.

var list = new Array(); 

<c:foreach items="${TestList}" var="item">
list.push("${item.name}");
</c:foreach>

 

*Expression Language

${식} 과 같은 방법으로 표현한다.

JSP의 스크립트 요소(스크립틀릿, 표현식, 선언부)를 제외한 나머지 부분에서 사용할 수 있다.


반응형

'IT > Jsp|JSTL' 카테고리의 다른 글

jstl split,startsWith,endsWith 사용법  (0) 2018.01.26
JSP 에서 LinkedList 받기  (0) 2018.01.02
Javascript 에서 JSTL 사용하기 와 주의사항  (2) 2018.01.02
반응형

가끔은 실무 개발중에 일어날수있는 문제들도 다뤄보고자 한다

form 태그를 사용하면서 ajax 도 태울시에 페이지가 새로고침 하는문제가 종종발생한다


1
2
3
4
5
6
7
8
9
10
11
12
13
var paramJson = {id : $("#_id").val(), pw : $("#_pw").val()};
 
$.ajax({
    type : 'POST'// Http Request Method로 POST로 지정
    url : "login.do"// 서버 요청 주소
    contentType : 'application/json;charset=UTF-8'// 서버 요청시 전송할 데이터가 UTF-8 형식의 JSON 객체임을 명시
    data : JSON.stringify(paramJson), // JavaScript 객체를 JSON 객체로 변환하여 서버 요청시 전송
    dataType : 'json'// 서버로부터 응답받을 데이터가 JSON 객체임을 명시하여 수작업 없이 응답 데이터를 JavaScript 객체로 획득
    success : function(res){alert(res.result);}, //callBackFunc(response)
    error : function(request, status, error){
        alert(error);
    }
});    
cs



이런식으로 ajax를 태우는데 

form 태그 내부의 버튼을 눌러서 발생되는 이벤트면 form 태그의 action을 타게되는것이다

해결방법은 이러하다


-방법1


1
2
3
4
5
6
7
8
9
10
<form name="data_form" method="post" action="./">
 
<!-- 클릭시 form(data_form)의 submit 동작을 하게 됨 -->
<button id="btn_example1">버튼 예제1</button>
 
<!-- 클릭시 submit 동작하지 않고 아무 반응 없음 -->
<button type="button" id="btn_example2">버튼 예제2</button>
 
</form>
<!--출처 : http://blog.freezner.com/archives/807 -->
cs


버튼에 type="button" 을 주면 action을 타지않게된다 



-방법2


1
2
3
4
5
6
7
8
9
10
11
12
$('#form_submit').click(function(){
   $.ajax({
        type: 'post',
        url: 'process.php',
        success: function(data){
            alert(data);
        }
   });
    return false//<- 이 문장으로 새로고침(reload)이 방지됨
});
 
//출처: http://somoly.tistory.com/103 [somoly.tistory.com]
cs

버튼이벤트에서 새로고침을 막는 방법도있다
방법은 여러가지지만 사용시에는 한가지로 통일시켜야 가독성이 좋고 어떤방식인지 헷갈리지않으니
주의하도록 한다


반응형

'IT > Javascript|Jquery' 카테고리의 다른 글

[JavaScript] ES6 문법 정리  (0) 2018.01.08
javascript 셀렉트박스(SelectBox) 바로실행  (2) 2018.01.04
promise 패턴 예제  (0) 2018.01.02
ajax 배열전송  (0) 2018.01.02
모바일/PC 코딩하기  (0) 2018.01.02
반응형

오늘은 간단한 팁을 드리려고합니다

보통 submit 방식으로 데이터를 넘긴후 

알림창을띄워줘야할떄가 있습니다.

페이지로 이동해서 해도되지만 ajax 방식이 아니라서 애매하게되죠


검색하면 PrintWriter 라는 클래스를 이용하여 자바단에서 스크립트 조작이 가능합니다

그런데 잘못사용하는 경우가 있습니다


-잘못된 사용의 예


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@RequestMapping(value = "/goregist", method = RequestMethod.POST)
    @ResponseBody
    public ModelAndView OrganRegist(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> result = new HashMap<String,Object>();
        C_OrganVO vo = new C_OrganVO();
        vo.setT_num(Integer.parseInt(request.getParameter("t_num")));
        vo.setType(request.getParameter("type"));
        vo.setName(request.getParameter("name"));
        vo.setContent(request.getParameter("content"));
        vo.setHomepage(request.getParameter("homepage"));
        vo.setPhone_number(request.getParameter("phone_number"));
        int cnt = c_organService.registC_Organ(vo);
        if(cnt==1){
            result.put("state""success");
            PrintWriter writer = response.getWriter();
            writer.println("<script>alert('Success'); location.href='/helpInfo/update';</script>");
            return new ModelAndView("redirect:/helpInfo/update");
        } else{
            result.put("state""fail");
            result.put("error", egovMessageSource.getMessage("fail.update.information"));
        }
        return new ModelAndView("redirect:/helpInfo/02");
    }
cs


실제로 잘못 사용된 예제를 가져와봤습니다

여기서 보면 

1
2
3
result.put("state""success");
PrintWriter writer = response.getWriter();
writer.println("<script>alert('Success'); location.href='/helpInfo/update';</script>");
cs



이렇게 된 부분이있을건데 잘못사용된 부분입니다

response는 예민한 객체이기 때문에


1
2
3
4
5
6
7
response.setContentType("text/html; charset=UTF-8");
 
PrintWriter out = response.getWriter();
 
out.println("<script>alert('계정이 등록 되었습니다'); location.href='이동주소';</script>");
 
out.flush();
cs


이렇게 사용해주시는것이 올바를 표현방식입니다

이상 사용법설명을 마치겠습니다

반응형
반응형

# 출처 ::
 http://www.slipp.net/wiki/pages/viewpage.action?pageId=5177633

0. PC를 업그레이드한다.
– CPU의 성능보다는 저장장치의 성능에 조금 더 영향을 많이 받는다.
– RAM은 많을수록 좋고, 8G정도는 되어야하지 않을까 생각한다.
– 이제 SSD는 선택이 아니라 필수!!!

1. ‘eclipse.ini’ 설정파일 변경.
=> /eclipse/eclipse.ini
=> 각자 시스템에 맞게 변경.
-Xverify:none
-XX:+UseParallelGC
-XX:-UseConcMarkSweepGC
-XX:PermSize=64M
-XX:MaxPermSize=512M
-XX:MaxNewSize=512M
-XX:NewSize=128M
-Xms512m
-Xmx1024m

2. 소스 자동 폴딩 해제
=> Preferences > Java > Editor > Folding
=> Preferences > JavaScript > Editor > Folding

3. 코드 자동완성기능 해제(CTRL + SPACE 로 사용가능)
=> Preferences > Java > Editor > Content Assist : ‘Auto Activation’ 체크해제
=> Preferences > JavaScript > Editor > Content Assist : ‘Auto Activation’ 체크해제
=> Preferences > HTML Files > Editor > Content Assist : ‘Auto Activation’ 체크해제
=> Preferences > XML > XML Files > Editor > Content Assist : ‘Auto Activation’ 체크해제

4. 불필요한 Builder 설정 해제
=> Properties > Builders > 필요한 Builder만 체크
=> “JavaScript Validator”는 되도록 체크해제

5. JavaScript Library를 전역화하지 않는다.
=> Properties > JavaScript > Include Path > Source > Excluded : Library경로 제외

6. Spelling 체크 설정 해제
=> Preferences > General > Editors > Text Editors > Spelling : ‘Enable spell checking’ 체크해제

7. 불필요한 Validation (컴파일시 유효성체크) 설정 해제
=> Preferences > Validation

8. 작업중이지 않은 프로젝트 닫기
=> Project > Close Project

9. 불필요한 Plug-In 삭제
=> Preferences > Install/Update > Uninstall or update : 불필요한 Plug-In Uninstall

10. Eclipse 처음 실행속도 개선
=> Preferences > General > Startup and Shutdown : 불필요한 항목 체크해제

11. 자동업데이트 끄기
=> Preferences > Install/Update > Automatic Updates : 체크해제

12. Eclipse Heap Memory 관리
=> Preferences > General : Show Heap status

13. 자동빌드기능을 사용하지않는다.
=> Preferences > General > Workspace > Build automatically : 체크해제

+ 추가

14. 힙 스테이터스 추가

=> Preference > General > Show heap status 체크

체크를 하면 휴지통 모양이 보인다 누르면 힙메모리를 조절 가능하다



보통 view 작업을 진행하다 보면, 여러가지 코드가 한 파일에 뒤섞이게 된다. JSP 파일안에 html, css, javascript, java 등의 코드들이 뒤섞에 있다보면 validation이 크게 의미가 없게 되는 경우가 있는데 이럴 경우에는 굳이 validation을 할필요가 없어지게 된다. Validation은 에디터상에서 말그대로 문법에 대한 오류를 실시간으로 검사해 알려주는 것이기 때문에 validation만 해제해도 eclipse 작업속도에 그 만큼의 영향을 미치게 된다.



Window > Preferences > General > Validation > Validator 항목에서 문법검사를 하지 않을 항목에 대해 체크를 해제하면 된다.


소스 자동 폴딩 해제

블록단위로 접혀지는 자동 폴딩을 해제 합니다.  

 

자동 동작하는 코드 자동완성기능 해제

클래스의 변수, 메소드 등을 접근할 때 유용한 기능이지만 자동 동작으로 인해 버벅거리는 원인을 발생하곤 하죠?

이걸 해제한다고 해도 CTRL + SPACE 를 사용해서 동작 시킬 수 있습니다.

 

불필요한 플러그인 삭제

컴퓨터를 사용하더라도 많은 프로그램들이 깔려 있으면 컴퓨터가 느린것처럼 이클립스 또한 사용하지 않는 플러그인들은 제거하는 것이 좋습니다.

Window > Preferences > Install/Update


Autometic Update Off



출처: http://kimyhcj.tistory.com/169 [아율아빠의 스토리]

반응형
반응형
1···456789

+ Recent posts