📌 Ajax란?

  • Asynchronous JavaScript and XML의 약자
  • 비동기식으로 서버와 데이터를 주고받을 수 있는 기술
  • 페이지 이동 없이 데이터 전송 및 화면 갱신 가능

 

📌 데이터를 서버로 보내는 방법

  1. Form 태그 사용
    • action 속성에 지정된 URL로 데이터를 전송
  2. a 태그의 href 사용
    • 쿼리 스트링을 이용한 데이터 전달: ?id=test123
  3. Ajax 사용
    • 페이지를 새로고침하지 않고 데이터 전송 가능
    • 회원가입 시 ID 중복 체크와 같은 기능 구현에 사용

 

 

📌  Ajax와 서버의 데이터 흐름

  1. Ajax → JSP: 입력한 id 값을 전달
  2. JSP → DB: id 값을 기반으로 DB 조회
  3. DB → JSP: 조회 결과 (count = 1 또는 count = 0) 반환
  4. JSP → Ajax: 결과를 String 타입으로 전달
 

 

📌  주의사항

  1. DB와 직접 연결할 수 없음
    • Ajax는 서버와의 중간 매개체 역할
    • JSP, PHP, API 등을 통해 DB와 통신
  2. Boolean 타입 사용 X
    • 서버에서 결과를 Ajax로 리턴할 때는 String 타입으로 넘겨야 함

 

📌 간단한 Ajax 사용 예시 (JQuery)

$.ajax({
    type: "POST",
    url: "checkId.jsp",
    data: { id: $("#userId").val() },
    success: function(data) {
        if(data === "1") {
            alert("이미 사용 중인 아이디입니다.");
        } else {
            alert("사용 가능한 아이디입니다.");
        }
    },
    error: function() {
        alert("오류가 발생했습니다.");
    }
});
  • url: 서버의 JSP 파일 위치
  • data: 서버에 전송할 데이터 (id)
  • success: 서버에서 받은 응답 처리
  • error: 통신 실패 시 처리

 

 

'프론트엔드 > JQuery' 카테고리의 다른 글

[JQuery] Ajax 답변삭제 팝업  (0) 2021.06.16
[JQuery] on 함수  (0) 2021.06.15
[JQuery] 부트스트랩 - Carousel(캐러셀) 만들기  (0) 2021.06.05
[JQuery] 클릭 이벤트  (0) 2021.05.25
[JQuery] 선택자  (0) 2021.05.25

세미 프로젝트의 인덱스 페이지를 담당하게 되면서 좌우로 슬라이드 되는 캐러셀을 만들어야 했는데,

제이쿼리에 익숙하지 않아서 혼자 골머리를 앓으며 캐러셀을 만들었다. (캐러셀에 사용된 이미지는 출처: FreePik )!

 

 

  제이쿼리로 만든 캐러셀

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
	$(document).ready(function() {
		
		var carouselIndex = 0;
		var carouselLength = $(".carousel_wrap li").length;
		
		setInterval(function() {
			if(carouselIndex < carouselLength-1) {
				$(".carousel_wrap").animate({left:"-=100%"}, 500);
				carouselIndex += 1;
			} else {
				$(".carousel_wrap").animate({left:"0"}, 500);
				carouselIndex = 0;
			}
		}, 4000);
 		
		$(".prev").click(function() {
				if(carouselIndex > 0) {
					$(".carousel_wrap").animate({left:"+=100%"}, 500);
					carouselIndex -= 1;
				} else {
					$(".carousel_wrap").animate({left:"-200%"}, 500);
					carouselIndex = carouselLength-1;
				}
		});
 
		$(".next").click(function() {
			if(carouselIndex < carouselLength-1) {
				$(".carousel_wrap").animate({left:"-=100%"}, 500);
				carouselIndex += 1;
			} else {
				$(".carousel_wrap").animate({left:"0"}, 500);
				carouselIndex = 0;
			}
		});
	});
</script>

<style>
.carousel_slide {
	position: relative;
	width: 100%;
	overflow: hidden;
}
.carousel_wrap {
	margin: 0;
	padding: 0;
	line-style-type: none;
	height: 697px;
	width: 300%;
	overflow: hidden;
	position: relative;
} 
.carousel_wrap li {
	width: 33.333%;
	display: inline-block;
	position: relative;
	float: left;
}
.carousel_wrap li a {
	height: 697px;
	display: flex;
	justify-content: center;
	position: relative;
}
.carousel_1 a {
	background-color: #acb5ad;
}
.carousel_2 a {
	background-color: #f5f7ee;
}
.carousel_3 a {
	background-color: #6e7e23;
}
.carousel_btns a{
	display: block;
	position: absolute;
	top: 40%;
}
.carousel_btns .prev {
	left: 20px;
}
.carousel_btns .next {
	right: 20px;
}

</style>
</head>
<body>
	<div class="carousel_slide">
		<div>
			<ul class="carousel_wrap">
				<li class="carousel_1"><a href="#"><img src="../images/banner_1.jpg" alt="banner_1"></a></li>
				<li class="carousel_2"><a href="#"><img src="../images/banner_2.jpg" alt="banner_2"></a></li>
				<li class="carousel_3"><a href="#"><img src="../images/banner_3.jpg" alt="banner_3"></a></li>
			</ul>
		</div>
		<div class="carousel_btns">
			<a href="#" class="prev" onclick="return false"><img src="../images/btn_prev.png"></a>
			<a href="#" class="next" onclick="return false"><img src="../images/btn_next.png"></a>
		</div>
	</div>
	<a href="http://www.freepik.com">Designed by Freepik</a>
</body>
</html>

CSS

화면의 너비를 가득 채우는 캐러셀을 만들고자 했기 때문에 carousel-slide의 width를 100%로 설정했다.

처음이다 보니 움직임을 고려하여 너비를 지정해야하는 부분이 헷갈려 한참을 고민하다, 

3장의 캐러셀을 포함하는 carousel_wrap의 width는 300%, 그에 속하는 각 캐러셀의 width는 33.333%로 지정했다.

 

JQuery

이전/이후 버튼을 누를 때마다 carousel_wrap의 위치가 좌 또는 우로 100%씩 이동하도록 설정했고

첫 번째 이미지에서 이전 버튼을 누를 경우 마지막 위치(left:-200%)로,

마지막 이미지에서 이후 버튼을 누를 경우 처음 위치(left:0)로 돌아가도록 설정했다.

이를 carouselIndex, carousleLength 변수를 만들어 위치를 비교했다.

 

느낀점

만들고 난 직후에는 혼자 굉장히 뿌듯해 했는 데 며칠이 지나고 다시 보니 정말 엉성해보인다... 😅

마지막 이미지에서 첫 이미지로 넘어가는 부분도 후루룩 되돌아가지 않고 자연스럽게 순환되도록 고쳐야할 것 같고...

지금은 프로젝트와 정보처리기사 공부로 시간이 모자라서 나중에 날 잡고 고쳐보는 시간을 가져야겠다.

 

 

 

  부트스트랩을 이용하여 만든 캐러셀

제이쿼리로 혼자 씨름했던 날이 며칠이나 지났을까, 수업시간에 부트스트랩을 이용해 캐러셀을 만드는 방법을 배웠다.

캐러셀 하나 만든다고 꽤 오랜 시간을 소비했었는데 부트스트랩을 이용하니 엄청 간단해서 조금 눈물이 날 뻔 했다,,,,,😂

 

Tryit Editor v3.6

Bootstrap Example /* Make the image fully responsive */ .carousel-inner img { width: 100%; height: 100%; }

www.w3schools.com

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<style>
.carousel {
	position: relative
}
.carousel.pointer-event {
	-ms-touch-action: pan-y;
	touch-action: pan-y
}
.carousel-inner {
	position: relative;
	width: 100%;
	overflow: hidden
}
.carousel-inner::after {
	display: block;
	clear: both;
	content: ""
}
.carousel-item {
	position: relative;
	display: none;
	float: left;
	width: 100%;
	margin-right: -100%;
	-webkit-backface-visibility: hidden;
	backface-visibility: hidden;
	transition: -webkit-transform .6s ease-in-out;
	transition: transform .6s ease-in-out;
	transition: transform .6s ease-in-out, -webkit-transform .6s ease-in-out
}
@media ( prefers-reduced-motion :reduce) {
	.carousel-item {
		transition: none
	}
}
.carousel-item-next, .carousel-item-prev, .carousel-item.active {
	display: block
}
.active.carousel-item-right, .carousel-item-next:not (.carousel-item-left
	){
	-webkit-transform: translateX(100%);
	transform: translateX(100%)
}
.active.carousel-item-left, .carousel-item-prev:not (.carousel-item-right
	){
	-webkit-transform: translateX(-100%);
	transform: translateX(-100%)
}
.carousel-fade .carousel-item {
	opacity: 0;
	transition-property: opacity;
	-webkit-transform: none;
	transform: none
}
.carousel-fade .carousel-item-next.carousel-item-left, .carousel-fade .carousel-item-prev.carousel-item-right,
	.carousel-fade .carousel-item.active {
	z-index: 1;
	opacity: 1
}
.carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right
	{
	z-index: 0;
	opacity: 0;
	transition: opacity 0s .6s
}
@media ( prefers-reduced-motion :reduce) {
	.carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right
		{
		transition: none
	}
}
.carousel-control-next, .carousel-control-prev {
	position: absolute;
	top: 0;
	bottom: 0;
	z-index: 1;
	display: -ms-flexbox;
	display: flex;
	-ms-flex-align: center;
	align-items: center;
	-ms-flex-pack: center;
	justify-content: center;
	width: 15%;
	color: #fff;
	text-align: center;
	opacity: .5;
	transition: opacity .15s ease
}
@media ( prefers-reduced-motion :reduce) {
	.carousel-control-next, .carousel-control-prev {
		transition: none
	}
}
.carousel-control-next:focus, .carousel-control-next:hover,
	.carousel-control-prev:focus, .carousel-control-prev:hover {
	color: #fff;
	text-decoration: none;
	outline: 0;
	opacity: .9
}
.carousel-control-prev {
	left: 0
}
.carousel-control-next {
	right: 0
}
.carousel-control-next-icon, .carousel-control-prev-icon {
	display: inline-block;
	width: 20px;
	height: 20px;
	background: no-repeat 50%/100% 100%
}
.carousel-control-prev-icon {
	background-image:
		url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")
}
.carousel-control-next-icon {
	background-image:
		url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")
}
.carousel-indicators {
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 15;
	display: -ms-flexbox;
	display: flex;
	-ms-flex-pack: center;
	justify-content: center;
	padding-left: 0;
	margin-right: 15%;
	margin-left: 15%;
	list-style: none
}
.carousel-indicators li {
	box-sizing: content-box;
	-ms-flex: 0 1 auto;
	flex: 0 1 auto;
	width: 30px;
	height: 3px;
	margin-right: 3px;
	margin-left: 3px;
	text-indent: -999px;
	cursor: pointer;
	background-color: #fff;
	background-clip: padding-box;
	border-top: 10px solid transparent;
	border-bottom: 10px solid transparent;
	opacity: .5;
	transition: opacity .6s ease
}

@media ( prefers-reduced-motion :reduce) {
	.carousel-indicators li {
		transition: none
	}
}
.carousel-indicators .active {
	opacity: 1
}
.carousel-caption {
	position: absolute;
	right: 15%;
	bottom: 20px;
	left: 15%;
	z-index: 10;
	padding-top: 20px;
	padding-bottom: 20px;
	color: #fff;
	text-align: center
}
#demo {
	width: 100%;
	height: 700px;
	text-align: center;
}
.carousel-inner>div {
	width: 100%;
}
.carousel-inner div:nth-child(1) {
	background-color: #acb5ad;
}
.carousel-inner div:nth-child(2) {
	background-color: #f5f7ee;
}
.carousel-inner div:nth-child(3) {
	background-color: #6e7e23;
}
</style>
</head>
<body>
	<div id="demo" class="carousel slide" data-ride="carousel">

		<!-- Indicators -->
		<ul class="carousel-indicators">
			<li data-target="#demo" data-slide-to="0" class="active"></li>
			<li data-target="#demo" data-slide-to="1"></li>
			<li data-target="#demo" data-slide-to="2"></li>
		</ul>

		<!-- The slideshow -->
		<div class="carousel-inner">
			<div class="carousel-item active">
				<img src="../images/banner_1.jpg" alt="banner_1" width="1240" height="700">
			</div>
			<div class="carousel-item">
				<img src="../images/banner_2.jpg" alt="banner_2" width="1240" height="700">
			</div>
			<div class="carousel-item">
				<img src="../images/banner_3.jpg" alt="banner_3" width="1240" height="700">
			</div>
		</div>

		<!-- Left and right controls -->
		<a class="carousel-control-prev" href="#demo" data-slide="prev"> <span
			class="carousel-control-prev-icon"></span>
		</a> <a class="carousel-control-next" href="#demo" data-slide="next">
			<span class="carousel-control-next-icon"></span>
		</a>
	</div>

</body>
</html>

 

부트스트랩

예제 코드를 그대로 복사해서 필요한 부분만 변경해 만들면 된다.

처음엔 CSS 스타일 시트도 예제의 링크 그대로 사용하여 만들었다가, 변경이 필요한 부분이 생겨서 CSS 링크로 들어가 캐러셀의 CSS만 가져와 스타일 태그로 붙여넣었다.

 

느낀점

이렇게... 이렇게 간단할 수가.. 부트스트랩을 이번에 처음 알게 됐는데 정말 손쉽게 원하는 내용을 만들 수 있어서 놀랐다.처음엔 이렇게 쉬운 방법을 두고 혼자 쩔쩔맨 게 조금 허탈하기도 했는 데, 스스로 해보는 것도 중요한 배움의 과정 중 하나니까 긍정적으로 생각하기로 했다! 나도 얼른 실력을 키우고 싶다...!.. 

 

 

 

'프론트엔드 > JQuery' 카테고리의 다른 글

[JQuery] Ajax 답변삭제 팝업  (0) 2021.06.16
[JQuery] on 함수  (0) 2021.06.15
[JQuery] Ajax  (0) 2021.06.11
[JQuery] 클릭 이벤트  (0) 2021.05.25
[JQuery] 선택자  (0) 2021.05.25

원래는 주석처리가 되어있는데 해제해줌. 

<오라클 연동 후 기본 제공 테이블(EMP)의 데이터 출력하기>

import java.sql.*;

public class DBConnection {
	//필드(field)
	Connection conn;
	Statement stmt;
	ResultSet rs;
	
	//생성자(constructor)
	public DBConnection() {
		try {
			//1
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			//2
			String url = "jdbc:oracle:thin:@127.0.0.1:1521";   //오라클 서버의 네번째 db 타입(thin)으로 접근하는 주소
			String user = "scott";  //기본 제공 아이디로 로그인
			String password = "tiger";
			conn = DriverManager.getConnection(url, user, password);
			
			//3
			stmt = conn.createStatement();
			
		} catch (SQLException e) {
			// TODO: handle exception
		}
		
	}

	
	//Method
	public void getResult() {
		try {
			//4
			String sql = "select * from emp";
			rs = stmt.executeQuery(sql); 
			
			//5
			while(rs.next()) {
				//하나의 row 출력    >>  rs.getInt(columnIndex);
				System.out.print(rs.getInt(1)+"\t"); 
				System.out.print(rs.getString(2)+"\t");
				System.out.print(rs.getString(3)+"\t");
				System.out.print(rs.getInt(4)+"\t");
				System.out.print(rs.getString(5)+"\t");
				System.out.print(rs.getInt(6)+"\t");
				System.out.print(rs.getInt(7)+"\t");
				System.out.print(rs.getInt(8)+"\n");
			}
            
			rs.close();
			stmt.close();
			conn.close();
		
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
	}
}

1. 드라이버 로딩 - 빌드패스로 연결해준 jar 파일의 압축을 풀어 경로 확인 가능

2. Connection 객체 생성

3. Statement 객체 생성 - 데이터를 운반해주는 택시 역할
4. ResultSet 객체 생성 - sql 필요!
5. ResultSet 객체에서 데이터 가져오기 
   - rs.next() ---> rs의 row를 한 줄씩 넘기며 가져옴. 데이터가 있으면 true, 없으면 false

 


** sql의 종류와 사용 용도에 따라 알맞은 execute~ 메소드를 사용해야함
  - executeQuery : 쿼리의 실행결과(테이블)를 ResultSet에 담아옴 (리턴타입: ResultSet)
  - executeUpdate : sql 실행시 스크립트에 나오는 "n행이 삽입/수정/삭제 되었습니다."의 n값을 가져옴(리턴타입: int)

https://programmers.co.kr/learn/courses/30/lessons/42576

 

코딩테스트 연습 - 완주하지 못한 선수

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수

programmers.co.kr

import java.util.*;
import java.util.Map.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
 
        HashMap<String, Integer> hm = new HashMap<>();
        
        for(String part : participant) {
            hm.put(part, hm.getOrDefault(part,0)+1);
        }
        for(String comp : completion) {
            hm.put(comp, hm.getOrDefault(comp,0)-1);
        }
        /*for(String name : hm.keySet())  {
            if(hm.get(name) != 0) {
                answer = name;
                break;
            }
        }*/
        for(Entry<String, Integer> entry: hm.entrySet()) {
            if(entry.getValue() != 0) {
                answer = entry.getKey();
                break;
            }
        }
       return answer;
    }
}

+ Recent posts