๐Ÿ’ป Programming/์›นํ”„๋กœ๊ทธ๋ž˜๋ฐ (25)

์›น ์ƒ์—์„œ ์„ค๋ฌธ์ง€ ํŽ˜์ด์ง€์— ์ด์šฉํ•˜๊ธฐ ์ข‹์€ fieldset ํƒœ๊ทธ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

fieldset ํƒœ๊ทธ๋Š” form๋‚ด์—์„œ ์—ฐ๊ด€๋œ ์—˜๋ฆฌ๋จผํŠธ๋“ค์„ ๊ทธ๋ฃนํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ ‡๊ฒŒ ๊ทธ๋ฃนํ™”๋œ ์—˜๋ฆฌ๋จผํŠธ๋“ค์„ ๋‘˜๋Ÿฌ์‹ผ ์„ ์„ ๊ทธ๋ ค์ค๋‹ˆ๋‹ค.

์•„๋ž˜์ฒ˜๋Ÿผ ๋ง์ด์ฃ 

<fieldset> ํƒœ๊ทธ๋ฅผ ํ™œ์šฉํ•œ ์„ค๋ฌธ์ง€ ์˜ˆ์ œ

์œ„ ์ฒ˜๋Ÿผ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๋ ค๋ฉด ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<form action="#">
  <fieldset>
      <legend>1. ์ข‹์•„ํ•˜๋Š” ์ƒ‰๊น”์€?</legend>
      <input type="radio" id="blue" name="favorite-color"><label for="blue">ํŒŒ๋ž€์ƒ‰</label>
      <input type="radio" id="green" name="favorite-color"><label for="green">์ดˆ๋ก์ƒ‰</label>
      <input type="radio" id="red" name="favorite-color"><label for="red">๋นจ๊ฐ„์ƒ‰</label>
    </fieldset>
    
    <p></p>
    
    <fieldset>
      <legend>2. ์ข‹์•„ํ•˜๋Š” ์Œ์‹ ์ข…๋ฅ˜๋Š”?</legend>
      <input type="radio" id="korean" name="food-type"><label for="korean">ํ•œ์‹</label>
      <input type="radio" id="american" name="food-type"><label for="american">์–‘์‹</label>
      <input type="radio" id="japanese" name="food-type"><label for="japanese">์ผ์‹</label>
      <input type="radio" id="chinese" name="food-type"><label for="chinese">์ค‘์‹</label>
    </fieldset>
</form>

 

์ฆ‰, legend ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜์—ฌ ํƒ€์ดํ‹€์„ ๋„ฃ์–ด์ฃผ๊ณ  input ์ด๋‚˜ textarea์™€ ๊ฐ™์€ ํƒœ๊ทธ๋“ค์„ ์ด์šฉํ•ด์„œ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์œ„ ์ฝ”๋“œ์— ํ•˜๋‚˜์˜ ํ•„๋“œ์…‹์„ ๋” ์ถ”๊ฐ€ํ•˜์—ฌ ์ฃผ๊ด€์‹ ๋ฌธํ•ญ์„ ๋„ฃ์–ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

<fieldset> ํƒœ๊ทธ๋ฅผ ํ™œ์šฉํ•œ ์„ค๋ฌธ์ง€ ์˜ˆ์ œ

<form action="#">
    <fieldset>
      <legend>1. ์ข‹์•„ํ•˜๋Š” ์ƒ‰๊น”์€?</legend>
      <input type="radio" id="blue" name="favorite-color"><label for="blue">ํŒŒ๋ž€์ƒ‰</label>
      <input type="radio" id="green" name="favorite-color"><label for="green">์ดˆ๋ก์ƒ‰</label>
      <input type="radio" id="red" name="favorite-color"><label for="red">๋นจ๊ฐ„์ƒ‰</label>
    </fieldset>
    <p></p>
    <fieldset>
      <legend>2. ์ข‹์•„ํ•˜๋Š” ์Œ์‹ ์ข…๋ฅ˜๋Š”?</legend>
      <input type="radio" id="korean" name="food-type"><label for="korean">ํ•œ์‹</label>
      <input type="radio" id="american" name="food-type"><label for="american">์–‘์‹</label>
      <input type="radio" id="japanese" name="food-type"><label for="japanese">์ผ์‹</label>
      <input type="radio" id="chinese" name="food-type"><label for="chinese">์ค‘์‹</label>
    </fieldset>
    <p></p>
    <fieldset>
      <legend>3. ํƒ•์ˆ˜์œก์€ ์–ด๋–ป๊ฒŒ ๋จน์–ด์•ผ ๋ง›์žˆ๋‚˜์š”?</legend>
      <textarea placeholder="์ƒ๊ฐ์„ ์ ์–ด์ฃผ์„ธ์š”."></textarea>
    </fieldset>
  </form>

 

fieldset ํƒœ๊ทธ๋Š” ํฌ๋กฌ, ํŒŒํญ, ์—ฃ์ง€, ์˜คํŽ˜๋ผ ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ง€์›ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ fieldset์˜ ์†์„ฑ์œผ๋กœ disabled๋ฅผ ๋ช…์‹œํ•ด์ฃผ๋ฉด ํ•ด๋‹น ํ•„๋“œ์…‹ ๋‚ด์˜ ์—˜๋ฆฌ๋จผํŠธ๋“ค์ด ๋ชจ๋‘ ๋น„ํ™œ์„ฑํ™” ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

 

๊ฐœ์ธ๋ธ”๋กœ๊ทธ ๋งŒ๋“ค๊ธฐ ํ”„๋กœ์ ํŠธํ•˜๋‹ค๊ฐ€ ์•Œ๊ฒŒ๋œ ์ƒˆ๋กœ์šด ํƒœ๊ทธ๋ผ ๊ธฐ๋ก์šฉ์œผ๋กœ ํฌ์ŠคํŒ…ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

 

์ฐธ๊ณ ๋ฌธ์„œ: https://developer.mozilla.org/ko/docs/Web/HTML/Element/fieldset

์•ˆ๋…•ํ•˜์„ธ์š”, ์ผ€์ด์น˜์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ ์—ฐ๋ฝ์ฒ˜ ๊ด€๋ฆฌ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“œ๋Š” ์›น์•ฑ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉํ•  ๋„๊ตฌ๋Š” Eclipse 2020-06 R ์ด๊ณ ์š”, ์Šคํ”„๋ง๋ถ€ํŠธ์™€ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ, ๊ทธ๋ฆฌ๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™์€ mamp์™€ mybatis๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์šฐ์„  ๊ธฐ๋ณธ์ ์ธ ๋„๊ตฌ๋“ค๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค ๊ทธ๋ฆฌ๊ณ  ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์„ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœํ™˜๊ฒฝ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

  1. MacOS Catalina (10.15.6)
  2. Eclipse 2020-06 R (Download)
  3. Eclipse Spring Tool Suite 4 (์„ค์น˜ํ•˜๊ธฐ ๊ฐ€์ด๋“œ)
  4. MAMP (Download) -> community ๋ฒ„์ „ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์œผ์„ธ์š”, Window์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ WAMP๋ฅผ ์„ค์น˜ํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  5. DBeaver (๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฌด๋ฃŒ ํˆด Download) -> community ๋ฒ„์ „ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์œผ์„ธ์š”

 

์ž, ์œ„ ๋„๊ตฌ๋“ค์„ ๋ชจ๋‘ ์„ค์น˜์™„๋ฃŒํ–ˆ๋‹ค๋ฉด ์ด์ œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์šฐ์„  ๊ฒฐ๊ณผ๋ฌผ์€ ์•„๋ž˜ ๋™์˜์ƒ์ฒ˜๋Ÿผ ๋‚˜์˜ฌ๊ฒ๋‹ˆ๋‹ค.

 

์—ฐ๋ฝ์ฒ˜ ๊ด€๋ฆฌ ์›น์•ฑ

์ž, ๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ง„ํ–‰์€ ์•„๋ž˜ ์ˆœ์„œ๋Œ€๋กœ ํ•ฉ๋‹ˆ๋‹ค.

  1. ํ…Œ์ด๋ธ” ์„ค๊ณ„
  2. ๋ฐฑ์—”๋“œ ๊ตฌํ˜„
  3. ํ”„๋ก ํŠธ ๊ตฌํ˜„

 

ํ…Œ์ด๋ธ” ์„ค๊ณ„

์šฐ์„  ํ…Œ์ด๋ธ” ์„ค๊ณ„๋ถ€ํ„ฐ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. (MAMP์„ค์น˜ ๋ฐ ํ…Œ์ด๋ธ” ์†Œ์œ ์ž ๊ถŒํ•œ ๋“ฑ์˜ ์„ค์ •์€ ์—ฌ๊ธฐ์„œ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)

ํ…Œ์ด๋ธ”์€ contact ๋ผ๊ณ  ๋ช…๋ช…์ง€์–ด์ฃผ๊ณ  ์ปฌ๋Ÿผ์€ ์•„๋ž˜์ฒ˜๋Ÿผ ๋‘ ๊ฐœ๋งŒ ์ถ”๊ฐ€๋ฅผ ํ•ด์ค„ ๊ฒ๋‹ˆ๋‹ค.

CREATE TABLE `contact` (
  `name` varchar(100) NOT NULL,
  `phone` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

 

DBeaver์—์„œ ์กฐํšŒํ•œ contact ํ…Œ์ด๋ธ” ๋ช…์„ธ

์ •๋ง ๊ฐ„๋‹จํ•œ ์—ฐ๋ฝ์ฒ˜ ๊ด€๋ฆฌ ํ”„๋กœ๊ทธ๋žจ์ด๋ฏ€๋กœ ์ด๋ฆ„๊ณผ ์—ฐ๋ฝ์ฒ˜ ์ •๋ณด๋งŒ ๋‹ด์„ ์˜ˆ์ •์ด๊ณ  ๊ฐœ์ธ์ •๋ณด ์•”ํ˜ธํ™” ๊ฐ™์€๊ฑด ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ๋ฐ›์€ ์ •๋ณด ๊ทธ๋Œ€๋กœ string์œผ๋กœ ์ €์žฅ์„ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ…Œ์ด๋ธ” ์„ค๊ณ„๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์ด์ œ ๋ฐฑ์—”๋“œ์—์„œ ์ฟผ๋ฆฌํ•ด์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„์„ ๋“ค์–ด๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ

์šฐ์„  ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด์•ผ๊ฒ ์ฃ .

์•„๋ž˜ ์ˆœ์„œ๋Œ€๋กœ ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

Project Explorer > New > Project ์„ ํƒ

 

Wizards์—์„œ spring์œผ๋กœ ๊ฒ€์ƒ‰ํ•œ ๋’ค Spring Starter Prject ์„ ํƒ (์ด๊ฒŒ ์•ˆ๋‚˜์˜จ๋‹ค๋ฉด STS์„ค์น˜ํ•˜๊ธฐ๋ถ€ํ„ฐ ํ•˜๊ณ  ์˜ค์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.)

 

 

Name ํ•ญ๋ชฉ์€ ํ”„๋กœ์ ํŠธ๋ช…์„ ์ž…๋ ฅํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— contact-manager ๋ผ๊ณ  ๋„ฃ์–ด์ฃผ์‹œ๊ณ  Java Version์€ 8 ์ด์ƒ์œผ๋กœ ์•„๋ฌด๊ฑฐ๋‚˜ ์“ฐ์…”๋„ ๋ฌด๋ฐฉํ• ๊ฒ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” Java 11 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

Next๋ฅผ ๋ˆŒ๋Ÿฌ ๋‹ค์Œ์œผ๋กœ ๋„˜์–ด๊ฐ„ ๋’ค Available ๊ฒ€์ƒ‰์ฐฝ์—์„œ spring web, lombok, mybatis, mysql๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์šฐ์ธก์˜ selected ํ•ญ๋ชฉ์— ์„ธ ๊ฐœ ํ•ญ๋ชฉ์ด ๋“ค์–ด๊ฐ€๋„๋ก ์ฒดํฌํ•˜๊ณ  Finish ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ด๋ฏธ ์‚ฌ์šฉํ•œ ์ ์ด ์žˆ์–ด์„œ Frequently Used์— ํ•ญ๋ชฉ์ด ๋‚˜ํƒ€๋‚˜์„œ ์ฒดํฌ๋งŒ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ ํ•˜์‹œ๋Š” ๋ถ„๋“ค์€ Available์—์„œ ๊ฒ€์ƒ‰ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

์šฐ์ธก ํ•˜๋‹จ์— progress bar๊ฐ€ ์ง„ํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋˜๋Š” Progress View์—์„œ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์ฃ . Progress View๊ฐ€ ์•ˆ๋ณด์ธ๋‹ค๋ฉด ์ดํด๋ฆฝ์Šค ์ƒ๋‹จ ๋ฉ”๋‰ด์—์„œ Window > Show View > Other > Progress๋กœ ๊ฒ€์ƒ‰ํ•˜๋ฉด ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์ง„ํ–‰์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉด Project Explorer์—์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ํŒŒ์ผํŠธ๋ฆฌ๊ฐ€ ๋ณด์ผ๊ฒ๋‹ˆ๋‹ค.

pom.xml ํŒŒ์ผ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์ด ๋“ค์–ด์žˆ์ฃ .

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>contact-manager</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>contact-manager</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>11</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.3</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

 

 

์ด์ œ ์ž๋ฐ”๋กœ ์ฝ”๋”ฉํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

์šฐ์„  ์œ„์—์„œ ๋งŒ๋“  contact ํ…Œ์ด๋ธ”์˜ ๋‚ด์šฉ์„ ์กฐํšŒํ•ด์˜ค๋Š” API๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

com.example.demo ํŒจํ‚ค์ง€ ํ•˜์œ„์— domain ๋ผ๋Š” ์ด๋ฆ„์˜ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํŒจํ‚ค์ง€์— ContactInfo.java ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ContactInfo {
    private String name;
    private String phone;
}

 

ContactInfo ํด๋ž˜์Šค๋Š” contact ํ…Œ์ด๋ธ”๊ณผ ์—ฐ๋™ํ•  dto์ž…๋‹ˆ๋‹ค.

 

com.example.demo ํŒจํ‚ค์ง€ ํ•˜์œ„์— mapper ๋ผ๋Š” ์ด๋ฆ„์˜ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํŒจํ‚ค์ง€์— ContactInfoMapper.java ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค. ContactInfoMapper๋Š” ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ƒ์„ฑํ•ด์ฃผ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ฟผ๋ฆฌ๋ฌธ์„ ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

import com.example.demo.domain.ContactInfo;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface ContactInfoMapper {

    @Select("select * from contact")
    List<ContactInfo> selectAll();

    @Insert("insert into contact (name, phone) values (#{name}, #{phone})")
    int insert(ContactInfo contactInfo);

    @Delete("delete from contact where name = #{name}")
    int delete(String name);

    @Select("<script>" +
            "select * from contact " +
            "<where>" +
            "<if test=\"name != null and name.length > 0\">and name = #{name}</if>" +
            "<if test=\"phone != null and phone.length > 0\">and phone = #{phone}</if>" +
            "</where>" +
            "</script>")
    List<ContactInfo> selectBy(@Param("name") String name, @Param("phone") String phone);

    @Update("update contact " +
            "set phone = #{phone} " +
            "where name = #{name}")
    int update(String name, String phone);
}

 

์ด ContactInfoMapper ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค์™€ ์—ฐ๋™์ด ๋˜์–ด ์ฟผ๋ฆฌ๋ฅผ database๋กœ ์ „๋‹ฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

 

com.example.demo ํŒจํ‚ค์ง€ ํ•˜์œ„์— service ๋ผ๋Š” ์ด๋ฆ„์˜ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํŒจํ‚ค์ง€์— ContactInfoService.java ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

์ด ํŒŒ์ผ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚ด์šฉ์„ ๋„ฃ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.domain.ContactInfo;
import com.example.demo.mapper.ContactInfoMapper;

@Service
public class ContactInfoService {

	@Autowired
	private ContactInfoMapper contactInfoMapper;

	public List<ContactInfo> getEveryContactInfo() {
		return contactInfoMapper.selectAll();
	}

	public int addContactInfo(ContactInfo contactInfo) {
		return contactInfoMapper.insert(contactInfo);
	}

	public int delContactInfo(String name) {
		return contactInfoMapper.delete(name);
	}

	public List<ContactInfo> getContactInfos(String name, String phone) {
		return contactInfoMapper.selectBy(name, phone);
	}

	public int updateContactInfo(String name, String phone) {
		return contactInfoMapper.update(name, phone);
	}
}

 

ContactInfoMapper์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์—ญํ• ๋งŒ ํ•˜๊ณ  ์žˆ์ง€๋งŒ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ณต์žกํ•ด์ง€๋ฉด ๊ฐ์ข… ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋“ค์–ด๊ฐ€์•ผํ•  ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

์กฐํšŒํ•œ ๋’ค์— ์ •๋ ฌ์„ ํ•œ๋‹ค๋“ ์ง€, ํ•„ํ„ฐ๋ง์„ ํ•œ๋‹ค๋“ ์ง€ ํ•˜๋Š” ๋กœ์ง์€ ์ด ์„œ๋น„์Šค ํด๋ž˜์Šค์— ๋„ฃ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

์ด์ œ controller์ชฝ์—์„œ ์‚ฌ์šฉํ•  ์‘๋‹ต ๋„๋ฉ”์ธ ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๋” ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

com.example.demo.domain ํŒจํ‚ค์ง€์— Response.java ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonInclude(Include.NON_NULL)
public class Response<T> {

    private int code;
    private String message;
    private T data;

    public Response(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public Response(int code, String message, T data) {
        this(code, message);
        this.data = data;
    }
}

 

๋งˆ์ง€๋ง‰์œผ๋กœ com.example.demo ํŒจํ‚ค์ง€ ํ•˜์œ„์— controller ๋ผ๋Š” ์ด๋ฆ„์˜ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํŒจํ‚ค์ง€์— ContactInfoController.java ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์„œ ์•„๋ž˜ ๋‚ด์šฉ์„ ๋„ฃ์–ด์ฃผ์„ธ์š”.

import com.example.demo.domain.ContactInfo;
import com.example.demo.domain.Response;
import com.example.demo.service.ContactInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/contact-info")
public class ContactInfoController {

	@Autowired
	private ContactInfoService contactInfoService;

	@GetMapping("/list") // --> localhost:8080/contact-info/list
	public List<ContactInfo> getAllContactInfo() {
		return contactInfoService.getEveryContactInfo();
	}

	@GetMapping("/get")
	public ResponseEntity<Response> getContactInfos(
			@RequestParam(required = false) String name,
			@RequestParam(required = false) String phone) {
		List<ContactInfo> result = contactInfoService.getContactInfos(name, phone);
		if (result.size() == 0) {
			return ResponseEntity.status(HttpStatus.OK).body(new Response(204, "๋ฐ์ดํ„ฐ ์—†์Œ"));
		}
		return ResponseEntity.ok(new Response(200, "์กฐํšŒ ์„ฑ๊ณต", result));
	}

	@PostMapping("/add")
	public ResponseEntity<Response> addNewContactInfo(@RequestBody ContactInfo contactInfo) {
		contactInfoService.addContactInfo(contactInfo);
		return ResponseEntity.ok(new Response(200, "๋“ฑ๋ก ์„ฑ๊ณต"));
	}

	@DeleteMapping("/del")
	public ResponseEntity<Response> delContactInfo(@RequestParam String name) {
		int result = contactInfoService.delContactInfo(name);
		if (result == 0) {
			return ResponseEntity.status(HttpStatus.OK).body(new Response(204, "๋ฐ์ดํ„ฐ ์—†์Œ"));
		}
		return ResponseEntity.ok(new Response(200, "์‚ญ์ œ ์„ฑ๊ณต"));
	}

	@PutMapping("/update")
	public ResponseEntity<Response> updateContactInfo(@RequestParam String name, @RequestParam String phone) {
		int result = contactInfoService.updateContactInfo(name, phone);
		if (result == 0) {
			return ResponseEntity.status(HttpStatus.OK).body(new Response(204, "๋ฐ์ดํ„ฐ ์—†์Œ"));
		}
		return ResponseEntity.ok(new Response(200, "์ˆ˜์ • ์„ฑ๊ณต"));
	}

	@ExceptionHandler
	public ResponseEntity<Response> contactInfoErrorHandler(Exception e) {

		log.error("error!!, {}", e.getClass().getName(), e);

		if (e instanceof DuplicateKeyException) {
			return ResponseEntity.status(HttpStatus.CONFLICT).body(new Response(409, "์ด๋ฏธ ์ค‘๋ณต๋œ ์ด๋ฆ„์ด ๋“ฑ๋ก๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค."));
		} else {
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new Response(500, "์„œ๋ฒ„์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค."));
		}
	}
}

์ด ํด๋ž˜์Šค๊ฐ€ ํ”„๋ก ํŠธ์™€ ๋ฐฑ์—”๋“œ๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๋ถ€๋ถ„์œผ๋กœ API url์„ ์ •์˜ํ•˜๊ณ  ์–ด๋–ค ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ์ „๋‹ฌ๋ฐ›์•„์•ผ ํ•˜๋Š”์ง€, ์‘๋‹ต์€ ์–ด๋–ป๊ฒŒ ์ฃผ๊ณ  ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ๋‹ด๊ฒจ์žˆ์ฃ . 

 

์ด์ œ ๋ฐฑ์—”๋“œ ๊ตฌํ˜„์€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•„ ์ฐธ!! ํ•˜๋‚˜ ๋นผ๋จน์€๊ฒŒ ์žˆ๋„ค์š”. database ์ ‘์† ์ •๋ณด๋ฅผ ๋นผ๋จน์—ˆ์Šต๋‹ˆ๋‹ค. ์ž, src/main/resources ํ•˜์œ„์˜ application.properties ํŒŒ์ผ์„ ์—ด์–ด์„œ ์ง์ ‘ ์ƒ์„ฑํ•˜์…จ๋˜ database ์ ‘์† ์ •๋ณด๋ฅผ ์•„๋ž˜์ฒ˜๋Ÿผ ๋„ฃ์–ด์ฃผ์„ธ์š”.

spring.datasource.url=jdbc:mysql://localhost:8889/javastudy?useSSL=false&serverTimezone=UTC
spring.datasource.username=javastudy
spring.datasource.password=javastudy
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

์ ‘์† ํฌํŠธ(8889)์™€ database๋ช…(javastudy) ๊ทธ๋ฆฌ๊ณ  username, password ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•˜์‹  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋งž๊ฒŒ ๋ณ€๊ฒฝํ•ด์ฃผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ๊นŒ์ง€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด Project Explorer์— ์•„๋ž˜์™€ ๊ฐ™์ด ํŒŒ์ผ๋“ค์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ContactManagerApplication์„ Sppring Boot App์œผ๋กœ ๊ธฐ๋™ํ•ด์„œ API๊ฐ€ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธ์„ ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์•ฑ ๊ธฐ๋™์— ์„ฑ๊ณตํ•˜๋ฉด Console View์—์„œ ์•„๋ž˜ ๋กœ๊ทธ๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

INFO 69998 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
INFO 69998 --- [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
INFO 69998 --- [main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.37]
INFO 69998 --- [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
INFO 69998 --- [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1185 ms
INFO 69998 --- [main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
INFO 69998 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
INFO 69998 --- [main] c.e.demo.ContactManagerApplication       : Started ContactManagerApplication in 2.457 seconds (JVM running for 3.521)

 

์ด์ œ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์„ ์—ด๊ณ  http://localhost:8080/contact-info/get ์„ ์ฃผ์†Œ์ฐฝ์— ์ž…๋ ฅํ•˜๊ณ  ํ˜ธ์ถœํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์ฒ˜๋Ÿผ ์ถœ๋ ฅ์ด ๋˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ž˜ ๋™์ž‘ํ•œ ๊ฒ๋‹ˆ๋‹ค.

{"code":204,"message":"๋ฐ์ดํ„ฐ ์—†์Œ"}

 

์—ฌ๊ธฐ์„œ ํ˜น์‹œ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค๋ฉด ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ ๋‹ค์‹œ ์ˆœ์„œ๋Œ€๋กœ ๋”ฐ๋ผํ•ด๋ณด์„ธ์š”.

๊ทธ๋ž˜๋„ ์•ˆ๋˜์‹ ๋‹ค๋ฉด....๋Œ“๊ธ€๋กœ ์—๋Ÿฌ๋ฉ”์‹œ์ง€๋ฅผ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ํ•จ๊ป˜ ๊ณ ๋ฏผํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ž, ์ด์ œ ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.

 

ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ

ํ”„๋ก ํŠธ ์˜์—ญ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด์„œ pom.xml์— ๋‘ ๊ฐœ์˜ dependency๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

<dependency>
	<groupId>org.webjars</groupId>
	<artifactId>bootstrap</artifactId>
	<version>4.5.0</version>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

thymeleaf์™€ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  controller ํŒจํ‚ค์ง€ ๋‚ด์— ViewController.java ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์งง์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ViewController {

    @GetMapping("/contact-info")
    public String contactInfo() {
        return "contact-info";	// contact-info.html์„ ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• 
    }

}

 

๊ทธ๋ฆฌ๊ณ  src/main/resources ํ•˜์œ„์˜ templates ๋””๋ ‰ํ† ๋ฆฌ์— contact-info.html ํŒŒ์ผ์„ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜ ๋‚ด์šฉ์„ ๋„ฃ์–ด์ฃผ์„ธ์š”.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">

    <!-- JS link -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="/webjars/bootstrap/4.5.0/js/bootstrap.min.js"></script>
    <script src="script/contact-info.js"></script>

    <!-- CSS link -->
    <link rel="stylesheet"
          href="/webjars/bootstrap/4.5.0/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="style/contact-info.css"/>

</head>
<body>

<div id="content">
    <h1>์—ฐ๋ฝ์ฒ˜ ๊ด€๋ฆฌ</h1>
    <p>
        <label>์ด๋ฆ„:</label>
        <input id="name" type="text" placeholder="์ด๋ฆ„" pattern=""/>
        
        <label>์—ฐ๋ฝ์ฒ˜:</label>
        <input id="phone" type="text" placeholder="010-1234-5678"/>
        <button type="button" class="btn btn-primary btn-lg" onclick="addContact()">๋“ฑ๋ก</button>
        <button type="button" class="btn btn-danger btn-lg" onclick="delContact()">์‚ญ์ œ</button>
    </p>

    <div>
        <button type="button" class="btn btn-info btn-lg" onclick="getContacts()">์—ฐ๋ฝ์ฒ˜ ๋ชฉ๋ก ์กฐํšŒ</button>
        <table>
            <thead>
	            <tr>
	                <th class="name">Name</th>
	                <th class="phone">Phone</th>
	            </tr>
            </thead>
            <tbody id="contact-info-table"></tbody>
        </table>
    </div>
</div>


<!-- Update Modal -->
<div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel"
     aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="updateModalLabel">์—ฐ๋ฝ์ฒ˜ ์ˆ˜์ •</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary" onclick="updateContactInfo()">Save changes</button>
            </div>
        </div>
    </div>
</div>

</body>
</html>

 

๊ทธ๋ฆฌ๊ณ  src/main/resources ํ•˜์œ„์˜ static ๋””๋ ‰ํ† ๋ฆฌ ํ•˜์œ„์— style, script ๋‘ ๊ฐœ์˜ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

style ๋””๋ ‰ํ† ๋ฆฌ์—๋Š” contact-info.css ํŒŒ์ผ์„ ๋„ฃ์„๊ฑฐ๊ณ , script ๋””๋ ‰ํ† ๋ฆฌ์—๋Š” contact-info.js ํŒŒ์ผ์„ ๋„ฃ์„ ๊ฒ๋‹ˆ๋‹ค.

๊ฐ ํŒŒ์ผ์˜ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

src/main/resources/static/style/contact-info.css

body {background-color: beige;}
th {text-align:center}
.name {width:100px;}
.phone {width:200px;}
#content {margin:100px;}
#contact-info-table tr:hover {background-color: cornflowerblue;}

 

src/main/resources/static/script/contact-info.js

$( document ).ready(function() {
    getContacts();
});

function addContact() {
    let name = $('#name').val();
    if (!name) {
        alert('"name" is required!');
        return;
    }
    if (!validateName(name)) {
        alert('"name" is invalid! ํ•œ๊ธ€๋งŒ ์ž…๋ ฅ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.');
        return;
    }
    let phone = $('#phone').val();
    if (!validatePhone(phone)) {
        alert('"phone number" is invalid!\nvalid format: 000-0000-0000');
        return;
    }

    let contactInfo = new Object();
    contactInfo.name = name;
    contactInfo.phone = phone;

    $.ajax({
        url: 'contact-info/add',
        dataType: 'json',
        type: 'post',
        contentType: 'application/json',
        data: JSON.stringify(contactInfo)
    }).done(function(response) {
        alert(response.message);
        console.log(response);
        $('#name').val('');
        $('#phone').val('');
        getContacts();
    }).fail(function(jqXHR, textStatus, errorThrown) {
        alert(jqXHR.responseText);
        console.log(jqXHR.responseText);
    });
}

function validateName(name) {
    return /^[๊ฐ€-ํžฃ]+$/.test(name);
// /^[A-Za-z]+$/
}
function validatePhone(phone){
    return /^\d{2,3}-\d{3,4}-\d{4}$/.test(phone);
}

function delContact() {

    let name = $('#name').val();
    if (!name) {
        alert('"name" is required!');
        return;
    }
    $.ajax({
        url: 'contact-info/del?name=' + name,
        dataType: 'json',
        type: 'delete',
        contentType: 'application/json'
    }).done(function(response) {
        alert(response.message);
        console.log(response);
        $('#name').val('');
        $('#phone').val('');
        getContacts();
    }).fail(function(jqXHR, textStatus, errorThrown) {
        alert(jqXHR.responseText);
        console.log(jqXHR.responseText);
    });
}

function getContacts() {
    let name = $('#name').val();
    let phone = $('#phone').val();

    $.ajax({
        url: 'contact-info/get' + generateQueryParams(name,phone),
        dataType: 'json',
        type: 'get',
        contentType: 'application/json'
    }).done(function(response) {
        printContactInfos(response.data);
    }).fail(function(jqXHR, textStatus, errorThrown) {
        alert(jqXHR.responseText);
        console.log(jqXHR.responseText);
    });
}

function generateQueryParams(name, phone) {
    let params = '';
    if (name || phone) {
        params = '?';
        if (name) {
            params += 'name=' + name;
        }
        if (phone) {
           if (params.length > 1) { params += '&';}
            params += 'phone=' + phone;
        }
    }
    return params;
}

function printContactInfos(contactInfos) {
    let rows = '';
    if (contactInfos) {
        contactInfos.forEach(function (item, index) {
            rows += '<tr onclick="popsUpUpdateModal(this)" ><td class="name">' + item.name
            + '</td><td class="phone">' + item.phone + '</td></tr>';
        });
    } else {
        alert('์กฐํšŒ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.');
    }
    $('#contact-info-table').html(rows);
}
function popsUpUpdateModal(row) {
    let name = $(row).find('.name').text();
    let phone = $(row).find('.phone').text();
    let modalBody = '<input type="text" class="name" value="' + name + '" disabled>'
        + '<input type="text" class="phone" value="' + phone + '">';
    $('#updateModal .modal-body').html(modalBody);
    $('#updateModal').modal('show');
}
function updateContactInfo() {
    let name = $('#updateModal .modal-body .name').val();
    let phone = $('#updateModal .modal-body .phone').val();

    if (!validateName(name)) {
        alert('"name" is invalid! ํ•œ๊ธ€๋งŒ ์ž…๋ ฅ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.');
        return;
    }
    if (!validatePhone(phone)) {
        alert('"phone number" is invalid!\nvalid format: 000-0000-0000');
        return;
    }

    $.ajax({
        url: 'contact-info/update' + generateQueryParams(name,phone),
        dataType: 'json',
        type: 'put',
        contentType: 'application/json'
    }).done(function(response) {
        alert(response.message);
        console.log(response);
        getContacts();
        $('#updateModal').modal('hide');
    }).fail(function(jqXHR, textStatus, errorThrown) {
        alert(jqXHR.responseText);
        console.log(jqXHR.responseText);
    });
}

 

๊ฐ ํŒŒ์ผ๋“ค ๋‚ด์—์„œ ํ•˜๋Š” ์—ญํ• ์ด ๋ญ”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค๋Š” ๋ถ„๋“ค์€ ๋Œ“๊ธ€ ๋‹ฌ์•„์ฃผ์‹œ๋ฉด ์•„๋Š” ํ•œ๋„ ๋‚ด์—์„œ ๋‹ต๋ณ€ ๋‹ฌ์•„๋“œ๋ฆด๊ฒŒ์š”. 

ํฌ์ŠคํŒ…์ด ๋„ˆ๋ฌด ๊ธธ์–ด์ ธ์„œ ์ผ์ผ์ด ์„ค๋ช…์„ ๋‹ค ์ถ”๊ฐ€ํ•  ์ˆ˜๊ฐ€ ์—†์Œ์„ ์–‘ํ•ด๋ฐ”๋ž๋‹ˆ๋‹ค.

 

์ž, ์ด๋ ‡๊ฒŒ ์ด 4 ๊ฐœ์˜ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ๋‹ค์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์žฌ๊ธฐ๋™ํ•œ ๋’ค ํ™”๋ฉด์œผ๋กœ ์ ‘์†ํ•ด์„œ ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” localhost:8080/contact-info ์ฃผ์†Œ๋กœ ์ ‘์†์„ ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์•ž์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ /get ์ฃผ์†Œ๋Š” API๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ˆ ๋นผ๊ณ  ์ ‘์†ํ•ด์ฃผ์‹œ๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ํ™”๋ฉด์ด ๋œฐ๊ฒ๋‹ˆ๋‹ค.

์—ฐ๋ฝ์ฒ˜ ๊ด€๋ฆฌ ์›น์•ฑ ์™„์„ฑ

์ด ์›น์•ฑ์—์„œ๋Š” ๋“ฑ๋ก์‹œ์— ์ด๋ฆ„์„ ์ •์ƒ์ ์ธ ํ•œ๊ธ€์„ ์ž…๋ ฅํ•ด์ค˜์•ผ ํ•˜๊ณ  ์—ฐ๋ฝ์ฒ˜์˜ ๊ฒฝ์šฐ -๋ฅผ ํฌํ•จํ•˜์—ฌ ์ž๋ฆฌ์ˆ˜๋ฅผ ๊ฒ€์ฆํ•˜๋„๋ก ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒ€์ฆ์€ contact-info.js์—์„œ validateName(), validatePhone() ํ•จ์ˆ˜์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์œผ๋‹ˆ ํ™•์ธํ•ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

 

์˜ค๋ฅ˜๋ฐœ์ƒ์‹œ์—๋Š” ํ™”๋ฉด์— ์˜ค๋ฅ˜๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ๊ฒฝ๊ณ ํŒ์—…์ฐฝ์ด ๋œจ๋„๋ก ๋˜์–ด์žˆ์œผ๋ฉฐ, ์„œ๋ฒ„๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์—ฐ๋ฝ์ฒ˜ ์ˆ˜์ •์€ ์ œ์ผ ์ฒ˜์Œ์— ๊ณต์œ ํ•ด๋“œ๋ฆฐ ๋™์˜์ƒ์„ ๋”ฐ๋ผํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ๊นŒ์ง€ 30๋ถ„๋งŒ์— ์—ฐ๋ฝ์ฒ˜ ๊ด€๋ฆฌ ์›น์•ฑ ๋งŒ๋“ค๊ธฐ ํฌ์ŠคํŒ…์„ ๋งˆ์น˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๊ถ๊ธˆํ•˜์‹  ์‚ฌํ•ญ์ด๋‚˜ ์ž˜ ์•ˆ๋˜์‹œ๋Š” ๋ถ„๋“ค์€ ๋Œ“๊ธ€ ๋‹ฌ์•„์ฃผ์‹œ๋ฉด ํ™•์ธํ•ด์„œ ๋‹ต๋ณ€๋“œ๋ฆฌ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์˜ค๋Š˜๋„ ์ฆํ”„ํ•˜์„ธ์š”~ 

 

 

Eclipse + SpringBoot + JSP ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ธํŒ…ํ•˜๊ธฐ 2ํƒ„์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ backend ๋ณด๋‹ค๋Š” frontend ์ž‘์—…์„ ์œ„ํ•œ Bootstrap ์ถ”๊ฐ€๋ฅผ webjar๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด๋ณด๋„๋ก ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

์ €๋Š” backend ๊ฐœ๋ฐœ์ž๋‹ค๋ณด๋‹ˆ front์ชฝ์€ ์ž์„ธํžˆ ์•Œ๋ ค๋“œ๋ฆฌ๊ธฐ๋Š” ํž˜๋“ค์ง€๋งŒ ๋น ๋ฅด๊ฒŒ ์„œ์น˜ํ•ด์„œ ์‚ฌ์šฉํ•ด๋ณธ ๊ฒฝํ—˜์ƒ webjar๋Š” maven ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ํ†ตํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๋งค์šฐ ์‰ฝ๊ฒŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. org.webjars์—๋Š” bootstrap, jquery, font-awesome, swagger-ui ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ angularJS, momentJS, d3js ๋“ฑ ๋งค์šฐ ๋งŽ์€ ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค๋ฒˆ ๋‹ค์šด๋กœ๋“œ๋ฐ›์•„์„œ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•  ํ•„์š” ์—†์ด ๋ฐฑ์—”๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๊ด€๋ฆฌํ•˜๋“ฏ์ด ๋ฉ”์ด๋ธ ์˜์กด์„ฑ์œผ๋กœ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์šฐ์„  ์ง€๋‚œ์‹œ๊ฐ„์— ํ–ˆ๋˜ Eclipse + SpringBoot + JSP ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ธํŒ…ํ•˜๊ธฐ 1ํƒ„ ์„ ์™„์„ฑํ•˜์…จ๋˜ ๋ถ„๋“ค์„ ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…์„ ํ•  ์˜ˆ์ •์ด๋‹ˆ ํ•ด๋‹น ํฌ์ŠคํŒ…์„ ์•ˆ๋ณด์‹  ๋ถ„๋“ค์€ ํ•œ๋ฒˆ ์ญˆ์šฑ~ ํ›‘์–ด๋ณด์‹œ๊ณ  ๋‹ค์‹œ ์˜ค์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

webjar ์„ค์ •์„ ์œ„ํ•ด์„œ ์ถ”๊ฐ€ํ•  ํŒŒ์ผ์€ ๋”ฑ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. org.springframework.web.servlet.config.annotation.WebMvcConfigurer๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” WebMVCConfig ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด addResourceHandlers ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
	    if (!registry.hasMappingForPattern("/webjars/**")) {
	        registry.addResourceHandler("/webjars/**").addResourceLocations(
	                "classpath:/META-INF/resources/webjars/");
	    }
	    if (!registry.hasMappingForPattern("/**")) {
	        registry.addResourceHandler("/**").addResourceLocations(
	        		new String[] {"classpath:/static/script", "classpath:/static/style"});
	    }
    }

 

์šฐ์„  webjars ๊ฒฝ๋กœ๋ฅผ ๋“ฑ๋กํ•ด์ฃผ๋Š” ๊ฒƒ ๋•Œ๋ฌธ์— ์ด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ด๋•Œ @EnableWebMvc ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•  ์ ์ด ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ฒŒ๋˜๋ฉด WebMvcAutoConfiguration ์ด disable๋˜๋ฉด์„œ ๊ธฐ์กด ์„ค์ •๋“ค์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ์กด์— ์ž˜ ์ฝ์–ด์˜ค๋˜ staticํ•˜์œ„์˜ javascriptํŒŒ์ผ๋“ค๊ณผ cssํŒŒ์ผ๋“ค์„ ๋ชป์ฐพ์•„ 404 ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜์ฃ . ๊ทธ๋ž˜์„œ addResourceHandlers์— ์ด ๋‘ ํŒŒ์ผ๋“ค์ด ์กด์žฌํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ classpath๊ฒฝ๋กœ๋กœ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, application.properties ํŒŒ์ผ์— ์ž‘์„ฑํ•˜์˜€๋˜ ์•„๋ž˜ ๋‘ ๋ผ์ธ์€ ๋”์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐฉ๊ธˆ ์ถ”๊ฐ€ํ•œ WebMVCConfig ํด๋ž˜์Šค์— ๋ณ„๋„๋กœ ViewResolver๋ฅผ ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

	@Bean
	public ViewResolver getViewResolver(){
	    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
	    resolver.setPrefix("/WEB-INF/views/");
	    resolver.setSuffix(".jsp");
	    resolver.setViewClass(JstlView.class);
	    return resolver;
	}

 

์•„๋ž˜๋Š” ์™„์„ฑ๋œ WebMVCConfig ํด๋ž˜์Šค์˜ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
public class WebMVCConfig implements WebMvcConfigurer {

	@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
		if (!registry.hasMappingForPattern("/webjars/**")) {
	        registry.addResourceHandler("/webjars/**").addResourceLocations(
	                "classpath:/META-INF/resources/webjars/");
	    }
	    if (!registry.hasMappingForPattern("/**")) {
	        registry.addResourceHandler("/**").addResourceLocations(
	        		new String[] {"classpath:/static/script", "classpath:/static/style"});
	    }
    }
	
	@Bean
	public ViewResolver getViewResolver(){
	    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
	    resolver.setPrefix("/WEB-INF/views/");
	    resolver.setSuffix(".jsp");
	    resolver.setViewClass(JstlView.class);
	    return resolver;
	}
}

 

์ž, ๋ชจ๋“  ์ค€๋น„๋Š” ์™„๋ฃŒ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ pom.xml์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

		<!-- Bootstrap CSS -->
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>bootstrap</artifactId>
			<version>4.5.0</version>
		</dependency>

 

๊ทธ๋ฆฌ๊ณ  test.jsp ํŒŒ์ผ์„ ์—ด์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ๋งํฌ๊ฑธ์–ด์ค๋‹ˆ๋‹ค.

<link rel="stylesheet" href="/webjars/bootstrap/4.5.0/css/bootstrap.min.css" />

 

๋งŒ์•ฝ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์ด ์•„๋‹Œ jQuery์™€ ๊ฐ™์€ javascript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•  ๊ฒฝ์šฐ ์˜์กด์„ฑ ์ถ”๊ฐ€๋Š” ๋™์ผํ•˜๊ฒŒ, jspํŒŒ์ผ์— ๋งํฌ๋ฅผ ๊ฑธ์–ด์ค„ ๋•Œ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<script src="/webjars/jqeury/3.5.1/js/jqeury.min.js"></script>

 

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ ์™„๋ฃŒ๋˜๋ฉด ๋ชจ๋“  ์ค€๋น„๋Š” ๋๋‚œ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ œ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งˆ์Œ๊ป ์‚ฌ์šฉํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์ง€๋‚œ ์‹œ๊ฐ„์— ์ตœ์ข…๊ฒฐ๊ณผ๋ฌผ์—์„œ ๋ฒ„ํŠผ์„ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด๋ณด๋Š” ์ •๋„๋กœ ์ด๋ฒˆ ํฌ์ŠคํŒ…์„ ๋งˆ์น˜๊ฒ ์Šต๋‹ˆ๋‹ค.

test.jsp์˜ body์— ๋‹ค์Œ ํ•œ ์ค„์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

<button type="button" class="btn btn-danger btn-lg">๋ฒ„ํŠผ</button>

 

๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋นจ๊ฐ„์ƒ‰ ๋ฒ„ํŠผ์ด ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด์ƒ์œผ๋กœ Eclipse + SpringBoot + JSP ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ธํŒ…ํ•˜๊ธฐ 2ํƒ„ ํฌ์ŠคํŒ…์„ ๋งˆ์นฉ๋‹ˆ๋‹ค.

์˜ค๋Š˜๋„ ์ฆ๊ฒ๊ณ  ํ–‰๋ณตํ•œ ์ฝ”๋”ฉ์„ ํ•˜๋Š” ์ผ€์ด์น˜์˜€์Šต๋‹ˆ๋‹ค~

์ดํด๋ฆฝ์Šค์—์„œ ์Šคํ”„๋ง๋ถ€ํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ JSP๊ฐœ๋ฐœํ•˜๊ธฐ

์•ˆ๋…•ํ•˜์„ธ์š”, ์˜ค๋Š˜์€ ์Šคํ”„๋ง๋ถ€ํŠธ ๊ธฐ๋ฐ˜์œผ๋กœ JSP๊ฐœ๋ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์„ธํŒ…ํ•˜๋Š” ๊ณผ์ •์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

์ตœ๊ทผ์— ๋Œ€๊ทœ๋ชจ์˜ ์›น ๊ฐœ๋ฐœ์€ ๋ฐฑ์—”๋“œ์™€ ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ๋ณ„๋„์˜ ํ”„๋กœ์ ํŠธ๋กœ ๊ตฌ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ชจ๋“ˆ๋กœ ๋‚˜๋ˆ„์–ด ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ๊ฐœ๋ฐœ์„ ํ•˜๋˜์ง€ ๊ฒฐ๊ตญ ๋ฐฑ์—”๋“œ์™€ ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ์™„์ „ํžˆ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜๊ฒŒ๋˜์ฃ . ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ๊นŒ์ง€ ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์ž‘์€ ํ”„๋กœ์ ํŠธ๋“ค์€ ๊ตณ์ด ๊ทธ๋ ‡๊ฒŒ ๋‚˜๋ˆ„์–ด ๊ฐœ๋ฐœ์„ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๊ตฌ๋ถ„์„ ํ•˜๋Š” ๊ฒƒ์ด ์˜คํžˆ๋ ค ์œ ์ง€๋ณด์ˆ˜๋ฅผ ํž˜๋“ค๊ฒŒ ํ•˜๋Š” ์›์ธ์ด ๋˜๊ธฐ๋„ ํ•˜์ฃ .

์˜ค๋Š˜์€ ํ•˜๋‚˜์˜ ์Šคํ”„๋ง๋ถ€ํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  JSP๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ธํŒ…ํ•˜๋Š” ๋ถ€๋ถ„๊นŒ์ง€ ์•Œ๋ ค๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ์ค€๋น„๋ฌผ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

1. Eclipse (2020๋…„ 7์›” ๊ธฐ์ค€ ์ตœ์‹ ๋ฒ„์ „ ๋‹ค์šด๋กœ๋“œ)

Version: 2020-09 M1 (4.17.0 M1)

 

2. Spring Tools plugin (์„ค์น˜๋ฐฉ๋ฒ•)

 

์ด๋ ‡๊ฒŒ๋งŒ ์žˆ์œผ๋ฉด ์ผ๋‹จ ์ค€๋น„๋Š” ์™„๋ฃŒ์ž…๋‹ˆ๋‹ค.

 

์ด์ œ ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ดํด๋ฆฝ์Šค๋ฅผ ์ฒ˜์Œ ์„ค์น˜ํ•˜์‹  ๋ถ„์ด๋ผ๋ฉด ํŒจํ‚ค์ง€ ํƒ์ƒ‰๊ธฐ(Project Explorer)์— ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜ค๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ๋ฐ‘์—์„œ ๋‘ ๋ฒˆ์งธ์— ์žˆ๋Š” Create a project...๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด๋ฏธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋†“์€๊ฒŒ ์žˆ๋Š” ๋ถ„๋“ค์ด๋ผ๋ฉด ๊ทธ๋ƒฅ ํƒ์ƒ‰๊ธฐ ์ฐฝ์—์„œ ์šฐํด๋ฆญํ•ด์„œ New > Project ๋ฅผ ์„ ํƒํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ์ƒˆ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋œจ๋ฉด spring ์œผ๋กœ ๊ฒ€์ƒ‰์„ ํ•ด์„œ Spring Starter Project๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

 

์ด์ œ ๋งŒ๋“ค ํ”„๋กœ์ ํŠธ์˜ ์ด๋ฆ„์„ Name ํ•ญ๋ชฉ์— ์ ์–ด์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Java Version ์€ 11๋กœ ์„ ํƒํ•ด์ค๋‹ˆ๋‹ค. (8๋กœ ํ•ด๋„ ๋ฌด๋ฐฉํ•ฉ๋‹ˆ๋‹ค)

 

Spring Boot์˜ ๋ฒ„์ „์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด ๋ถ€๋ถ„์€ ๊ทธ๋Œ€๋กœ ๋†”๋‘๊ณ  Available ๊ฒ€์ƒ‰์ฐฝ์—์„œ web์ด๋ผ๊ณ  ๊ฒ€์ƒ‰ํ•˜์—ฌ Spring Web์„ ์„ ํƒํ•ด์ค๋‹ˆ๋‹ค. (์ด์™ธ์—๋„ lombok์ด๋‚˜ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„, MyBatis ๋“ฑ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์„ ํƒํ•˜์—ฌ ์‚ฌ์ „์„ค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค๋งŒ ์—ฌ๊ธฐ์„œ๋Š” ์„ ํƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)

 

Finish ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ–๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

์ด์ œ MyDemoApplication.java ํŒŒ์ผ์„ ์—ด์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์ค๋‹ˆ๋‹ค.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class MyDemoApplication extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(MyDemoApplication.class);
	}

	public static void main(String[] args) {
		SpringApplication.run(MyDemoApplication.class, args);
	}

}

SpringBootServletInitializer๋ฅผ ์ƒ์†ํ•˜๊ณ  configure ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  pom.xml ํŒŒ์ผ์— ์•„๋ž˜ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค. jasper๋Š” JSP ํŒŒ์ผ์„ ์ปดํŒŒ์ผ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ํ•ฉ๋‹ˆ๋‹ค.

<!-- Need this to compile JSP -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

 

์ด์ œ ํ”„๋กœ์ ํŠธ๋ช…์—์„œ ์šฐํด๋ฆญํ•˜๊ณ  "src/main/webapp" ์ƒˆ ํด๋”๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํด๋”๋ฅผ ๋งŒ๋“ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

 

์ด์ œ ๋‹ค์‹œ ์šฐํด๋ฆญํ•˜์—ฌ build path ์„ค์ •(Configure Buildpath...)ํ™”๋ฉด์œผ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

 

Add Folder... ๋ฅผ ํด๋ฆญํ•˜๊ณ  webapp ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ฐพ์•„ ์ฒดํฌํ•ด์ค๋‹ˆ๋‹ค.

OK ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  Applyํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ”๋€๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ webapp ์•„๋ž˜์— WEB-INF๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•˜์œ„์— ๋˜ views ๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  test.jsp ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ค๋‹ˆ๋‹ค.

<%@ page import="java.util.*" %>

<!DOCTYPE html>
<html>
<body>
	<h1>Test Page</h1>
	Today's date: <%= new Date() %>
</body>
</html>

 

application.properties ํŒŒ์ผ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‘ ๋ผ์ธ์„ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp

 

์ž, ์ด์ œ ๋งˆ์ง€๋ง‰์œผ๋กœ ํ•ด๋‹น ํŽ˜์ด์ง€์™€ ์—ฐ๊ฒฐํ•  API๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. root package์—์„œ controller ๋ผ๋Š” ํŒจํ‚ค์ง€๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ๊ทธ ์•„๋ž˜์— DemoController.java๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

package com.example.demo.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class DemoController {
	
	@GetMapping("/test")
	public String login() {
		return "/test";
	}
}

 

์—ฌ๊ธฐ๊นŒ์ง€ ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉด ์ด์ œ Run As > Java Application ๋˜๋Š” Run As > Spring Boot App ์œผ๋กœ ๊ธฐ๋™์‹œ์ผœ์ค๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  localhost:8080/test ์— ์ ‘์†ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด jsp ํŽ˜์ด์ง€๊ฐ€ ๋œจ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

JSP ํŽ˜์ด์ง€์— javascript ๋ฐ css ํŒŒ์ผ ์—ฐ๋™

์ด์ œ JSP ํŽ˜์ด์ง€์— javascript ํŒŒ์ผ ๋ฐ css ํŒŒ์ผ์„ ์—ฐ๊ฒฐ์‹œ์ผœ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

javascript์™€ css ํŒŒ์ผ์€ src/main/resources ํ•˜์œ„์˜ static ํด๋” ์•ˆ์ชฝ์— ๋ชฐ์•„๋„ฃ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์šฐ์„  static ํด๋” ํ•˜์œ„์— script ํด๋”๋ฅผ ๋งŒ๋“ค์–ด test.jsํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

$(document).ready(function() { printCurrentDatetime(); });

function printCurrentDatetime() {
	let date = new Date();
	$('#currentTime').html(date);
	setTimeout(printCurrentDatetime, 1000);
}

 

๊ทธ๋ฆฌ๊ณ  static ํด๋” ํ•˜์œ„์— style ํด๋”๋ฅผ ๋งŒ๋“ค์–ด test.css ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

@charset "UTF-8";

body {background-color:cornflowerblue;}

 

์ž, ๋”์ด์ƒ ํŒŒ์ผ์„ ๋งŒ๋“ค ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ JSP ํŒŒ์ผ์— ์œ„์—์„œ ์ž‘์„ฑํ•œ ๋‘ ํŒŒ์ผ์„ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

test.jsp ํŒŒ์ผ์„ ์—ด์–ด ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์ค๋‹ˆ๋‹ค.

<%@ page import="java.util.*"%>

<!DOCTYPE html>
<html>
<head>

<!-- JS link -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="script/test.js"></script>

<!-- CSS link -->
<link href="style/test.css" rel="stylesheet">

</head>
<body>
	<h1>Test Page</h1>
	Today's date: <span id='currentTime'></span>
</body>
</html>

 

๋ณ€๊ฒฝํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

1. html์˜ body ์•ˆ์— ์žˆ๋˜ ์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ test.js๋กœ ์˜ฎ๊ธฐ๋ฉด์„œ refresh ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€

2. test.jsํŒŒ์ผ์—์„œ jquery๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— htmlํŽ˜์ด์ง€(jspํŒŒ์ผ)์— jQuery ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋งํฌ ์ถ”๊ฐ€

3. css ๋งํฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  body์˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ƒ‰์ƒ์„ cornflowerblue ๋กœ ์„ค์ •

 

์—ฌ๊ธฐ๊นŒ์ง€ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ์ตœ์ข…์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ๋ฅผ ๊ฐ–๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

SpringBoot + JSP ์—ฐ๋™ ์ตœ์ข… ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

 

์—ฌ๊ธฐ๊นŒ์ง€ ์ž˜ ๋”ฐ๋ผ์˜ค์…จ๋‹ค๋ฉด ์‹คํ–‰์‹œ์ผฐ์„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด ํ˜„์žฌ์‹œ๊ฐ„์ด ๊ณ„์† ์—…๋ฐ์ดํŠธ๋˜๋Š” ํŒŒ๋ž€ ํ™”๋ฉด์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Š

 

์ตœ์ข… ์™„๋ฃŒ ํ™”๋ฉด

 

์ด์ƒ์œผ๋กœ Eclipse์—์„œ SpringBoot์™€ JSP๋ฅผ ์—ฐ๋™ํ•˜์—ฌ ์›นํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

์ž๋™์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” mysql ๋ฐ๋ชฌํ”„๋กœ์„ธ์Šค ๊ฐ•์ œ์ข…๋ฃŒ

MySQL 8 ๋ฒ„์ „(mysql-8.0.20-macos10.15)์„ MacOS 10.14 (Mojave) ์— ์„ค์น˜ํ–ˆ๋‹ค. ์„ค์น˜๋Š” CE๋ฒ„์ „ dmg ํŒŒ์ผ์„ ๋‹ค์šด๋ฐ›์•„์„œ ํ–ˆ๋Š”๋ฐ, ์„ค์น˜ํ•  ๋•Œ ๋งˆ์ง€๋ง‰์— ์ธ์Šคํ†จ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ ํ›„ ์ž๋™์œผ๋กœ MySQL์„ ์‹œ์ž‘ํ• ๊ฑด์ง€์— ๋Œ€ํ•œ ์ฒดํฌ๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š๊ณ  finishํ–ˆ๊ณ , MAMP๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๊ธธ๋ž˜(ํŒ์—…์ฐฝ์ด ๋œจ์ง€ ์•Š๊ธธ๋ž˜) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ˆ˜๋™์œผ๋กœ ์‹คํ–‰์„ ์‹œ์ผฐ๋Š”๋ฐ nginx ์„œ๋ฒ„๋งŒ ๋œจ๊ณ  mysql ์„œ๋ฒ„๊ฐ€ ๋œจ์ง€ ์•Š์•˜๋‹ค.

์˜ค๋žœ๋งŒ์— MAMP๋ฅผ ์“ฐ๋ ค๋‹ค๋ณด๋‹ˆ ์™œ ์•ˆ๋œจ๋Š”์ง€ ์›์ธ์„ ์ฐพ๊ธฐ๊ฐ€ ํž˜๋“ค์–ด์„œ ์ •๋ฆฌํ•ด๋ณธ๋‹ค.

์ผ๋‹จ mysql ์„œ๋ฒ„์˜ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ด๋ณด๋ ค ํ–ˆ๋‹ค. ๋กœ๊ทธ ์œ„์น˜๊ฐ€ ์–ด๋””์ธ์ง€๋ฅผ ๋ชฐ๋ผ์„œ ๊ทธ๋ƒฅ find ๋ช…๋ น์–ด๋กœ mysql*.log ํŒŒ์ผ์„ ์ฐพ์œผ๋ คํ–ˆ๋Š”๋ฐ ์•ˆ๋‚˜์˜จ๋‹ค -_-; ๊ทธ๋ž˜์„œ ๊ตฌ๊ธ€๋ง์„ ํ•ด๋ดค๋”๋‹ˆ .err ํ™•์žฅ์ž๋กœ ๋๋‚˜๋Š” ํŒŒ์ผ์ด MAMP ์•ˆ์— log ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์— ์žˆ์—ˆ๊ณ (ํŒŒ์ผ๋ช…์€ mysql_error_log.err ์ด๋‹ค) ํ•ด๋‹น ํŒŒ์ผ์„ ์—ด์–ด์„œ ์—๋Ÿฌ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ–ˆ๋”๋‹ˆ ํ•ด๋‹น ํฌํŠธ๊ฐ€ ์ด๋ฏธ ์‚ฌ์šฉ์ค‘์ด๋ž€๋‹ค. ์˜ค์ž‰? ๊ทธ๋Ÿผ ์„ค์น˜ํ›„์— ์‹คํ–‰์ด ๋๋‹ค๋Š” ์–˜๊ธด๊ฐ€??? ๊ทธ๋ž˜์„œ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ™•์ธํ•ด๋ณด์•˜๋‹ค.

ps -ef|grep mysql

๊ทธ๋žฌ๋”๋‹ˆ mysql ๋ฐ๋ชฌ์ด ์ด๋ฏธ ๋– ์žˆ๋‹ค. ์‹คํ–‰์‹œํ‚จ ์œ ์ €๋Š” _mysql ์ด๋ผ๊ณ  ๋˜์–ด์žˆ์—ˆ๊ณ  ์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋„๊ณ  ๋‹ค์‹œ MAMP๋ฅผ ์‹คํ–‰์‹œ์ผœ์„œ mysql ์„œ๋ฒ„๋ฅผ ๋„์šฐ๋ ค๊ณ  kill -9 PID๋ฅผ ์‹คํ–‰์‹œ์ผฐ๋Š”๋ฐ ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๋Š” ๊บผ์กŒ์œผ๋‚˜ ๋‹ค๋ฅธ PID๋ฅผ ๊ฐ–๋Š” mysql๋ฐ๋ชฌ์ด ์ž๋™์œผ๋กœ ์‹คํ–‰์ด ๋˜์–ด์žˆ์—ˆ๋‹ค. ใ…กใ…ก;

๋ญ์ง€?? ์–˜ ์ข€๋น„๋„ค? ๋‹ค์‹œ ์—ด์‹ฌํžˆ ๊ตฌ๊ธ€๋ง์„ ํ•ด์„œ ๋™์ผํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•ด ์„ค๋ช…์„ ์ž˜ ํ•ด๋†“์€ ๋ฏธ๋””์—„ ํฌ์ŠคํŒ…์„ ํ•˜๋‚˜ ์ฐพ์•˜๋‹ค. ๋ฐ”๋กœ ์—ฌ๊ธฐ์ด๋‹ค. ํ•ด๋‹น ์‚ฌ์ดํŠธ์—์„œ๋Š” mysql-8.0.12-macos10.13 ๋ฒ„์ „์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์žˆ์—ˆ๊ณ  ๋‚ด๊ฐ€ ์„ค์น˜ํ•œ ๋ฒ„์ „์€ mysql-8.0.20-macos10.15 ๋ฒ„์ „์ด์—ˆ๋‹ค. ์•„๋งˆ macOS ๋ฒ„์ „๋„ ๋‹ค๋ฅด์ง€ ์•Š์„๊นŒ ์‹ถ์€๋ฐ ์•„๋ฌดํŠผ ์ € ์‚ฌ์ดํŠธ์˜ ์„ค๋ช…๋Œ€๋กœ ํ•ด๋„ ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๋Š” ์ฃฝ์—ˆ๋‹ค ์‚ด์•„๋‚˜๊ณ  ์ฃฝ์—ˆ๋‹ค ์‚ด์•„๋‚˜๊ณ ๋ฅผ ๋ฐ˜๋ณตํ–ˆ๋‹ค.


๊ทธ๋ž˜์„œ ์ข€ ๋” ๊ตฌ๊ธ€๋ง์„ ํ•˜์—ฌ MySQL ๊ณต์‹ ๋ฌธ์„œ ์ค‘ MySQL launch daemon์— ๊ด€ํ•œ ๋ฌธ์„œ๋ฅผ ๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ํ•ด๋‹น ๋ฌธ์„œ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์ด ์žˆ์—ˆ๋‹ค.

2.4.3 Installing and Using the MySQL Launch Daemon
macOS uses launch daemons to automatically start, stop, and manage processes 
and applications such as MySQL.

By default, the installation package (DMG) on macOS installs a launchd file named 
/Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist that contains a plist 
definition similar to:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>             <string>com.oracle.oss.mysql.mysqld</string>
    <key>ProcessType</key>       <string>Interactive</string>
    <key>Disabled</key>          <false/>
    <key>RunAtLoad</key>         <true/>
    <key>KeepAlive</key>         <true/>
    <key>SessionCreate</key>     <true/>
    <key>LaunchOnlyOnce</key>    <false/>
    <key>UserName</key>          <string>_mysql</string>
    <key>GroupName</key>         <string>_mysql</string>
    <key>ExitTimeOut</key>       <integer>600</integer>
    <key>Program</key>           <string>/usr/local/mysql/bin/mysqld</string>
    <key>ProgramArguments</key>
        <array>
            <string>/usr/local/mysql/bin/mysqld</string>
            <string>--user=_mysql</string>
            <string>--basedir=/usr/local/mysql</string>
            <string>--datadir=/usr/local/mysql/data</string>
            <string>--plugin-dir=/usr/local/mysql/lib/plugin</string>
            <string>--log-error=/usr/local/mysql/data/mysqld.local.err</string>
            <string>--pid-file=/usr/local/mysql/data/mysqld.local.pid</string>
            <string>--keyring-file-data=/usr/local/mysql/keyring/keyring</string>
            <string>--early-plugin-load=keyring_file=keyring_file.so</string>
        </array>
    <key>WorkingDirectory</key>  <string>/usr/local/mysql</string>
</dict>
</plist>

์ฆ‰, mysql์„ ์„ค์น˜ํ•˜๋ฉด /Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist ํŒŒ์ผ์— ์œ„์™€ ๊ฐ™์€ ์„ค์ • ๋‚ด์šฉ์ด ๋“ค์–ด์žˆ๋‹ค๋Š” ๋‚ด์šฉ์ด์—ˆ๊ณ  ์„ค์ • ํ•ญ๋ชฉ๋“ค ์ค‘์— ์ž๋™์‹คํ–‰๊ณผ ๊ด€๋ จ๋œ ํ•ญ๋ชฉ์ด ์žˆ์„๊นŒ ์‹ถ์–ด ์ญˆ์šฑ ํ›‘์–ด๋ณด๋‹ˆ RunAtLoad ์™€ LaunchOnlyOnce ํ•ญ๋ชฉ์ด ๋ˆˆ์— ๋„์—ˆ๋‹ค.
์ผ๋‹จ ๋‘˜๋‹ค ๊ธฐ๋ณธ๊ฐ’๊ณผ ๋ฐ˜๋Œ€๋กœ ์„ค์ •ํ•˜์—ฌ RunAtLoad ๊ฐ’์€ false๋กœ, LaunchOnlyOnce์˜ ๊ฐ’์€ true๋กœ ์ˆ˜์ •ํ•ด์„œ ์ €์žฅํ•˜๊ณ  ๋‹ค์‹œ kill์„ ํ•ด๋ณด์•˜๋‹ค. (์ด ๊ณผ์ •์—์„œ ์žฌ๋ถ€ํŒ…์„ ํ–ˆ์—ˆ๋Š”์ง€ ์ •ํ™•ํžˆ ๊ธฐ์–ต์ด ๋‚˜์ง€๋Š” ์•Š๋Š”๋‹ค;; ์•ˆํ–ˆ๋˜๊ฒƒ ๊ฐ™์€๋ฐ..^^; ) ๊ทธ๋žฌ๋”๋‹ˆ ๋”์ด์ƒ ์ž๋™์œผ๋กœ ์‹คํ–‰๋˜์ง€ ์•Š์•˜๊ณ , MAMP๋ฅผ ์‹คํ–‰์‹œ์ผœ์„œ mysql ์„œ๋ฒ„๋ฅผ startํ•˜๋‹ˆ ์ด์ œ ์ž˜ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
 

๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๊พธ~~์šฑ~~ 

MySQL์˜ auto_increment ๊ฐ’์ด ์ฆ๊ฐ€ํ•˜๋Š” ์‹œ์ 

์‚ฌ๋‚ด์—์„œ ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘์„ ์œ„ํ•ด์„œ ํ…Œ์ด๋ธ” ๋งŒ๋“ค ๋•Œ auto increment ์ปฌ๋Ÿผ์„ pk๋กœ ์ถ”๊ฐ€ํ•ด๋‹ฌ๋ผ๋Š” ์š”์ฒญ์ด ์žˆ์–ด์„œ ํ…Œ์ด๋ธ” ์ƒ์„ฑ์‹œ ๊ผญ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ auto increment ์ปฌ๋Ÿผ์˜ ๊ฐ’์€ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ(insert)๋  ๋•Œ๋งŒ ์˜ฌ๋ผ๊ฐˆ ๊ฑฐ๋ผ๊ณ  ์ง€๋ ˆ์ง์ž‘๋งŒ ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์ด๋ฒˆ์— ์–ด๋–ค ์„œ๋น„์Šค๋ฅผ ๋นจ๋ฆฌ ๊ฐœ๋ฐœํ•ด์ค˜์•ผํ•ด์„œ ์ƒˆ๋กœ์šด ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด ํ…Œ์ŠคํŠธํ•˜๋‹ค๊ฐ€ auto increment๊ฐ’์ด ์ˆœ์„œ๋Œ€๋กœ ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋Š” ํ˜„์ƒ์„ ๋ณด๊ฒŒ๋˜์—ˆ๋‹ค.

ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋Š” insert -> select -> update -> select ์ˆœ์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ๊ตฌ์„ฑํ–ˆ๊ณ  ๋™์ผํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ตœ์†Œ ๋‘ ๋ฒˆ ์ด์ƒ ๋Œ๋ ธ๋‹ค. ์ด๋ ‡๊ฒŒ ๋Œ๋ฆฌ๋‹ˆ๊นŒ ์ฒ˜์Œ์—๋Š” ๋‹น์—ฐํžˆ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์–ด์„œ no๊ฐ’์€ default๋กœ 1๋กœ ์ƒ์„ฑ์ด ๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋˜‘๊ฐ™์€ ํ…Œ์ŠคํŠธ์ผ€์ด์Šค๋ฅผ ๋‹ค์‹œ ๋Œ๋ฆฌ๋ฉด duplicate key exception์ด ๋ฐœ์ƒํ•˜๋ฉด์„œ ๋‚ด๋ถ€์ ์œผ๋กœ auto increment๊ฐ’์ด ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์„ ์ค„ ์•Œ์•˜์œผ๋‚˜, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์ง€ ๋ชปํ•œ๋‹คํ•ด๋„ insert๊ฐ€ ์‹œ๋„๋  ๋•Œ๋งˆ๋‹ค no๊ฐ’์ด ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. auto increment๊ฐ’์ด ์ฆ๊ฐ€ํ•˜๋Š” ์ผ€์ด์Šค๋ฅผ ์ •๋ฆฌํ•˜์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1. insert๊ฐ€ ์‹œ๋„๋˜๋ฉด no๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค.

2. duplication key ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹คํ•ด๋„ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค.

3. update์‹œ์—๋Š” ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์•˜๋‹ค.

์ผ๋ถ€ ํ…Œ์ด๋ธ”์€ ๋งŽ์€ ์–‘์˜ insert on duplicate key update ๋ฌธ์„ ์‹คํ–‰ํ•˜๊ณ ์žˆ๋Š”๋ฐ auto increment๊ฐ’์ด overflow ๋˜์ง€ ์•Š์„๊นŒ ์—ผ๋ ค๋˜์–ด ํ˜„์žฌ max no๊ฐ’์„ ์กฐํšŒํ•ด๋ณด๋‹ˆ ์•„์ง ์ˆ˜ ๋…„์€ ๋ฒ„ํ‹ธ ์ˆ˜๋Š” ์žˆ์„ ์ •๋„์˜€๋‹ค.

๋งŒ์•ฝ overflow ๋ ์ •๋„๋กœ ๋งŽ์ด ์˜ฌ๋ผ๊ฐ„๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ ??? no ๊ฐ’์„ ๋‹ค์‹œ 1๋กœ ์„ธํŒ…ํ•˜์—ฌ ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๊ธฐ๋Š” ํ•˜๋‹ค. ์•„๋ž˜ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋ฉด ๋‹ค์‹œ 1๋ถ€ํ„ฐ ์„ธํŒ…์„ ํ•ด์ค€๋‹ค.

ALTER TABLE YOUR_TABLE_NAME AUTO_INCREMENT=1;
SET @COUNT = 0;
UPDATE YOUR_TABLE_NAME SET AUTO_INCREMENT_COLUMN_NAME = @COUNT:=@COUNT+1;

ํ•˜์ง€๋งŒ ํ•ด๋‹น ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ lock์ด ์žกํž ๊ฒƒ์ด๋ผ์„œ ์ ๊ฒ€๋•Œ์—๋‚˜ ์‹คํ–‰ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

์ด ๋ฐฉ๋ฒ• ๋ง๊ณ  ์ง์ ‘ no๋ฅผ ์„ธํŒ…ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. ๋ฐ์ดํ„ฐ ์ €์žฅ ์‹œ์— no๊ฐ’์„ ์ง์ ‘ ํ• ๋‹นํ•ด์ค„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋ง์ด๋‹ค.

MyBatis TypeHandler๋ฅผ ์ด์šฉํ•œ ๊ฐ์ฒด๋ฆฌ์ŠคํŠธ ํ•ธ๋“ค๋ง

์ด๋ฒˆ์— ํŠน์ • ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๋‹ค๊ฐ€ JSON ํ˜•ํƒœ์˜ ์ŠคํŠธ๋ง์„ ๊ทธ๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๊บผ๋‚ด์จ์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์ƒ๊ฒผ๋‹ค.

๊ทธ๊ฒƒ๋„ RBD์ธ mysql ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ง์ด๋‹ค. mysql์ด json ์ปฌ๋Ÿผ์„ ์ง€์›ํ•˜๊ธฐ๋Š” ํ•˜์ง€๋งŒ json ํ•จ์ˆ˜๋ฅผ ์ฟผ๋ฆฌ์— ์“ธ ํ•„์š”๊นŒ์ง€๋Š” ์—†๋Š” ์ƒํ™ฉ์ด๋‹ค๋ณด๋‹ˆ ๊ทธ๋ƒฅ varcharํƒ€์ž…์œผ๋กœ ์ปฌ๋Ÿผ์„ ์ •์˜ํ–ˆ๊ณ  ์—ฌ๊ธฐ์— jsonํฌ๋งท์˜ ์ŠคํŠธ๋ง์„ ๊ทธ๋Œ€๋กœ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๊บผ๋‚ด์“ธ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ–ˆ๋‹ค.

์ผ๋‹จ ํƒ€์ž…ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋กœ ํ–ˆ๊ณ  ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด์ง€ ๊ฒ€์ƒ‰์„ ์ข€ ํ•ด๋ดค๋‹ค. ๊ตฌ๊ธ€์—์„œ "Type handler for ArrayList in myBatis" ๋ผ๊ณ  ๊ฒ€์ƒ‰์„ ํ•˜๋‹ˆ ๋งŽ์€ ํฌ์ŠคํŒ…์ด ๊ฒ€์ƒ‰์ด ๋˜์—ˆ๊ณ  ๋‚ด ํ”„๋กœ์ ํŠธ์— ๋งž๊ฒŒ ๊ฐ€์ ธ๋‹ค๊ฐ€ ์“ธ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ž‘์—… ๋‚ด์šฉ์„ ์ •๋ฆฌํ•˜์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. 

 

์šฐ์„  dto์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด MyJsonDataWrapperClass ๊ฐ€ myJsonData ๋ฆฌ์ŠคํŠธ๋ฅผ ๋“ค๊ณ  ์žˆ๋Š”๋ฐ ์ด๋•Œ MyJsonData ํด๋ž˜์Šค๊ฐ€ ๋ฐ”๋กœ json ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋  ์ •๋ณด์ด๋‹ค.

@Getter
@Setter
@JsonInclude(Include.NON_NULL)
public class MyJsonDataWrapperClass {

    private Integer someIntData;
    private List<MyJsonData> myJsonData = new ArrayList<>();
    
    @Override
    public String toString() {
        return new Gson().toJson(this);
    }
}
@Getter
@Setter
@EqualsAndHashCode
public class MyJsonData {
    private String name;
    private int age;

    @Override
    public String toString() {
        return new Gson().toJson(this);
    }
}

 

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” myJsonData ๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ textํƒ€์ž…์˜ ์ปฌ๋Ÿผ์„ ๋งŒ๋“ค์—ˆ๊ณ  mybatis์˜ insert๋ฌธ์— ์‚ฌ์šฉํ•  ํƒ€์ž…ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ช…์‹œํ•ด์ฃผ์—ˆ๋‹ค.

, myJsonData = #{myJsonData, typeHandler=MyJsonDataTypeHandler}

 

๊ทธ๋ฆฌ๊ณ  ํƒ€์ž…ํ•ธ๋“ค๋Ÿฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜ํ•˜์˜€๋‹ค.

@Slf4j
public class MyJsonDataTypeHandler extends BaseTypeHandler<List<MyJsonData>> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<MyJsonData> parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, new Gson().toJson(parameter));
    }

    @Override
    public List<MyJsonData> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return convertToList(rs.getString(columnName));
    }

    @Override
    public List<MyJsonData> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return convertToList(rs.getString(columnIndex));
    }

    @Override
    public List<MyJsonData> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return convertToList(cs.getString(columnIndex));
    }

    private List<MyJsonData> convertToList(String myJsonDataListAsString) {
        try {
            return new ObjectMapper().readValue(myJsonDataListAsString, new TypeReference<List<MyJsonData>>() {
            });
        } catch (IOException e) {
            log.error("MyJsonDataTypeHandler failed to convert text to list, myJsonDataListAsString:{}", myJsonDataListAsString, e);
        }
        return Collections.emptyList();
    }
}

 

BaseTypeHandler๋ฅผ ์ƒ์†ํ•˜๋ฉด์„œ List<MyJsonData> ํƒ€์ž…์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ์ž„์„ ๋ช…์‹œํ•ด์ฃผ์—ˆ๊ณ  setter์—๋Š” ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋ฅผ json ์ŠคํŠธ๋ง์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋„๋ก Gson.toJson() ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์˜€๊ณ , getter์—๋Š” ์กฐํšŒํ•œ json ์ŠคํŠธ๋ง์„ ๋‹ค์‹œ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋„๋ก ํ•˜์˜€๋Š”๋ฐ ์ด๋•Œ๋Š” ObjectMapper.readValue()๋ฅผ ์ด์šฉํ•˜์˜€๋‹ค.

 

์กฐํšŒ์‹œ์—๋Š” mybatis ๋งคํ•‘ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์ด resultMap์„ ์ •์˜ํ•˜์—ฌ MyJsonDataTypeHandler๋ฅผ ์ด์šฉํ•ด์„œ myJsonDataํ•„๋“œ์˜ ๊ฐ’์„ ArrayList๋กœ ๋ณ€ํ™˜ํ•˜๋„๋ก ํ•˜์˜€์œผ๋ฉฐ, ์ด๋ ‡๊ฒŒ ์ •์˜ํ•œ resultMap์„ select ๋ฌธ์˜ resultMap์œผ๋กœ ์„ ์–ธํ•ด์ฃผ์—ˆ๋‹ค.

<resultMap id="myJsonDataClassMap" type="MyJsonDataWrapperClass">
<result property="myJsonData" column="myJsonData" javaType="java.util.ArrayList"
jdbcType="VARCHAR" typeHandler="MyJsonDataTypeHandler" />
</resultMap>

....์ค‘๋žต....

<select id="findMyJsonDataType"
resultMap="myJsonDataClassMap">
SELECT * FROM findMyJsonDataWrapperClass
</select>

 

์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด ์†Œ์Šค๋ ˆ๋ฒจ์—์„œ๋Š” ํŠน์ • ๊ฐ์ฒด์˜ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ํ•ธ๋“ค๋ง์„ ํ•˜๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๋Š” json ์ŠคํŠธ๋ง์œผ๋กœ ์ €์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ปฌ๋Ÿผ๋‹จ์œ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ชผ๊ฐœ์„œ ์ €์žฅํ•˜๊ธฐ ์• ๋งคํ•œ ์ƒํ™ฉ์—์„œ json ์ŠคํŠธ๋ง์„ varchar(text) ํƒ€์ž…์œผ๋กœ ํ†ต์œผ๋กœ ์ €์žฅํ•˜๊ณ  ์†Œ์Šค๋ ˆ๋ฒจ์—์„œ๋Š” ๊ฐ์ฒดํƒ€์ž…์œผ๋กœ ํ•ธ๋“ค๋งํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ฑด ์ •๋ง ๋ฉ‹์ง„ ๊ธฐ๋Šฅ์ธ๊ฒƒ ๊ฐ™๋‹ค.

 

 

AWS Beanstalk

AWS ๋นˆ์Šคํ†ก์„ ์ด์šฉํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ๋„์šฐ๊ณ 

๋ถ„์‚ฐ์‹œ์Šคํ…œ ํ™˜๊ฒฝ์„ ๋งŒ๋“ค์–ด ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ

๊ฐ ๋นˆ์Šคํ†ก ์ธ์Šคํ„ด์Šค์˜ private IP๊ฐ€ ํ•„์š”ํ•  ๊ฒฝ์šฐ 

AWS SDK๋ฅผ ์ด์šฉํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

public List<String> getBeanstalkIps() {
	return findIpsByIds(findIds(getBeanstalkResources()));
}

private DescribeEnvironmentResourcesResult getBeanstalkResources() {
	DescribeEnvironmentResourcesRequest request =
		new DescribeEnvironmentResourcesRequest()
        		.withEnvironmentName("my-beanstalk-app");
	return beanstalk.describeEnvironmentResources(request);
}

private List<String> findIds(DescribeEnvironmentResourcesResult resources) {
	return resources.getEnvironmentResources().getInstances().stream()
			.map(Instance::getId)
			.collect(toList());
}

private List<String> findIpsByIds(List<String> ids) {
	DescribeInstancesRequest request = 
    	new DescribeInstancesRequest().withInstanceIds(ids);
	DescribeInstancesResult result = ec2.describeInstances(request);
	return result.getReservations().stream()
			.flatMap(n -> n.getInstances().stream())
			.map(com.amazonaws.services.ec2.model.Instance::getPrivateIpAddress)
			.sorted()
			.collect(toList());
}

 

์—ฌ๊ธฐ์„œ ํ•„์š”ํ•œ ๊ฒƒ์€ "my-beanstalk-app"์„ ๋Œ€์ฒดํ•  ๋นˆ์Šคํ†ก ํ™˜๊ฒฝ๋ช…์ธ๋ฐ

์ด ์ด๋ฆ„์€ AWS Console > Elastic Beanstalk > (์• ํ”Œ๋ฆฌ์ผ€์ด์…˜) > Environment ์—์„œ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 

AWS SDK๋Š” 2018๋…„ 11์›” 2.x ๋ฒ„์ „์ด ๋‚˜์™”์œผ๋‚˜ ์•„์ง 1.11 ๋ฒ„์ „์„ ์‚ฌ์šฉ ์ค‘์ด๋‹ค.

SDK 2.x๋กœ ๊ตฌํ˜„์‹œ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค.

-- TODO --

์›น์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“ค๋‹ค๋ณด๋ฉด HTMLํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๊ธฐ ๋งˆ๋ จ์ž…๋‹ˆ๋‹ค.

์›น์‚ฌ์ดํŠธ๊ฐ€ dynamicํ•œ ๋™์  ์‚ฌ์ดํŠธ๋ผ๋ฉด ๋”๋”์šฑ ๊ทธ๋Ÿด ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์ง‘๋‹ˆ๋‹ค.

์ด๋Ÿฐ ์ €๋Ÿฐ ๊ธฐ๋Šฅ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๊ตฌํ˜„์„ ํ•˜๋‹ค๋ณด๋ฉด ์ฃผ์ฒดํ•  ์ˆ˜ ์—†์ด ์ปค์ง€๋Š” html ํŒŒ์ผ์„ ๋ณผ ์ˆ˜๋„ ์žˆ๋Š”๋ฐ์š”

์ด๋Ÿด ๋•Œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ถ€๋ถ„์„ ๋ณ„๋„์˜ .js ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•œ ๋’ค html ํŒŒ์ผ์— ๋งํฌ๋ฅผ ๊ฑธ์–ด์„œ

๋งˆ์น˜ html ํŒŒ์ผ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐฉ๋ฒ•๋„ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ html ์˜ˆ์ œ๋ฅผ ๋จผ์ € ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" type="text/css" href="toggle.css" />
</head>

<body>
    <label class="switch">
        <input type="checkbox" onclick="toggle(this)">
        <span class="slider round"></span>
    </label>

    <script>
        function toggle(element) {
            console.log(element.checked);
        }
    </script>
</body>

</html>

์œ„ ์ฝ”๋“œ๋Š” ํ† ๊ธ€๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ ์‹œ๊ฐ„์— ์‚ฌ์šฉํ–ˆ๋˜ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

์œ„ ์ฝ”๋“œ์—์„œ <script> ํƒœ๊ทธ๋กœ ๊ฐ์‹ผ ๋ถ€๋ถ„์„ .js ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•ด๋‚ด๊ณ  ํ•ด๋‹น ํŒŒ์ผ์„ htmlํŒŒ์ผ์— ๋งํฌ(import, include๋ผ๊ณ  ์–˜๊ธฐํ•˜๊ธฐ๋„ ํ•จ)๋ฅผ ๊ฑธ์–ด์„œ ๊ธฐ๋Šฅ์ด ์ •์ƒ์ ์œผ๋กœ ๋Œ์•„๊ฐ€๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ์„  html ๋ฌธ์„œ์˜ <script> ํƒœ๊ทธ ๋‚ด์— ์žˆ๋˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•˜์—ฌ toggle.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

function toggle(element) {
    console.log(element.checked);
}

์ด์ œ <head>ํƒœ๊ทธ ๋‚ด์— ์•„๋ž˜์™€ ๊ฐ™์ด toggle.js ํŒŒ์ผ์„ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๊ณ , <body>์•ˆ์— ์žˆ๋˜ script๋Š” ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" type="text/css" href="toggle.css" />
    <script src="toggle.js"></script>
</head>

<body>
    <label class="switch">
        <input type="checkbox" onclick="toggle(this)">
        <span class="slider round"></span>
    </label>
</body>

</html>

<script> ํƒœ๊ทธ๊ฐ€ ์‚ฌ๋ผ์ง€๋‹ˆ ํ™”๋ฉด์— ๊ทธ๋ฆผ์„ ๊ทธ๋ ค์ฃผ๋Š” ์š”์†Œ๋“ค๋งŒ <body>์— ๋‚จ์•„์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์œ„ ์ฝ”๋“œ ์ž์ฒด๊ฐ€ ์›Œ๋‚™ ์ž‘์€ ์ฝ”๋“œ๋ผ ๊น”๋”ํ•ด์กŒ๋‹ค๋Š” ๋Š๋‚Œ์„ ๋ฐ›์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์œผ๋‚˜, 

์œ„ ์ฒ˜๋Ÿผ ์งง์€ html ๋ฌธ์„œ๋Š” ํ…Œ์ŠคํŠธ์šฉ๋ฐ–์— ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ณ ์‹ถ๋‹ค๋ฉด ํ•ญ์ƒ .js ํŒŒ์ผ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๋งํฌ๊ฑธ์–ด ์‚ฌ์šฉํ•˜๊ธธ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

 

๋ญ”๊ฐ€ ๊ธธ๊ฒŒ ์„ค๋ช…๋“œ๋ ธ์ง€๋งŒ, htmlํŒŒ์ผ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์—ฐ๊ฒฐ/๋งํฌ/import/include ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์€ <head>ํƒœ๊ทธ ๋‚ด์— ์•„๋ž˜์™€ ๊ฐ™์ด ํ•œ ์ค„๋งŒ ์ถ”๊ฐ€ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<script src="toggle.js"></script>

์—ฌ๊ธฐ์„œ .js ํŒŒ์ผ์˜ ์œ„์น˜๋Š” html ํŒŒ์ผ์˜ ์œ„์น˜์—์„œ ์ƒ๋Œ€๊ฒฝ๋กœ๋กœ ์ง€์ •ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋˜๋Š” ์›น์ƒ์— ์žˆ๋Š” ํŒŒ์ผ์ผ ๊ฒฝ์šฐ URL ์ฃผ์†Œ๊ฐ€ ๋“ค์–ด์˜ฌ ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

 

์ž๋ฐ” ์›น์•ฑ์„ ๊ฐœ๋ฐœํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ํˆด์ด ์ดํด๋ฆฝ์Šค์™€ ์Šคํ”„๋ง๋ถ€ํŠธ์ž…๋‹ˆ๋‹ค.

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” ์ดํด๋ฆฝ์Šค์—์„œ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์Šคํ”„๋ง์„ ์„ค์น˜ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ์„ , ์ดํด๋ฆฝ์Šค๊ฐ€ ์„ค์น˜๋˜์–ด์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์‹  ์ดํด๋ฆฝ์Šค๋Š” ์šฐ์ธก ๋งํฌ์—์„œ ๋ฐ›์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -> https://www.eclipse.org/downloads/

 

์ดํด๋ฆฝ์Šค ์ƒ๋‹จ ๋ฉ”๋‰ด์—์„œ Help > Eclipse Marketplace... ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฒ€์ƒ‰์ฐฝ์—์„œ "sts"๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

์œ„ ํ™”๋ฉด์ฒ˜๋Ÿผ ๋‚˜์˜ค๋ฉด "Spring Tools 4 - for Spring Boot (aka Spring Tool Suite 4)"๋ฅผ install ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

Spring Tools 4 ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•  ๋•Œ ์–ด๋–ค ๊ฒƒ๋“ค์„ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ชฉ๋ก์„ ์กฐํšŒํ•ด ์˜ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์„ธ ๋ชฉ๋ก์„ ์œ„ ์‚ฌ์ง„์ฒ˜๋Ÿผ ๋ณด์—ฌ์ฃผ๋Š”๋ฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋‘ ์ฒดํฌ๊ฐ€ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ƒฅ "confirm" ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”.

์†Œํ”„ํŠธ์›จ์–ด ๋ผ์ด์„ผ์Šค์— ๋™์˜ํ•˜๋Š”์ง€ ๋ฌป๋Š” ์งˆ๋ฌธ์—๋Š” "I accept the terms...."๋ฅผ ์„ ํƒํ•˜๊ณ  "Finish"๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

STS 4 ์„ค์น˜ ์ง„ํ–‰ ์ƒํƒœ

์šฐ์ธก ํ•˜๋‹จ์˜ "Progress" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด Progress ์ฐฝ์œผ๋กœ focus๊ฐ€ ๋งž์ถฐ์ง€๋ฉด์„œ ์„ค์น˜ ์ƒํƒœ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ธํ„ฐ๋„ท ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

jQuery provides a trivially simple interface for doing various kind of amazing effects. jQuery methods allow us to quickly apply commonly used effects with a minimum configuration.

This tutorial covers all the important jQuery methods to create visual effects.


์š”์†Œ ์ˆจ๊ธฐ๊ธฐ์™€ ๋ณด์ด๊ธฐ

The commands for showing and hiding elements are pretty much what we would expect: show() to show the elements in a wrapped set and hide() to hide them.

๋ฌธ๋ฒ•:

Here is the simple syntax for show() method:

[selector].show( speed, [callback] );

Here is the description of all the parameters:

  • speed: A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).

  • callback: This optional parameter represents a function to be executed whenever the animation completes; executes once for each element animated against.

Following is the simple syntax for hide() method:

[selector].hide( speed, [callback] );

Here is the description of all the parameters:

  • speed: A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).

  • callback: This optional parameter represents a function to be executed whenever the animation completes; executes once for each element animated against.

์˜ˆ์ œ:

Consider the following HTML file with a small JQuery coding:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {

     $("#show").click(function () {
        $(".mydiv").show( 1000 );
     });

     $("#hide").click(function () {
        $(".mydiv").hide( 1000 );
     });

   });

   </script>
   <style>
   .mydiv{ margin:10px;padding:12px;
      border:2px solid #666;
      width:100px;
      height:100px;
    }
  </style>
</head>
<body>
   <div class="mydiv">
      This is  SQUAR
   </div>

   <input id="hide" type="button" value="Hide" />   
   <input id="show" type="button" value="Show" />   

</body>
</html>

 

 

์š”์†Œ ํ† ๊ธ€๋ง

jQuery provides methods to toggle the display state of elements between revealed or hidden. If the element is initially displayed, it will be hidden; if hidden, it will be shown.

๋ฌธ๋ฒ•:

Here is the simple syntax for one of the toggle() methods:

[selector]..toggle([speed][, callback]);

Here is the description of all the parameters:

  • speed: A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).

  • callback: This optional parameter represents a function to be executed whenever the animation completes; executes once for each element animated against.

์˜ˆ์ œ:

We can animate any element, such as a simple <div> containing an image:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">

   $(document).ready(function() {
      $(".clickme").click(function(event){
          $(".target").toggle('slow', function(){
             $(".log").text('Transition Complete');
          });
      });

   });
   </script>
   <style>
   .clickme{ margin:10px;padding:12px;
      border:2px solid #666;
      width:100px;
      height:50px;
    }
   </style>
</head>
<body>
   <div class="content">
      <div class="clickme">Click Me</div>
      <div class="target">
         <img src="/images/jquery.jpg" alt="jQuery" />
      </div>
      <div class="log"></div>
</body>
</html>

 

 

JQuery ํšจ๊ณผ ๊ด€๋ จ ๋ฉ”์†Œ๋“œ ๋ชฉ๋ก

 

Methods and Description
animate( params, [duration, easing, callback] )
A function for making custom animations.
fadeIn( speed, [callback] )
Fade in all matched elements by adjusting their opacity and firing an optional callback after completion.
fadeOut( speed, [callback] )
Fade out all matched elements by adjusting their opacity to 0, then setting display to "none" and firing an optional callback after completion.
fadeTo( speed, opacity, callback )
Fade the opacity of all matched elements to a specified opacity and firing an optional callback after completion.
hide( )
Hides each of the set of matched elements if they are shown.
hide( speed, [callback] )
Hide all matched elements using a graceful animation and firing an optional callback after completion.
show( )
Displays each of the set of matched elements if they are hidden.
show( speed, [callback] )
Show all matched elements using a graceful animation and firing an optional callback after completion.
slideDown( speed, [callback] )
Reveal all matched elements by adjusting their height and firing an optional callback after completion.
slideToggle( speed, [callback] )
Toggle the visibility of all matched elements by adjusting their height and firing an optional callback after completion.
slideUp( speed, [callback] )
Hide all matched elements by adjusting their height and firing an optional callback after completion.
stop( [clearQueue, gotoEnd ])
Stops all the currently running animations on all the specified elements.
toggle( )
Toggle displaying each of the set of matched elements.
toggle( speed, [callback] )
Toggle displaying each of the set of matched elements using a graceful animation and firing an optional callback after completion.
toggle( switch )
Toggle displaying each of the set of matched elements based upon the switch (true shows all elements, false hides all elements).
jQuery.fx.off
Globally disable all animations.


UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํšจ๊ณผ ๋ชฉ๋ก

To use these effects you would have to download jQuery UI Library jquery-ui-1.7.2.custom.min.js or latest version of this UI library from jQuery UI Library.

After extracting jquery-ui-1.7.2.custom.min.js file from the download, you would include this file in similar way as you include core jQuery Library file.

Methods and Description
Blind
Blinds the element away or shows it by blinding it in.
Bounce
Bounces the element vertically or horizontally n-times.
Clip
Clips the element on or off, vertically or horizontally.
Drop
Drops the element away or shows it by dropping it in.
Explode
Explodes the element into multiple pieces.
Fold
Folds the element like a piece of paper.
Highlight
Highlights the background with a defined color.
Puff
Scale and fade out animations create the puff effect.
Pulsate
Pulsates the opacity of the element multiple times.
Scale
Shrink or grow an element by a percentage factor.
Shake
Shakes the element vertically or horizontally n-times.
Size
Resize an element to a specified width and height.
Slide
Slides the element out of the viewport.
Transfer
Transfers the outline of an element to another.

 

 

 

 

Reference : http://www.tutorialspoint.com/jquery/jquery-effects.htm 

 

 

 

 

AJAX is an acronym standing for Asynchronous JavaScript and XML and this technology help us to load data from the server without a browser page refresh.

If you are new with AJAX, I would recommend you go through our Ajax Tutorial before proceeding further.

JQuery is a great tool which provides a rich set of AJAX methods to develope next generation web application.


๋ฐ์ดํƒ€ ๋กœ๋”ฉํ•˜๊ธฐ

This is very easy to load any static or dynamic data using JQuery AJAX. JQuery provides load() method to do the job:

๋ฌธ๋ฒ•:

Here is the simple syntax for load() method:

[selector].load( URL, [data], [callback] );

Here is the description of all the parameters:

  • URL: The URL of the server-side resource to which the request is sent. It could be a CGI, ASP, JSP, or PHP script which generates data dynamically or out of a database.

  • data: This optional parameter represents an object whose properties are serialized into properly encoded parameters to be passed to the request. If specified, the request is made using the POST method. If omitted, the GET method is used.

  • callback: A callback function invoked after the response data has been loaded into the elements of the matched set. The first parameter passed to this function is the response text recieved from the server and second parameter is the status code.

์˜ˆ์ œ:

Consider the following HTML file with a small JQuery coding:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   $(document).ready(function() {
      $("#driver").click(function(event){
          $('#stage').load('/jquery/result.html');
      });
   });
   </script>
</head>
<body>
   <p>Click on the button to load result.html file:</p>
   <div id="stage" style="background-color:blue;">
          STAGE
   </div>
   <input type="button" id="driver" value="Load Data" />
</body>
</html>

Here load() initiates an Ajax request to the specified URL /jquery/result.html file. After loading this file, all the content would be populated inside <div> tagged with ID stage. Assuming, our /jquery/result.html file has just one HTML line:

   <h1>THIS IS RESULT...</h1>

When you click the given button, then result.html file gets loaded. 


JSON ๋ฐ์ดํƒ€ ์ฝ์–ด์˜ค๊ธฐ

There would be a situation when server would return JSON string against your request. JQuery utility function getJSON() parses the returned JSON string and makes the resulting string available to the callback function as first parameter to take further action.

๋ฌธ๋ฒ•:

Here is the simple syntax for getJSON() method:

[selector].getJSON( URL, [data], [callback] );

Here is the description of all the parameters:

  • URL: The URL of the server-side resource contacted via the GET method.

  • data: An object whose properties serve as the name/value pairs used to construct a query string to be appended to the URL, or a preformatted and encoded query string.

  • callback: A function invoked when the request completes. The data value resulting from digesting the response body as a JSON string is passed as the first parameter to this callback, and the status as the second.

์˜ˆ์ œ:

Consider the following HTML file with a small JQuery coding:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   $(document).ready(function() {
      $("#driver").click(function(event){
          $.getJSON('/jquery/result.json', function(jd) {
             $('#stage').html('<p> Name: ' + jd.name + '</p>');
             $('#stage').append('<p>Age : ' + jd.age+ '</p>');
             $('#stage').append('<p> Sex: ' + jd.sex+ '</p>');
          });
      });
   });
   </script>
</head>
<body>
   <p>Click on the button to load result.html file:</p>
   <div id="stage" style="background-color:blue;">
          STAGE
   </div>
   <input type="button" id="driver" value="Load Data" />
</body>
</html>

Here JQuery utility method getJSON() initiates an Ajax request to the specified URL /jquery/result.json file. After loading this file, all the content would be passed to the callback function which finally would be populated inside <div> tagged with ID stage. Assuming, our /jquery/result.json file has following json formatted content:

{
"name": "Zara Ali",
"age" : "67",
"sex": "female"
}

When you click the given button, then result.json file gets loaded.


์„œ๋ฒ„๋กœ ๋ฐ์ดํƒ€ ์ „๋‹ฌํ•˜๊ธฐ

Many times you collect input from the user and you pass that input to the server for further processing. JQuery AJAX made it easy enough to pass collected data to the server using data parameter of any available Ajax method.

์˜ˆ์ œ:

This example demonstrate how can pass user input to a web server script which would send the same result back and we would print it:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   $(document).ready(function() {
      $("#driver").click(function(event){
          var name = $("#name").val();
          $("#stage").load('/jquery/result.php', {"name":name} );
      });
   });
   </script>
</head>
<body>
   <p>Enter your name and click on the button:</p>
   <input type="input" id="name" size="40" /><br />
   <div id="stage" style="background-color:blue;">
          STAGE
   </div>
   <input type="button" id="driver" value="Show Result" />
</body>
</html>

Here is the code written in result.php script:

<?php
if( $_REQUEST["name"] )
{
   $name = $_REQUEST['name'];
   echo "Welcome ". $name;
}
?> 

Now you can enter any text in the given input box and then click "Show Result" button to see what you have entered in the input box. 


JQuery์—์„œ ์‚ฌ์šฉ๋˜๋Š” AJAX ๋ฉ”์†Œ๋“œ ๋ชฉ๋ก

 

Methods and Description
jQuery.ajax( options )
Load a remote page using an HTTP request.
jQuery.ajaxSetup( options )
Setup global settings for AJAX requests.
jQuery.get( url, [data], [callback], [type] )
Load a remote page using an HTTP GET request.
jQuery.getJSON( url, [data], [callback] )
Load JSON data using an HTTP GET request.
jQuery.getScript( url, [callback] )
Loads and executes a JavaScript file using an HTTP GET request.
jQuery.post( url, [data], [callback], [type] )
Load a remote page using an HTTP POST request.
load( url, [data], [callback] )
Load HTML from a remote file and inject it into the DOM.
serialize( )
Serializes a set of input elements into a string of data.
serializeArray( )
Serializes all forms and form elements like the .serialize() method but returns a JSON data structure for you to work with.


JQuery AJAX ์ด๋ฒคํŠธ ๋ชฉ๋ก


Methods and Description
ajaxComplete( callback )
Attach a function to be executed whenever an AJAX request completes.
ajaxStart( callback )
Attach a function to be executed whenever an AJAX request begins and there is none already active.
ajaxError( callback )
Attach a function to be executed whenever an AJAX request fails.
ajaxSend( callback )
Attach a function to be executed before an AJAX request is sent.
ajaxStop( callback )
Attach a function to be executed whenever all AJAX requests have ended.
ajaxSuccess( callback )
Attach a function to be executed whenever an AJAX request completes successfully.

 

 

 

 

Reference : http://www.tutorialspoint.com/jquery/jquery-ajax.htm

 

 

 

 

We have the ability to create dynamic web pages by using events. Events are actions that can be detected by your Web Application.

Following are the examples events:

  • A mouse click
  • A web page loading
  • Taking mouse over an element
  • Submitting an HTML form
  • A keystroke on your keyboard
  • etc.

When these events are triggered you can then use a custom function to do pretty much whatever you want with the event. These custom functions call Event Handlers.


์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ

Using the jQuery Event Model, we can establish event handlers on DOM elements with the bind() method as follows:

$('div').bind('click', function( event ){
   alert('Hi there!');
});

This code will cause the division element to respond to the click event; when a user clicks inside this division thereafter, the alert will be shown.

The full syntax of the bind() command is as follows:

selector.bind( eventType[, eventData], handler)

Following is the description of the parameters:

  • eventType: A string containing a JavaScript event type, such as click or submit. Refer to the next section for a complete list of event types.

  • eventData: This is optional parameter is a map of data that will be passed to the event handler.

  • handler: A function to execute each time the event is triggered.


์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์‚ญ์ œํ•˜๊ธฐ

Typically, once an event handler is established, it remains in effect for the remainder of the life of the page. There may be a need when you would like to remove event handler.

jQuery provides the unbind() command to remove an exiting event handler. The syntax of unbind() is as follows:

selector.unbind(eventType, handler)

or 

selector.unbind(eventType)

Following is the description of the parameters:

  • eventType: A string containing a JavaScript event type, such as click or submit. Refer to the next section for a complete list of event types.

  • handler: If provided, identifies the specific listener that has to be removed.


์ด๋ฒคํŠธ ํƒ€์ž…

The following are cross platform and recommended event types which you can bind using JQuery:

Event TypeDescription
blurOccurs when the element loses focus
changeOccurs when the element changes
clickOccurs when a mouse click
dblclickOccurs when a mouse double-click
errorOccurs when there is an error in loading or unloading etc.
focusOccurs when the element gets focus
keydownOccurs when key is pressed
keypressOccurs when key is pressed and released
keyupOccurs when key is released
loadOccurs when document is loaded
mousedownOccurs when mouse button is pressed
mouseenterOccurs when mouse enters in an element region
mouseleaveOccurs when mouse leaves an element region
mousemoveOccurs when mouse pointer moves
mouseoutOccurs when mouse pointer moves out of an element
mouseoverOccurs when mouse pointer moves over an element
mouseupOccurs when mouse button is released
resizeOccurs when window is resized
scrollOccurs when window is scrolled
selectOccurs when a text is selected
submitOccurs when form is submitted
unloadOccurs when documents is unloaded


์ด๋ฒคํŠธ ๊ฐ์ฒด

The callback function takes a single parameter; when the handler is called the JavaScript event object will be passed through it.

The event object is often unneccessary and the parameter is omitted, as sufficient context is usually available when the handler is bound to know exactly what needs to be done when the handler is triggered, however there are certail attributes which you would need to be accessed.

์ด๋ฒคํŠธ ์†์„ฑ

The following event properties/attributes are available and safe to access in a platform independent manner:

PropertyDescription
altKeySet to true if the Alt key was pressed when the event was triggered, false if not. The Alt key is labeled Option on most Mac keyboards.
ctrlKeySet to true if the Ctrl key was pressed when the event was triggered, false if not.
dataThe value, if any, passed as the second parameter to the bind() command when the handler was established.
keyCodeFor keyup and keydown events, this returns the key that was pressed.
metaKeySet to true if the Meta key was pressed when the event was triggered, false if not. The Meta key is the Ctrl key on PCs and the Command key on Macs.
pageXFor mouse events, specifies the horizontal coordinate of the event relative from the page origin.
pageYFor mouse events, specifies the vertical coordinate of the event relative from the page origin.
relatedTargetFor some mouse events, identifies the element that the cursor left or entered when the event was triggered.
screenXFor mouse events, specifies the horizontal coordinate of the event relative from the screen origin.
screenYFor mouse events, specifies the vertical coordinate of the event relative from the screen origin.
shiftKeySet to true if the Shift key was pressed when the event was triggered, false if not.
targetIdentifies the element for which the event was triggered.
timeStampThe timestamp (in milliseconds) when the event was created.
typeFor all events, specifies the type of event that was triggered (for example, click).
whichFor keyboard events, specifies the numeric code for the key that caused the event, and for mouse events, specifies which button was pressed (1 for left, 2 for middle, 3 for right)

 

 

์ด๋ฒคํŠธ ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ

There is a list of methods which can be called on an Event Object:

MethodDescription
preventDefault()Prevents the browser from executing the default action.
isDefaultPrevented()Returns whether event.preventDefault() was ever called on this event object.
stopPropagation() Stops the bubbling of an event to parent elements, preventing any parent handlers from being notified of the event.
isPropagationStopped() Returns whether event.stopPropagation() was ever called on this event object.
stopImmediatePropagation() Stops the rest of the handlers from being executed.
isImmediatePropagationStopped()Returns whether event.stopImmediatePropagation() was ever called on this event object.


์ด๋ฒคํŠธ ์กฐ์ž‘ ๊ด€๋ จ ๋ฉ”์†Œ๋“œ

Following table lists down important event-related methods:

MethodDescription
bind( type, [data], fn )Binds a handler to one or more events (like click) for each matched element. Can also bind custom events.
die( type, fn )This does the opposite of live, it removes a bound live event.
hover( over, out )Simulates hovering for example moving the mouse on, and off, an object.
live( type, fn )Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.
one( type, [data], fn )Binds a handler to one or more events to be executed once for each matched element.
ready( fn )Binds a function to be executed whenever the DOM is ready to be traversed and manipulated.
toggle( fn, fn2, fn3,... )Toggle among two or more function calls every other click.
trigger( event, [data] )Trigger an event on every matched element.
triggerHandler( event, [data] )Triggers all bound event handlers on an element .
unbind( [type], [fn] )This does the opposite of bind, it removes bound events from each of the matched elements.


์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์†Œ๋“œ

jQuery also provides a set of event helper functions which can be used either to trigger an event to bind any event types mentioned above.

ํŠธ๋ฆฌ๊ฑฐ ๋ฉ”์†Œ๋“œ

Following is an example which would triggers the blur event on all paragraphs:

$("p").blur();

๋ฐ”์ธ๋”ฉ ๋ฉ”์†Œ๋“œ

Following is an example which would bind a click event on all the <div>:

$("div").click( function () { 
   // do something here
});

 

 

Here is a complete list of all the support methods provided by jQuery:

MethodDescription
blur( )Triggers the blur event of each matched element.
blur( fn )Bind a function to the blur event of each matched element.
change( )Triggers the change event of each matched element.
change( fn )Binds a function to the change event of each matched element.
click( )Triggers the click event of each matched element.
click( fn )Binds a function to the click event of each matched element.
dblclick( )Triggers the dblclick event of each matched element.
dblclick( fn )Binds a function to the dblclick event of each matched element.
error( )Triggers the error event of each matched element.
error( fn )Binds a function to the error event of each matched element.
focus( )Triggers the focus event of each matched element.
focus( fn )Binds a function to the focus event of each matched element.
keydown( )Triggers the keydown event of each matched element.
keydown( fn )Bind a function to the keydown event of each matched element.
keypress( )Triggers the keypress event of each matched element.
keypress( fn )Binds a function to the keypress event of each matched element.
keyup( )Triggers the keyup event of each matched element.
keyup( fn )Bind a function to the keyup event of each matched element.
load( fn )Binds a function to the load event of each matched element.
mousedown( fn )Binds a function to the mousedown event of each matched element.
mouseenter( fn )Bind a function to the mouseenter event of each matched element.
mouseleave( fn )Bind a function to the mouseleave event of each matched element.
mousemove( fn )Bind a function to the mousemove event of each matched element.
mouseout( fn )Bind a function to the mouseout event of each matched element.
mouseover( fn )Bind a function to the mouseover event of each matched element.
mouseup( fn )Bind a function to the mouseup event of each matched element.
resize( fn )Bind a function to the resize event of each matched element.
scroll( fn )Bind a function to the scroll event of each matched element.
select( )Trigger the select event of each matched element.
select( fn )Bind a function to the select event of each matched element.
submit( )Trigger the submit event of each matched element.
submit( fn )Bind a function to the submit event of each matched element.
unload( fn )Binds a function to the unload event of each matched element.

 

 

 

 

 

 Reference : http://www.tutorialspoint.com/jquery/jquery-events.htm

 

 

 

 

 

JQuery provides methods to manipulate DOM in efficient way. You do not need to write big code to modify the value of any element's attribute or to extract HTML code from a paragraph or division.

JQuery provides methods such as .attr(), .html(), and .val() which act as getters, retrieving information from DOM elements for later use.

์ปจํ…์ธ  ์กฐ์ž‘:

The html( ) method gets the html contents (innerHTML) of the first matched element.

Here is the syntax for the method:

selector.html( )

์˜ˆ์ œ:

Following is an example which makes use of .html() and .text(val) methods. Here .html() retrieves HTML content from the object and then .text( val ) method sets value of the object using passed parameter:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {

     $("div").click(function () {
      var content = $(this).html();
      $("#result").text( content );
    });

   });

   </script>
   <style>
      #division{ margin:10px;padding:12px;
                 border:2px solid #666;
                 width:60px;
               }
  </style>
</head>
<body>
   <p>Click on the square below:</p>
   <span id="result"> </span>
   <div id="division" style="background-color:blue;">
     This is Blue Square!!
   </div>
</body>
</html>

 

 

DOM ์š”์†Œ ๋ณ€๊ฒฝ

You can replace a complete DOM element with the specified HTML or DOM elements. The replaceWith( content ) method serves this purpose very well.

Here is the syntax for the method:

selector.replaceWith( content )

Here content is what you want to have instead of original element. This could be HTML or simple text.

์˜ˆ์ œ:

Following is an example which would replace division element with "<h1>JQuery is Great</h1>":

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {

     $("div").click(function () {
       $(this).replaceWith("<h1>JQuery is Great</h1>");
    });

   });

   </script>
   <style>
      #division{ margin:10px;padding:12px;
                 border:2px solid #666;
                 width:60px;
               }
  </style>
</head>
<body>
   <p>Click on the square below:</p>
   <span id="result"> </span>
   <div id="division" style="background-color:blue;">
     This is Blue Square!!
   </div>
</body>
</html>

 

 

DOM ์š”์†Œ ์‚ญ์ œ

There may be a situation when you would like to remove one or more DOM elements from the document. JQuery provides two methods to handle the situation.

The empty( ) method remove all child nodes from the set of matched elements where as the method remove( expr ) method removes all matched elements from the DOM.

Here is the syntax for the method:

selector.remove( [ expr ])

or 

selector.empty( )

You can pass optional paramter expr to filter the set of elements to be removed.

์˜ˆ์ œ:

Following is an example where elements are being removed as soon as they are clicked:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {

     $("div").click(function () {
       $(this).remove( );
    });

   });

   </script>
   <style>
      .div{ margin:10px;padding:12px;
             border:2px solid #666;
             width:60px;
           }
  </style>
</head>
<body>
   <p>Click on any square below:</p>
   <span id="result"> </span>
   <div class="div" style="background-color:blue;"></div>
   <div class="div" style="background-color:green;"></div>
   <div class="div" style="background-color:red;"></div>
</body>
</html>

 

 

DOM ์š”์†Œ ์ถ”๊ฐ€

There may be a situation when you would like to insert new one or more DOM elements in your existing document. JQuery provides various methods to insert elements at various locations.

The after( content ) method insert content after each of the matched elements where as the method before( content ) method inserts content before each of the matched elements.

Here is the syntax for the method:

selector.after( content )

or

selector.before( content )

Here content is what you want to insert. This could be HTML or simple text.

์˜ˆ์ œ:

Following is an example where <div> elements are being inserted just before the clicked element:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {

     $("div").click(function () {
       $(this).before('<div class="div"></div>' );
    });

   });

   </script>
   <style>
      .div{ margin:10px;padding:12px;
             border:2px solid #666;
             width:60px;
           }
  </style>
</head>
<body>
   <p>Click on any square below:</p>
   <span id="result"> </span>
   <div class="div" style="background-color:blue;"></div>
   <div class="div" style="background-color:green;"></div>
   <div class="div" style="background-color:red;"></div>
</body>
</html>

 

 

DOM ์กฐ์ž‘ ๊ด€๋ จ ๋ฉ”์†Œ๋“œ ๋ชฉ๋ก

 

MethodDescription
after( content )Insert content after each of the matched elements.
append( content )Append content to the inside of every matched element.
appendTo( selector )Append all of the matched elements to another, specified, set of elements.
before( content )Insert content before each of the matched elements.
clone( bool )Clone matched DOM Elements, and all their event handlers, and select the clones.
clone( )Clone matched DOM Elements and select the clones.
empty( )Remove all child nodes from the set of matched elements.
html( val )Set the html contents of every matched element.
html( )Get the html contents (innerHTML) of the first matched element.
insertAfter( selector )Insert all of the matched elements after another, specified, set of elements.
insertBefore( selector )Insert all of the matched elements before another, specified, set of elements.
prepend( content )Prepend content to the inside of every matched element.
prependTo( selector )Prepend all of the matched elements to another, specified, set of elements.
remove( expr )Removes all matched elements from the DOM.
replaceAll( selector )Replaces the elements matched by the specified selector with the matched elements.
replaceWith( content )Replaces all matched elements with the specified HTML or DOM elements.
text( val )Set the text contents of all matched elements.
text( )Get the combined text contents of all matched elements.
wrap( elem )Wrap each matched element with the specified element.
wrap( html )Wrap each matched element with the specified HTML content.
wrapAll( elem )Wrap all the elements in the matched set into a single wrapper element.
wrapAll( html )Wrap all the elements in the matched set into a single wrapper element.
wrapInner( elem )Wrap the inner child contents of each matched element (including text nodes) with a DOM element.
wrapInner( html )Wrap the inner child contents of each matched element (including text nodes) with an HTML structure.

 

 

 

 

Reference : http://www.tutorialspoint.com/jquery/jquery-dom.htm

 

 

 

 

 

The jQuery library supports nearly all of the selectors included in Cascading Style Sheet (CSS) specifications 1 through 3, as outlined on the World Wide Web Consortium's site.

Using JQuery library developers can enhance their websites without worrying about browsers and their versions as long as the browsers have JavaScript enabled.

Most of the JQuery CSS Methods do not modify the content of the jQuery object and they are used to apply CSS properties on DOM elements.


CSS ์†์„ฑ ์ ์šฉํ•˜๊ธฐ

This is very simple to apply any CSS property using JQuery method css( PropertyName, PropertyValue ).

Here is the syntax for the method:

selector.css( PropertyName, PropertyValue );

Here you can pass PropertyName as a javascript string and based on its value, PropertyValue could be string or integer.

์˜ˆ์ œ:

Following is an example which adds font color to the second list item.

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {
      $("li").eq(2).css("color", "red");
   });

   </script>
</head>
<body>
   <div>
   <ul>
     <li>list item 1</li>
     <li>list item 2</li>
     <li>list item 3</li>
     <li>list item 4</li>
     <li>list item 5</li>
     <li>list item 6</li>
   </ul>
   </div>
</body>
</html>

 

 

CSS ์†์„ฑ ๋‹ค์ค‘ ์ ์šฉํ•˜๊ธฐ

You can apply multiple CSS properties using a single JQuery method CSS( {key1:val1, key2:val2....). You can apply as many properties as you like in a single call.

Here is the syntax for the method:

selector.css( {key1:val1, key2:val2....keyN:valN})

Here you can pass key as property and val as its value as described above.

์˜ˆ์ œ:

Following is an example which adds font color as well as background color to the second list item.

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {
      $("li").eq(2).css({"color":"red", 
                         "background-color":"green"});
   });

   </script>
</head>
<body>
   <div>
   <ul>
     <li>list item 1</li>
     <li>list item 2</li>
     <li>list item 3</li>
     <li>list item 4</li>
     <li>list item 5</li>
     <li>list item 6</li>
   </ul>
   </div>
</body>
</html>

 

 

์š”์†Œ์˜ Width & Height ์„ธํŒ…ํ•˜๊ธฐ

The width( val ) and height( val ) method can be used to set the width and hieght respectively of any element.

์˜ˆ์ œ:

Following is a simple example which sets the width of first division element where as rest of the elements have width set by style sheet:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {
      $("div:first").width(100);
      $("div:first").css("background-color", "blue");
   });

   </script>
   <style>
   div{ width:70px; height:50px; float:left; margin:5px;
      background:red; cursor:pointer; }
  </style>
</head>
<body>
  <div></div>
  <div>d</div>
  <div>d</div>
  <div>d</div>
  <div>d</div>
</body>
</html>

 

 

JQuery CSS ๋ฉ”์†Œ๋“œ

๋‹ค์Œ์€ CSS ์†์„ฑ๊ณผ ๊ด€๋ จ์žˆ๋Š” ๋ชจ๋“  ๋ฉ”์†Œ๋“œ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. 

MethodDescription
css( name )Return a style property on the first matched element.
css( name, value )Set a single style property to a value on all matched elements.
css( properties )Set a key/value object as style properties to all matched elements.
height( val )Set the CSS height of every matched element.
height( )Get the current computed, pixel, height of the first matched element.
innerHeight( )Gets the inner height (excludes the border and includes the padding) for the first matched element.
innerWidth( )Gets the inner width (excludes the border and includes the padding) for the first matched element.
offset( )Get the current offset of the first matched element, in pixels, relative to the document
offsetParent( )Returns a jQuery collection with the positioned parent of the first matched element.
outerHeight( [margin] )Gets the outer height (includes the border and padding by default) for the first matched element.
outerWidth( [margin] )Get the outer width (includes the border and padding by default) for the first matched element.
position( )Gets the top and left position of an element relative to its offset parent.
scrollLeft( val )When a value is passed in, the scroll left offset is set to that value on all matched elements.
scrollLeft( )Gets the scroll left offset of the first matched element.
scrollTop( val )When a value is passed in, the scroll top offset is set to that value on all matched elements.
scrollTop( )Gets the scroll top offset of the first matched element.
width( val )Set the CSS width of every matched element.
width( )Get the current computed, pixel, width of the first matched element.

 

 

 

 

  

Reference : http://www.tutorialspoint.com/jquery/jquery-css.htm

 

 

 

 

jQuery is a very powerful tool which provides a variety of DOM traversal methods to help us select elements in a document randomly as well as in sequential method.

Most of the DOM Traversal Methods do not modify the jQuery object and they are used to filter out elements from a document based on given conditions.


์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•œ ๋” ์š”์†Œ ์ฐพ๊ธฐ

Consider a simple document with the following HTML content:

<html>
<head>
<title>the title</title>
</head>
<body>
   <div>
   <ul>
     <li>list item 1</li>
     <li>list item 2</li>
     <li>list item 3</li>
     <li>list item 4</li>
     <li>list item 5</li>
     <li>list item 6</li>
   </ul>
   </div>
</body>
</html>
  • Above every list has its own index, and can be located directly by using eq(index) method as below example.

  • Every child element starts its index from zero, thus, list item 2 would be accessed by using $("li").eq(1) and so on.

์˜ˆ์ œ:

Following is a simple example which adds the color to second list item.

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {
      $("li").eq(2).addClass("selected");
   });

   </script>
   <style>
      .selected { color:red; }
  </style>
</head>
<body>
   <div>
   <ul>
     <li>list item 1</li>
     <li>list item 2</li>
     <li>list item 3</li>
     <li>list item 4</li>
     <li>list item 5</li>
     <li>list item 6</li>
   </ul>
   </div>
</body>
</html>

 

 

์š”์†Œ ํ•„ํ„ฐ๋งํ•˜๊ธฐ

The filter( selector ) method can be used to filter out all elements from the set of matched elements that do not match the specified selector(s). The selector can be written using any selector syntax.

์˜ˆ์ œ:

Following is a simple example which applies color to the lists associated with middle class:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   
   $(document).ready(function() {
      $("li").filter(".middle").addClass("selected");
   });

   </script>
   <style>
      .selected { color:red; }
  </style>
</head>
<body>
   <div>
   <ul>
     <li class="top">list item 1</li>
     <li class="top">list item 2</li>
     <li class="middle">list item 3</li>
     <li class="middle">list item 4</li>
     <li class="bottom">list item 5</li>
     <li class="bottom">list item 6</li>
   </ul>
   </div>
</body>
</html>

 

 

๋‚ด๋ถ€ ์š”์†Œ ์ฐพ๊ธฐ

The find( selector ) method can be used to locate all the descendent elements of a particular type of elements. The selector can be written using any selector syntax.

์˜ˆ์ œ:

Following is an example which selects all the <span> elements available inside different <p> elements:

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">

   $(document).ready(function() {
      $("p").find("span").addClass("selected");
   });

   </script>
   <style>
      .selected { color:red; }
  </style>
</head>
<body>
   <p>This is 1st paragraph and <span>THIS IS RED</span></p>
   <p>This is 2nd paragraph and <span>THIS IS ALSO RED</span></p>
</body>
</html>

 

 

์œ ์šฉํ•œ JQuery DOM Traversing ๋ฉ”์†Œ๋“œ

 Following table lists down useful methods which you can use to filter out various elements from a list of DOM elements:

SelectorDescription
eq( index )Reduce the set of matched elements to a single element.
filter( selector )Removes all elements from the set of matched elements that do not match the specified selector(s).
filter( fn )Removes all elements from the set of matched elements that do not match the specified function.
is( selector )Checks the current selection against an expression and returns true, if at least one element of the selection fits the given selector.
map( callback )Translate a set of elements in the jQuery object into another set of values in a jQuery array (which may, or may not contain elements).
not( selector )Removes elements matching the specified selector from the set of matched elements.
slice( start, [end] )Selects a subset of the matched elements.

 

 

 

Following table lists down other useful methods which you can use to locate various elements in a DOM:

SelectorDescription
add( selector )Adds more elements, matched by the given selector, to the set of matched elements.
andSelf( )Add the previous selection to the current selection.
children( [selector])Get a set of elements containing all of the unique immediate children of each of the matched set of elements.
closest( selector )Get a set of elements containing the closest parent element that matches the specified selector, the starting element included.
contents( )Find all the child nodes inside the matched elements (including text nodes), or the content document, if the element is an iframe.
end( )Revert the most recent 'destructive' operation, changing the set of matched elements to its previous state .
find( selector )Searches for descendent elements that match the specified selectors.
next( [selector] )Get a set of elements containing the unique next siblings of each of the given set of elements.
nextAll( [selector] )Find all sibling elements after the current element.
offsetParent( )Returns a jQuery collection with the positioned parent of the first matched element.
parent( [selector] )Get the direct parent of an element. If called on a set of elements, parent returns a set of their unique direct parent elements.
parents( [selector] )Get a set of elements containing the unique ancestors of the matched set of elements (except for the root element).
prev( [selector] )Get a set of elements containing the unique previous siblings of each of the matched set of elements.
prevAll( [selector] )Find all sibling elements in front of the current element.
siblings( [selector] )Get a set of elements containing all of the unique siblings of each of the matched set of elements.

 

 

 

 

 

Reference : http://www.tutorialspoint.com/jquery/jquery-traversing.htm

 

 

 

 

 

Some of the most basic components we can manipulate when it comes to DOM elements are the properties and attributes assigned to those elements.

Most of these attributes are available through JavaScript as DOM node properties. Some of the more common properties are:

  • className

  • tagName

  • id

  • href

  • title

  • rel

  • src

Consider the following HTML markup for an image element:

<img id="myImage" src="image.gif" alt="An image" 
class="someClass" title="This is an image"/>

In this element's markup, the tag name is img, and the markup for id, src, alt, class, and title represents the element's attributes, each of which consists of a name and a value.

jQuery gives us the means to easily manipulate an element's attributes and gives us access to the element so that we can also change its properties.


์†์„ฑ๊ฐ’ ์ฝ์–ด์˜ค๊ธฐ

์†์„ฑ๊ฐ’์€ attr(name) ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ:

์•„๋ž˜ ์˜ˆ์ œ๋Š” em์š”์†Œ์˜ title์†์„ฑ์— ์ง€์ •๋œ ๊ฐ’์„ ์ฝ์–ด์™€์„œ div์š”์†Œ์— ์ถœ๋ ฅํ•˜๋Š” ์˜ˆ์ œ๋„ค์š”.

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">

   $(document).ready(function() {
      var title = $("em").attr("title");
      $("#divid").text(title);
   });

   </script>
</head>
<body>
   <div>
      <em title="Bold and Brave">This is first paragraph.</em>
      <p id="myid">This is second paragraph.</p>
      <div id="divid"></div>
   </div>
</body>
</html>

 

 

์†์„ฑ๊ฐ’ ์ˆ˜์ •ํ•˜๊ธฐ

 attr(name, value) ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠน์ • ์†์„ฑ๋ช…์— ๋Œ€ํ•œ ์†์„ฑ๊ฐ’์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ:

์•„๋ž˜ ์˜ˆ์ œ๋Š” src ์†์„ฑ์— ํŠน์ • ํŒŒ์ผ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ด์ฃผ๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">

   $(document).ready(function() {
      $("#myimg").attr("src", "/images/jquery.jpg");
   });

   </script>
</head>
<body>
   <div>
      <img id="myimg" src="/wongpath.jpg" alt="Sample image" />
   </div>
</body>
</html>

 

 

์Šคํƒ€์ผ ์ ์šฉํ•˜๊ธฐ

 addClass( classes ) ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •์˜ํ•œ ์Šคํƒ€์ผ์„ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.  ์—ฌ๋Ÿฌ๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ์ŠคํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„์ž๋กœ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ:

์•„๋ž˜ ์˜ˆ์ œ๋Š” ๋ฌธ์„œ๋‚ด์˜ ๋ชจ๋“  em์š”์†Œ์— selected์Šคํƒ€์ผ์„ ์ ์šฉ์‹œํ‚ค๊ณ , id๊ฐ€ myid์ธ ์š”์†Œ์—๋Š” highlight์Šคํƒ€์ผ์„ ์ ์šฉ์‹œํ‚ค๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.
<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" language="javascript">

   $(document).ready(function() {
      $("em").addClass("selected");
      $("#myid").addClass("highlight");
   });

   </script>
   <style>
      .selected { color:red; }
      .highlight { background:yellow; }
  </style>
</head>
<body>
   <em title="Bold and Brave">This is first paragraph.</em>
   <p id="myid">This is second paragraph.</p>
</body>
</html>

 

 

์œ ์šฉํ•œ ์†์„ฑ ๊ด€๋ จ ๋ฉ”์†Œ๋“œ ๋ชฉ๋ก

 

MethodsDescription
attr( properties )Set a key/value object as properties to all matched elements.
attr( key, fn )Set a single property to a computed value, on all matched elements.
removeAttr( name )Remove an attribute from each of the matched elements.
hasClass( class )Returns true if the specified class is present on at least one of the set of matched elements.
removeClass( class )Removes all or the specified class(es) from the set of matched elements.
toggleClass( class )Adds the specified class if it is not present, removes the specified class if it is present.
html( )Get the html contents (innerHTML) of the first matched element.
html( val )Set the html contents of every matched element.
text( )Get the combined text contents of all matched elements.
text( val )Set the text contents of all matched elements.
val( )Get the input value of the first matched element.
val( val )Set the value attribute of every matched element if it is called on <input> but if it is called on <select> with the passed <option> value then passed option would be selected, if it is called on check box or radio box then all the matching check box and radiobox would be checked.

Similar to above syntax and examples, following examples would give you understanding on using various attribute methods in different situation:

  • $("#myID").attr("custom") : This would return value of attribute custom for the first element matching with ID myID.

  • $("img").attr("alt", "Sample Image"): This sets the alt attribute of all the images to a new value "Sample Image".

  • $("input").attr({ value: "", title: "Please enter a value" }); : Sets the value of all <input> elements to the empty string, as well as sets the title to the string Please enter a value.

  • $("a[href^=http://]").attr("target","_blank"): Selects all links with an href attribute starting with http:// and set its target attribute to _blank

  • $("a").removeAttr("target") : This would remove target attribute of all the links.

  • $("form").submit(function() {$(":submit",this).attr("disabled", "disabled");}); : This would modify the disabled attribute to the value "disabled" while clicking Submit button.

  • $("p:last").hasClass("selected"): This return true if last <p> tag has associated classselected.

  • $("p").text(): Returns string that contains the combined text contents of all matched <p> elements.

  • $("p").text("<i>Hello World</i>"): This would set "<I>Hello World</I>" as text content of the matching <p> elements

  • $("p").html() : This returns the HTML content of the all matching paragraphs.

  • $("div").html("Hello World") : This would set the HTML content of all matching <div> to Hello World.

  • $("input:checkbox:checked").val() : Get the first value from a checked checkbox

  • $("input:radio[name=bar]:checked").val(): Get the first value from a set of radio buttons

  • $("button").val("Hello") : Sets the value attribute of every matched element <button>.

  • $("input").val("on") : This would check all the radio or check box button whose value is "on".

  • $("select").val("Orange") : This would select Orange option in a dropdown box with options Orange, Mango and Banana.

  • $("select").val("Orange", "Mango") : This would select Orange and Mango options in a dropdown box with options Orange, Mango and Banana.

 

 

 

 

Reference : http://www.tutorialspoint.com/jquery/jquery-attributes.htm 

 

 

 

 

 

 

 

 

The jQuery library harnesses the power of Cascading Style Sheets (CSS) selectors to let us quickly and easily access elements or groups of elements in the Document Object Model (DOM).

A jQuery Selector is a function which makes use of expressions to find out matching elements from a DOM based on the given criteria.

$() factory function (ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜):

All type of selectors available in jQuery, always start with the dollar sign and parentheses: $().

The factory function $() makes use of following three building blocks while selecting elements in a given document:

jQueryDescription
Tag Name:Represents a tag name available in the DOM. For example $('p') selects all paragraphs in the document.
Tag ID:Represents a tag available with the given ID in the DOM. For example $('#some-id') selects the single element in the document that has an ID of some-id.
Tag Class:Represents a tag available with the given class in the DOM. For example $('.some-class') selects all elements in the document that have a class of some-class.

All the above items can be used either on their own or in combination with other selectors. All the jQuery selectors are based on the same principle except some tweaking.

NOTE: The factory function $() is a synonym of jQuery() function. So in case you are using any other JavaScript library where $ sign is conflicting with some thing else then you can replace $ sign by jQuery name and you can use function jQuery() instead of $().

Example(์˜ˆ์ œ):

Following is a simple example which makes use of Tag Selector. This would select all the elements with a tag name p.

<html>
<head>
<title>the title</title>
   <script type="text/javascript" 
   src="/jquery/jquery-1.3.2.min.js"></script>
   
   <script type="text/javascript" language="javascript">
   $(document).ready(function() {
      var pars = $("p");
      for( i=0; i<pars.length; i++ ){
         alert("Found paragraph: " + pars[i].innerHTML);
      }
   });
   </script>
</head>
<body>
   <div>
      <p class="myclass">This is a paragraph.</p>
      <p id="myid">This is second paragraph.</p>
      <p>This is third paragraph.</p>
   </div>
</body>
</html>

 

 

Selectors ์‚ฌ์šฉ๋ฒ•

๊ธฐ๋ณธ์ ์œผ๋กœ ์…€๋ ‰ํ„ฐ๋Š” ์ด๋ฆ„, ์•„์ด๋””, ํด๋ž˜์Šค๋ช…์œผ๋กœ ์š”์†Œ๋ฅผ ๊ตฌ๋ถ„์„ ์ง€์–ด์„œ ํ•˜๋‚˜ ๋˜๋Š” ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

SelectorDescription
NameSelects all elements which match with the given element Name.
#IDSelects a single element which matches with the given ID
.ClassSelects all elements which match with the given Class.
Universal (*)Selects all elements available in a DOM.
Multiple Elements E, F, GSelects the combined results of all the specified selectors E, F or G.

์‹ค์ œ๋กœ ์œ„ ์…€๋ ‰ํ„ฐ๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์— ๋งŽ์ด ๋‚˜์™€์žˆ์Šต๋‹ˆ๋‹ค.

  • $('*'): This selector selects all elements in the document.

  • $("p > *"): This selector selects all elements that are children of a paragraph element.

  • $("#specialID"): This selector function gets the element with id="specialID".

  • $(".specialClass"): This selector gets all the elements that have the class of specialClass.

  • $("li:not(.myclass)"): Selects all elements matched by <li> that do not have class="myclass".

  • $("a#specialID.specialClass"): This selector matches links with an id of specialID and a class of specialClass.

  • $("p a.specialClass"): This selector matches links with a class of specialClass declared within <p> elements.

  • $("ul li:first"): This selector gets only the first <li> element of the <ul>.

  • $("#container p"): Selects all elements matched by <p> that are descendants of an element that has an id of container.

  • $("li > ul"): Selects all elements matched by <ul> that are children of an element matched by <li>

  • $("strong + em"): Selects all elements matched by <em> that immediately follow a sibling element matched by <strong>.

  • $("p ~ ul"): Selects all elements matched by <ul> that follow a sibling element matched by <p>.

  • $("code, em, strong"): Selects all elements matched by <code> or <em> or <strong>.

  • $("p strong, .myclass"): Selects all elements matched by <strong> that are descendants of an element matched by <p> as well as all elements that have a class of myclass.

  • $(":empty"): Selects all elements that have no children.

  • $("p:empty"): Selects all elements matched by <p> that have no children.

  • $("div[p]"): Selects all elements matched by <div> that contain an element matched by <p>.

  • $("p[.myclass]"): Selects all elements matched by <p> that contain an element with a class of myclass.

  • $("a[@rel]"): Selects all elements matched by <a> that have a rel attribute.

  • $("input[@name=myname]"): Selects all elements matched by <input> that have a name value exactly equal to myname.

  • $("input[@name^=myname]"): Selects all elements matched by <input> that have a name value beginning with myname.

  • $("a[@rel$=self]"): Selects all elements matched by <a> that have rel attribute value ending with self

  • $("a[@href*=domain.com]"): Selects all elements matched by <a> that have an href value containing domain.com.

  • $("li:even"): Selects all elements matched by <li> that have an even index value.

  • $("tr:odd"): Selects all elements matched by <tr> that have an odd index value.

  • $("li:first"): Selects the first <li> element.

  • $("li:last"): Selects the last <li> element.

  • $("li:visible"): Selects all elements matched by <li> that are visible.

  • $("li:hidden"): Selects all elements matched by <li> that are hidden.

  • $(":radio"): Selects all radio buttons in the form.

  • $(":checked"): Selects all checked boxex in the form.

  • $(":input"): Selects only form elements (input, select, textarea, button).

  • $(":text"): Selects only text elements (input[type=text]).

  • $("li:eq(2)"): Selects the third <li> element

  • $("li:eq(4)"): Selects the fifth <li> element

  • $("li:lt(2)"): Selects all elements matched by <li> element before the third one; in other words, the first two <li> elements.

  • $("p:lt(3)"): selects all elements matched by <p> elements before the fourth one; in other words the first three <p> elements.

  • $("li:gt(1)"): Selects all elements matched by <li> after the second one.

  • $("p:gt(2)"): Selects all elements matched by <p> after the third one.

  • $("div/p"): Selects all elements matched by <p> that are children of an element matched by <div>.

  • $("div//code"): Selects all elements matched by <code>that are descendants of an element matched by <div>.

  • $("//p//a"): Selects all elements matched by <a> that are descendants of an element matched by <p>

  • $("li:first-child"): Selects all elements matched by <li> that are the first child of their parent.

  • $("li:last-child"): Selects all elements matched by <li> that are the last child of their parent.

  • $(":parent"): Selects all elements that are the parent of another element, including text.

  • $("li:contains(second)"): Selects all elements matched by <li> that contain the text second.

์ง€๊ธˆ๊นŒ์ง€ ๋ณธ ์…€๋ ‰ํ„ฐ๋“ค์€ ์–ด๋– ํ•œ HTML/XML ์š”์†Œ์—๋„ ์ผ๋ฐ˜์ ์œผ๋กœ ์ ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด selector $("li:first") ๊ฐ€ <li> ํƒœ๊ทธ์— ์ ์šฉ์ด ๋œ๋‹ค๋ฉด $("p:first") ์—ญ์‹œ <p> ํƒœ๊ทธ์— ์ ์šฉ์ด ๋œ๋‹ค๋Š” ๋ง์ด์ฃ .

 

 

 

 

 

Reference : http://www.tutorialspoint.com/jquery/jquery-selectors.htm

 

 

 

 

AJAX ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์˜ˆ์ œ

์•„๋ž˜ ์˜ˆ์ œ๋Š” AJAX๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ฝ์–ด์˜จ ์ž๋ฃŒ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์˜ˆ์ œ

form ํƒœ๊ทธ๊ฐ€ ๋จนํžˆ์ง€ ์•Š๋Š” ๊ด€๊ณ„๋กœ ์˜ˆ์ œ๋Š” ์‹ค์Šตํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ W3Schools๋กœ ๊ฐ€์…”์„œ ํ•ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์‹ค์Šตํ•˜๊ธฐ ยป

์˜ˆ์ œ ์„ค๋ช… - showCustomer() ํ•จ์ˆ˜

์‚ฌ์šฉ์ž๊ฐ€ ๋“œ๋ž๋‹ค์šด ๋ฆฌ์ŠคํŠธ์—์„œ ๊ณ ๊ฐ์„ ์„ ํƒํ•˜๋ฉด, "showCustomer()" ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” "onchange" ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ˜ธ์ถœ๋˜๋„๋ก ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

showCustomer ํ•จ์ˆ˜ ์†Œ์Šค ์ฝ”๋“œ

function showCustomer(str) {
  var xhttp; 
  if (str == "") {
    document.getElementById("txtHint").innerHTML = "";
    return;
  }
  xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (xhttp.readyState == 4 && xhttp.status == 200) {
    document.getElementById("txtHint").innerHTML = xhttp.responseText;
    }
  };
  xhttp.open("GET""getcustomer.asp?q="+str, true);
  xhttp.send();
}

showCustomer() ํ•จ์ˆ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

  • customer๊ฐ€ ์„ ํƒ์ด ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์„ ๋ฐ›๊ณ ๋‚˜์„œ ์‹คํ–‰๋  ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„์— ์žˆ๋Š” ํŒŒ์ผ๋กœ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  • ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ํŒŒ๋ผ๋ฏธํ„ฐ "q" ์™€ ๋“œ๋ž๋‹ค์šด ๋ฆฌ์ŠคํŠธ์—์„œ ์ฝ์–ด์˜จ str์„ URL์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

 AJAX Server Page

์œ„ ์˜ˆ์ œ์—์„œ ์‚ฌ์šฉ๋œ ์„œ๋ฒ„ํŽ˜์ด์ง€๋Š” "getcustomer.asp"์ž…๋‹ˆ๋‹ค.


์„œ๋ฒ„ ํŽ˜์ด์ง€ ํŒŒ์ผ์€ PHP, JSP์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์„œ๋ฒ„ ์–ธ์–ด๋กœ๋„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


PHP๋กœ ๊ตฌํ˜„ํ•œ ๋™์ผํ•œ ๊ธฐ๋Šฅ์˜ ์†Œ์Šค ๋ณด๊ธฐ


 "getcustomer.asp" ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ฝ์–ด์˜จ ์ •๋ณด๋ฅผ HTML ํ…Œ์ด๋ธ”์— ๋„ฃ๋Š” ๊ธฐ๋Šฅ์„ ํ•ฉ๋‹ˆ๋‹ค.

<%
response.expires=-1
sql="SELECT * FROM CUSTOMERS WHERE CUSTOMERID="
sql=sql & "'" & request.querystring("q") & "'"

set conn=Server.CreateObject("ADODB.Connection")
conn.Provider="Microsoft.Jet.OLEDB.4.0"
conn.Open(Server.Mappath("/datafolder/northwind.mdb"))
set rs=Server.CreateObject("ADODB.recordset")
rs.Open sql,conn

response.write("<table>")
do until rs.EOF
  for each x in rs.Fields
    response.write("<tr><td><b>" & x.name & "</b></td>")
    response.write("<td>" & x.value & "</td></tr>")
  next
  rs.MoveNext
loop
response.write("</table>")
%>


์ž, ํฐ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ง€๋‚˜์š”?

์ •๋ฆฌ๋ฅผ ํ•œ๋ฒˆ ํ•ด๋“œ๋ฆฌ์ž๋ฉด,

1. ๋“œ๋ž๋‹ค์šด ๋ฆฌ์ŠคํŠธ์—์„œ ํ•ญ๋ชฉ์„ ์„ ํƒํ•œ๋‹ค.
2. ํ•ญ๋ชฉ์ด ์„ ํƒ๋˜๋ฉด onchange ์ด๋ฒคํŠธ์—์˜ํ•ด showCustomer() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ajax ์š”์ฒญ์ด ์„œ๋ฒ„๋กœ ์ „์†ก๋˜๊ณ 
3. ์„œ๋ฒ„์—์„œ getcustomer.aspํŒŒ์ผ์ด ์‹คํ–‰์ด ๋˜๋Š”๋ฐ ์ด ํŒŒ์ผ์€ DB๋ฅผ ์กฐํšŒํ•ด์„œ ์ฝ์–ด์˜จ ์ •๋ณด๋ฅผ htmlํ˜•ํƒœ์˜ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด์„œ ์‘๋‹ต์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
4. ๊ทธ๋Ÿฌ๋ฉด ์ด ์‘๋‹ต์œผ๋กœ ๋ฐ›์€ htmlํ˜•์‹์˜ ์ •๋ณด๋ฅผ ๋“œ๋ž๋‹ค์šด ๋ฆฌ์ŠคํŠธ ์•„๋ž˜์ชฝ์— ๋ฟŒ๋ ค์ค๋‹ˆ๋‹ค.

์ด๋Ÿฐ์‹์œผ๋กœ ajax๋ฅผ ์ด์šฉํ•œ ์š”์ฒญ์ด ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋Š” ๊ฒ๋‹ˆ๋‹ค.

๋ณ„๋กœ ์–ด๋ ต์ง€ ์•Š์ฃ ? ^-^ 

์—ฌ๊ธฐ์„œ AJAX ํฌ์ŠคํŒ…์€ ๋งˆ์น˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ AJAXํฌ์ŠคํŒ…์— ์‚ฌ์šฉ๋œ ์ž๋ฃŒ๋Š” W3Schools์— ์žˆ๋Š” ์ž๋ฃŒ๋ฅผ ๋ฒˆ์—ญํ•ด๋†“์€ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค.

๊ถ๊ธˆํ•œ๊ฒŒ ์žˆ์œผ์‹œ๋ฉด ๋Œ“๊ธ€ ๋‹ฌ์•„์ฃผ์‹œ๋ฉด ๋‹ต๊ธ€ ๋‹ฌ์•„๋“œ๋ฆฌ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.





onreadystatechange ์ด๋ฒคํŠธ

XMLHttpRequest๊ฐ์ฒด๋Š” ์ƒํƒœ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ readyState ์†์„ฑ์ด ๊ทธ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ์ด ์ƒํƒœ ์ •๋ณด๋ฅผ ๋ณด๊ณ  ์‘๋‹ต์ด ์™”๋Š”์ง€, ๊ทธ ์‘๋‹ต์ด ์ •์ƒ์ ์œผ๋กœ ์™”๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


์ด readyState ๊ฐ€ ๋ณ€ํ•  ๋•Œ๋งˆ๋‹ค ํ•ญ์ƒ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์žˆ๋Š”๋ฐ ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ  onreadystatechange ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค.


XMLHttpRequest ๊ฐ์ฒด์˜ ์ค‘์š”ํ•œ ์„ธ ๊ฐ€์ง€ ์†์„ฑ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์†์„ฑ์„ค๋ช…
onreadystatechange readyState ์†์„ฑ๊ฐ’์ด ๋ณ€ํ•  ๋•Œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋  ํ•จ์ˆ˜ ๋˜๋Š” ํ•จ์ˆ˜๋ช…์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
readyStateXMLHttpRequest ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , 0 ์—์„œ 4 ์˜ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. 
0: ์š”์ฒญ์ด ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. 
1: ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
2: ์š”์ฒญ์ด ๋ฐ›์•„๋“ค์—ฌ์กŒ์Šต๋‹ˆ๋‹ค.
3: ์š”์ฒญ์ด ์ง„ํ–‰์ค‘์ž…๋‹ˆ๋‹ค.
4: ์š”์ฒญ์ด ์™„๋ฃŒ๋˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
status200: ์ •์ƒ
404: ํŽ˜์ด์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.


 onreadystatechange ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  readyState๊ฐ€ 4์ด๋ฉฐ status๊ฐ€ 200์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์š”์ฒญ์ด ์ฒ˜๋ฆฌ๋˜์–ด ์‘๋‹ต์ด ์˜จ ๊ฒฝ์šฐ์ด๋ฏ€๋กœ ์ด๋•Œ ์›ํ•˜๋Š” ์ž‘์—…์„ ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ

function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
  if (xhttp.readyState == 4 && xhttp.status == 200) {
    document.getElementById("demo").innerHTML = xhttp.responseText;
  }
};
์‹ค์Šตํ•˜๊ธฐ ยป

Note: onreadystatechange ์ด๋ฒคํŠธ๋Š” ํ•œ๋ฒˆ์˜ ์š”์ฒญ์„ ํ•  ๋•Œ ์ด 5๋ฒˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค (readyState๊ฐ€ 0์—์„œ 4๊นŒ์ง€ ๋ฐ”๋€Œ๋ฏ€๋กœ).


Callback ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ

callback ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ์ง€๋Š” ํ•จ์ˆ˜๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์›น์‚ฌ์ดํŠธ์— ํ•˜๋‚˜ ์ด์ƒ์˜ AJAX ์ž‘์—…์ด ์žˆ๋‹ค๋ฉด, ๋‹จ ํ•˜๋‚˜์˜ ํ‘œ์ค€ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ๊ฐ์˜ AJAX ์ž‘์—…์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ์ด ํ‘œ์ค€ํ•จ์ˆ˜์—์„œ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ‘œ์ค€ํ•จ์ˆ˜๋Š” ๊ฐ๊ฐ์˜ AJAX์ž‘์—…์„ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ๋ฐ›์•„์„œ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ

function loadDoc(cFunc) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
  if (xhttp.readyState == 4 && xhttp.status == 200) {
    cFunc(xhttp);
  }
์‹ค์Šตํ•˜๊ธฐ ยป