반응형
반응형
package multi_thread;

public class SetAndGetThread extends Thread{
	public SetAndGetThread() {
		setName("ThreadA");
	}
	
	public void run() {
		for(int i = 0 ; i < 2 ; i++) {
			System.out.println(getName() + "가 출력한 내용");
		}
	}
}

생성자setName을 이용해 스레드 이름을 설정할 수 있습니다.

그리고 getName으로 스레드의 이름을 가져올 수 있습니다.

 

이번엔 귀찮아서 메인스레드는 안 만들었습니다.

반응형
반응형
package multi_thread;

import java.awt.Toolkit;

public class BeepThread extends Thread {
	@Override
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for(int i = 0 ; i < 5 ; i++) {
			toolkit.beep();
			try {Thread.sleep(500);} catch(Exception e) {}
		}
	}
}
package multi_thread;

import java.awt.Toolkit;

public class BeepPrintExample2 {

	public static void main(String[] args) {

		// 기존 방법
        // Runnable beepTask = new BeepTask(); // Runnable 상속 받은 BeepTask 클래스
		// Thread thread = new Thread(beepTask);

		// 방법1 (Runnable 객체 선언 후 Injection 안 해줘도 된다.
		Thread thread = new BeepThread();
		thread.start();
        

		
		// 방법2 (익명 객체를 이용한 방법)
		/*
		Thread thread2 = new Thread() {
			public void run() {
				Toolkit toolkit = Toolkit.getDefaultToolkit();
				for(int i = 0 ; i < 5 ; i++) {
					toolkit.beep();
					try {Thread.sleep(500);} catch(Exception e) {}
				}
			}
		};
		thread2.start();
		*/
		
		for (int i = 0 ; i < 5 ; i++) {
			System.out.println("띵");
			try {Thread.sleep(500);} catch(Exception e) {}
		}

	}

}

Runnable을 이용하지 않고 Thread의 하위 클래스로 스레드를 정의하면서 작업 내용을 포함 시킬 수도 있습니다.

 

extends로 Thread를 받고 run() 안에 스레드 실행할 코드를 정의합니다.

아니면 저번에 한 거 처럼 익명객체로 이용해 클래스 생성하지 않고 사용할 수 있습니다.

 

Thread thread = new BeepThread();

 

Thread를 상속 받는 BeepThread하위 클래스 입니다.

큰 Thread에 담게 되는 것이죠 Runnable역할을 해주면서 코드를 더 줄일 수 있습니다.

 

반응형
반응형
package multi_thread;

import java.awt.Toolkit;

public class BeepTask implements Runnable{
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for(int i = 0 ; i < 5 ; i++) {
			toolkit.beep();
			try {Thread.sleep(500);} catch(Exception e) {}
			}
		}
	}
package multi_thread;

import java.awt.Toolkit;

public class BeepPrintExample {

	public static void main(String[] args) {
		
		// 방법 1
		Runnable beepTask = new BeepTask(); // Runnable 상속 받은 BeepTask 클래스
		Thread thread = new Thread(beepTask);
		thread.start();

		// 방법 2 (익명 객체 이용)
		/* 
		Thread thread2 = new Thread(new Runnable() {
			@Override
			public void run() {
				Toolkit toolkit = Toolkit.getDefaultToolkit();
				for(int i = 0 ; i < 5 ; i++) {
					toolkit.beep();
					try {Thread.sleep(500);} catch(Exception e) {}
					}
				}
			});
		thread2.start();
		*/
		
		for (int i = 0 ; i < 5 ; i++) {
			System.out.println("띵");
			try {Thread.sleep(500);} catch(Exception e) {}
		}
		
		
	}
}

스레드하나를 실행시키는 역할을 하는 것을 의미합니다. 

(말이 하나지 100개의 업무를 한 사람이 하는 거라고 생각하시면 됩니다.)

(예를 들어 자바를 실행시키면 메인스레드만 돌아감)

 

멀티스레드란 여러개를 동시에 실행 시킬 수 있게 만들어서 병렬적으로 처리할 수 있는 것이죠

병렬적으로 처리하면 여러개의 일을 분담하니 효율적이겠죠?


메인 스레드가 작업스레드보다 먼저 종료되더라도

다른 스레드가 계속 실행중이라면 프로세스는 종료되지 않는 특징이 있습니다.

Runnable작업 스레드가 실행 할 수 있는 코드가지고 있는 객체라고 해서 붙여진 이름입니다.
인터페이스 타입이기 때문에 구현 객체를 만들어 대입해야한다. run()을 재정의해서 실행할 코드를 적어야합니다.

class Task implements Runnable{
	public void run(){
		실행할 자바코드
	}
}

이런 식이 기본 구조입니다. 

 

위에 예제는 컴퓨터에서 띵소리를 내게 하는 toolkit이라는 걸을 이용해 소리를 내면서

그와 동시에 for문을 이용해 띵이라는 걸 출력해보려고 합니다. 그러면 두개가 동시에 작동해야 겠죠?

 

public class BeepTask implements Runnable{
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for(int i = 0 ; i < 5 ; i++) {
			toolkit.beep();
			try {Thread.sleep(500);} catch(Exception e) {}
			}
		}
	}

 

run안에 스레드 내용에는 toolkit.beep()이 0.5초의 간격을두고 5번 반복하게 끔 만들었습니다.

 

beepTask라는 객체를 만듭니다.

또한 Runnable내용을 실행시킬 스레드만듭니다.(thread)

그리고 Runnable 내용을 그 안에 넣습니다. ( Thread thread = new Thread(beepTask) ) 선언과 Runnable 내용 넣기

thread.start로 Thread를 실행시킵니다.

 

이러면 메인 Thread에서는 이걸 일 하고 다른 스레드에서는 컴퓨터에서 띵소리를 내게하는 일을 합니다. (병렬)

 

Runnable을 상속받는 클래스를 만들어서 쓰는 위에 방법과 그렇지 않고 바로 메인쓰레드에서 선언과 동시에

쓰는 익명 객체를 이용하는 방식이 있습니다.

익명 객체란 일회성이고 파일을 줄일 수 있는 장점이 있습니다. 자세한 건 나중에 포스팅하겠습니다.

 

Thread thread2 = new Thread (new Runnable() {
    @Override
    public void run() {
        스레드내용
    }
});

이러한 구조가 됩니다. Thread 매개변수에는 Runnable객체가 들어가야하는데 그걸 밑에 바로 정의시켜주는 것이죠

 

반응형
반응형
package error_throws;

public class Calculator {
	
	public static int add (int x, int y) throws 천을_넘는_예외, 음수가_되는_예외 {
		int result = x + y;
		if(result > 1000) {
			throw new 천을_넘는_예외();
			// throw new NullPointerException();
		}
		
		if(result < 0) {
			throw new 음수가_되는_예외();
		}
		return x + y;
	}
}
package error_throws;

public class 음수가_되는_예외 extends Exception {
	
	@Override
	public String getMessage() {
		return "입력 값이 음수인 오류가 발생했습니다.";
	}
	
}
package error_throws;

public class 천을_넘는_예외 extends Exception {
	
}​
package error_throws;

public class ErrorThrows {
	

	public static void main(String[] args) {
	
		Calculator calc = new Calculator();
		int result = 0;
		// result = Calculator.add(6, 4); 예외처리를 해줘야한다.
		try {
			result = Calculator.add(-6, 4);
			
		}catch(음수가_되는_예외 e) {
			System.out.println(e.getMessage());
			System.out.println("음수가 발생 되었습니다.");
		}catch(천을_넘는_예외 e) {
			
		}
		System.out.println("add : " + result);
	}
}

컴파일하기 전에 빨간줄이 그어지는 에러가 있고 그렇지 않은 것이 있는데요 만약 값이 제대로 안 넘어갈 경우

컴파일은 됐지만 NullPointException이라는 에러가 나오게 됩니다. 이러한 것들을 처리하기 위해서 저번에

try catch문을 썼는데요 그걸 이제 더 발전 시켜서 사용해보려고 합니다.

 

더하기 계산 기능을 넣으려고 합니다. 

	public static int add (int x, int y) throws 천을_넘는_예외, 음수가_되는_예외 {
		int result = x + y;
		if(result > 1000) {
			throw new 천을_넘는_예외();
			// throw new NullPointerException();
		}
		
		if(result < 0) {
			throw new 음수가_되는_예외();
		}
		return x + y;
	}

static으로 선언해 주세요 throws는 신경 쓰지마시고 저희가 임의로 에러를 만드려고 합니다.

1000이라는 합이 나오면 에러가 나오도록 그리고 합이 음수가 나오면 에러가 나오도록 하려고 합니다.

 

throw new라는 건 에러를 강제로 발생시키는 것입니다. 

여기에서 우리가 만든 걸 쓸 수도 원래 있는 에러를 넣을수도 있습니다.

throw new 천을_넘는_예외(); 이런식으로 하면 천을_넘는_예외를 만들라고 빨간줄이 그어집니다.

가져다대시고 class를 만든다를 클릭해서 만들어주세요

 

package error_throws;

public class 천을_넘는_예외 extends Exception {
	
}

이렇게 만들어지게 됩니다.

 

이 클래스에서는 에러를 처리해주는 역할을 해줍니다. 어떤식으로 메세지를 반환할지 등...

아무것도 안 적을 수도 있습니다.

 

그리고 throws를 추가해줘야합니다.

public static int add (int x, int y) throws 천을_넘는_예외, 음수가_되는_예외 {
....

throws란 무엇이냐면 던진다는 뜻인데 s라서 여러개를 던질 수 있게 한다는 의미입니다.

여기에선 2개를 넘기도록 되어있는데 이게 어디로 던지냐고한다면 해당 에러가 발생한다면

예를 들어 result가 1000이 넘어가서 예외가 발생하면 그걸

위에 천을_넘는_예외라는 클래스에서 처리하겠다는 의미입니다.

 

package error_throws;

public class 음수가_되는_예외 extends Exception {
	
	@Override
	public String getMessage() {
		return "입력 값이 음수인 오류가 발생했습니다.";
	}
	
}

또한 예외 메세지를 넘길 때 이러한 방법으로도 넘길 수 있습니다.

getMessage()를 오버라이드 해서 사용 가능합니다.

	try {
			result = Calculator.add(-6, 4);
			
		}catch(음수가_되는_예외 e) {
			System.out.println(e.getMessage());
			System.out.println("음수가 발생 되었습니다.");
		}catch(천을_넘는_예외 e) {
			
		}

getMessage()를 통해서 메세지를 출력할수도 있고

저번에 try catch에서 한 거처럼 catch문에다가 에러처리를 할 수도 있습니다.

반응형
반응형
package nesting_interface_class.nesting_interface;

public class Button {
	
	OnClickListener listener; // 인터페이스 타입 필드
	
	void setOnClickListner(OnClickListener listener) {
		this.listener = listener;
	}

	void touch() {
		listener.onClick();
	}
	
	interface OnClickListener{ // 중첩 인터페이스
		void onClick();
	}
}
package nesting_interface_class.nesting_interface;

public class CallListener implements Button.OnClickListener{
	
	@Override
	public void onClick() {
		System.out.println("전화를 겁니다.");
	}
}​
package nesting_interface_class.nesting_interface;

public class MessageListener implements Button.OnClickListener{

	@Override
	public void onClick() {
		System.out.println("메시지를 보냅니다.");
	}
}
package nesting_interface_class.nesting_interface;

public class ButtonExample {

	public static void main(String[] args) {
		
		Button btn = new Button();
		
		btn.setOnClickListner(new CallListener());
		btn.touch();
		
		btn.setOnClickListner(new MessageListener());
		btn.touch();
	}

}

 

클래스 내부안에 선언한 인터페이스
주로 UI프로그래밍에서 이벤트 처리할 목적으로 사용 됩니다.

Button 이라는 클래스 안에 OnClickListener라는 인터페이스가 있고 무조건 구현해야하는 onClick 메소드가 있습니다.

 

void touch() 와 void setOnClickListener는 listener라고 선언한 인터페이스 타입 필드에 값이 들어갔을 때 

사용할 메소드입니다.

 

btn.setOnClickListner(new CallListener());
btn.setOnClickListner(new MessageListener());

이렇게 인터페이스를 상속받은 클래스를 넣는 것입니다. 그러면 각각 클래스에서 구현한 interface부분 메소드

다르게 출력이 되는 것입니다.

 

 

반응형
반응형
package nesting_interface_class;

public class NestingClassA {
	int aField = 5;
	void aMethod1() {};
	
	static int aField2 = 10;
	static void aMethod2() {};
	
    class NestingClassB{
		NestingClassB() {} 	// 생성자
		int field1; // 인스턴스 필드
		// static int field2; // 정적 필드 사용불가(x)
		void method1() { System.out.println("중첩 클래스B");} // 인스턴스 메소드
		// static void method2() {} // 정적 메소드 사용불가(x)
		
		void method2() {
			class NestingClassD { // *로컬 클래스*
				NestingClassD() {} 	// 생성자
				int field1;	// 인스턴스 필드
				// static int field2;	// 정적 필드 사용불가(x)
				void method1() {System.out.println("로컬 클래스");} // 인스턴스 메소드
				// static void method2() {}	// 정적 메소드 사용불가(x)
			}
			NestingClassD  D = new NestingClassD();
			D.field1 =3 ;
			D.method1();
		}
		
		// 멤버 클래스 에서 사용 제한 가능 여부
		void callA () {
			aField = 10; // A 인스턴스 필드
			aMethod1();  // A 인스턴스 메소드
			
			aField2 = 10; // A 정적 필드
			aMethod2(); // A 정적 메소드
			

			NestingClassA.this.aMethod1();  // 바깥 클래스 메소드 참조 (A 인스턴스 메소드)
			NestingClassA.this.aField = 10; // 바깥 클래스 필드 참조 (A 인스턴스 필드)
			this.field1 = 10; // 현재 클래스의 필드 참조 (B 인스턴스 필드)
			this.method1();	// 현재 클래스의 메소드 참조 (B 인스턴스 메소드)
		}
	}
	
	static class NestingClassC{
		NestingClassC() {};  // 생성자
		int field1; // 인스턴스 필드
		static int field2; // 정적 필드
		void method1() {System.out.println("중첩 클래스C");}; // 인스턴스메소드
		static void method2() {System.out.println("static 중첩 클래스C");}; // 정적 메소드
		
		void callA () {
			// aField = 10; // A 인스턴스 필드 사용불가(x)
			// aMethod1(); // A 인스턴스 메소드 사용불가(x)
			
			aField2 = 10; // A 정적 필드
			aMethod2();	// A 정적 메소드
		}
	}
}
package nesting_interface_class;

public class NestingClass {

	public static void main(String[] args) {
		
		NestingClassA A = new NestingClassA();
		NestingClassA.NestingClassB B = A.new NestingClassB();				
		B.field1 = 3; // 인스턴스 필드
		B.method1(); // 인스턴스 메소드
		
		NestingClassA.NestingClassC C = new NestingClassA.NestingClassC();
		C.field1 =3; // 인스턴스 필드
		C.method1(); // 인스턴스 메소드
		NestingClassA.NestingClassC.field2 = 3; // 정적 필드
		NestingClassA.NestingClassC.method2(); // 정적 메소드
	}

}


클래스 내부에 선언한 클래스입니다.
두 클래스의 멤버들을 서로 쉽게 접근할 수 있다는 특징과
클래스를 감춤으로서 코드의 복잡성을 줄일 수 있다는 특징을 가지고 있습니다.

멤버클래스도 하나의 클래스이기 때문에 컴파일하면 바이트 코드파일이 별도로 생성됩니다.

 

NestingClassA A = new NestingClassA();
NestingClassA.NestingClassB B = A.new NestingClassB();				
B.field1 = 3; // 인스턴스 필드
B.method1(); // 인스턴스 메소드

먼저 A객체(바깥클래스)를 생성후 B객체(내부클래스)를 생성해야 합니다.

 

static class NestingClassC{
		NestingClassC() {};  // 생성자
		int field1; // 인스턴스 필드
		static int field2; // 정적 필드
		void method1() {System.out.println("중첩 클래스C");}; // 인스턴스메소드
		static void method2() {System.out.println("static 중첩 클래스C");}; // 정적 메소드
		
		void callA () {
			// aField = 10; // A 인스턴스 필드 사용불가(x)
			// aMethod1(); // A 인스턴스 메소드 사용불가(x)
			
			aField2 = 10; // A 정적 필드
			aMethod2(); // A 정적 메소드
		}

또한 내부 클래스를 static으로 만든 경우에만 static으로 필드나 메소드를 정의할 수 있습니다.

 

  class NestingClassB{
  	...
    void callA () {
        aField = 10; // A 인스턴스 필드
        aMethod1();  // A 인스턴스 메소드

        aField2 = 10; // A 정적 필드
        aMethod2(); // A 정적 메소드


        NestingClassA.this.aMethod1();  // 바깥 클래스 메소드 참조 (A 인스턴스 메소드)
        NestingClassA.this.aField = 10; // 바깥 클래스 필드 참조 (A 인스턴스 필드)
        this.field1 = 10; // 현재 클래스의 필드 참조 (B 인스턴스 필드)
        this.method1();	// 현재 클래스의 메소드 참조 (B 인스턴스 메소드)
	}
}

내부 클래스가 static이 아니라면 바깥 클래스가 정적으로 정의되든 안 되든 접근이 가능합니다.

 

또 다른 접근 방법은 this를 이용해 접근할 수 있습니다. (바깥클래스.this.필드 or 메소드)

현재 클래스의 필드나 메소드도 접근할 수 있습니다. (this.필드 or 메소드)

 

static class NestingClassC{
	....
	void callA () {
			// aField = 10; // A 인스턴스 필드 사용불가(x)
			// aMethod1(); // A 인스턴스 메소드 사용불가(x)
			
			aField2 = 10; // A 정적 필드
			aMethod2();	// A 정적 메소드
	}
}

내부 클래스 static 선언된 경우에는 static으로 선언된 필드 메소드만 접근이 가능합니다.

 

class NestingClassB{
		void method2() {
			class NestingClassD { // *로컬 클래스*
				NestingClassD() {} 	// 생성자
				int field1;	// 인스턴스 필드
				// static int field2;	// 정적 필드 사용불가(x)
				void method1() {System.out.println("로컬 클래스");} // 인스턴스 메소드
				// static void method2() {}	// 정적 메소드 사용불가(x)
			}
			NestingClassD  D = new NestingClassD();
			D.field1 =3 ;
			D.method1();
		}
}

내부 클래스안에 메소드 안에 클래스를 또 만들어서 사용할 수도 있습니다.

이걸 로컬 클래스라고 합니다.

반응형
반응형

 

이번에는 JSP파일에 DB를 연결하는 걸 해보도록 하겠습니다.

 

1. DB는 MySQL 쓸겁니다.

2. JDBC라는 DB랑 JSP랑 연결해주는 게 필요합니다.

 

https://dev.mysql.com/downloads/

 

MySQL :: MySQL Community Downloads

The world's most popular open source database

dev.mysql.com

다운 받아서 압축을 풀면 mysql-connector-java-버전명.jar이라는게 있는데 이걸 WEB-INF - lib넣어주세요

 

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

    
<html>
<head><title>MEMBER 테이블 레코드 삽입</title></head>
<body>
<header>
	<%@ include file="topMenu.jsp" %>
</header>
<contents>
	<%@ include file="insertForm.jsp" %>
</contents>

</body>
</html>

join.jsp 입니다.

 

<%@ 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>
</head>
<body>
<h1> <a href="join.jsp">[ 회원 가입 ]</a> <a href="memberList.jsp">[회원 목록]</a> </h1>
</body>
</html>

topMenu.jsp 입니다.

 

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head><title>MEMBER 테이블 레코드 삽입</title></head>
<body>
<form action="useBeanInsert.jsp" method="post">
	<table border="1">
		<tr>
			<td>아이디</td>
			<td><input type="text" name="memberID" size="10"></td>
			<td>암호</td>
			<td><input type="text" name="password" size="10"></td>
		</tr>
		<tr>
			<td>이름</td>
			<td><input type="text" name="name" size="10"></td>
			<td>이메일</td>
			<td><input type="text" name="email" size="10"></td>
		</tr>
		<tr>
			<td colspan="4"><input type="submit" value="삽입"></td>
		</tr>
	</table>
</form>
</body>
</html>

insertForm.jsp 입니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import = "com.member.*"%>

<jsp:useBean class = "com.member.RegisterBean" id= "regBean" scope ="session"/>
<jsp:setProperty property ="*" name = "regBean"/>
<jsp:useBean class = "com.member.RegisterMgr" id ="regMgr" scope = "session"/>

<% regMgr.insertMember(regBean);%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	
</body>
</html>

useBeanInsert.jsp 입니다.

 

2개의 자바빈을 사용할 건데 한 개는 Setter Getter로 이루어져있는 일반 POJO클래스입니다.

한 개는 DB와 연결해 상황에 맞는 쿼리문을 작동시킬 수 있게 만든 클래스입니다. 

여기에선 회원가입인 거이고 그에 대한 정보가 INSERT 쿼리문을 이용해 DB에 저장하는 방식입니다.

 

package com.member;

public class RegisterBean {

		private String memberID;
		private String password;
		private String name;
		private String email;
		
		public String getMemberID() {
			return memberID;
		}
		public void setMemberID(String memberID) {
			this.memberID = memberID;
		}
		
		public String getPassword() {
			return password;
		}
		public void setPassword(String password) {
			this.password = password;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getEmail() {
			return email;
		}
		public void setEmail(String email) {
			this.email = email;
		}
		

}
package com.member;

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Vector;


 
 public class RegisterMgr {
    
 	private final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
 	private final String JDBC_URL = "jdbc:mysql://:3307/jsp?characterEncoding=utf-8";
 	// 타임존 에러시
 	// jdbc:mysql://localhost:3306/DB이름?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
 	// jdbc:mysql://ip:port/testdb?characterEncoding=UTF-8&serverTimezone=UTC
 	private final String USER = "root";
 	private final String PASS = "1234";
 
 	public RegisterMgr() {
 	 try{
 	   Class.forName(JDBC_DRIVER);
 	   }catch(Exception e){
 	      System.out.println("Error : JDBC 드라이버 로딩 실패");
 	   }
     }//MemberMgr()
 
    public Vector getMemberList() {
	   Connection conn = null;
	   Statement stmt = null;
       ResultSet rs = null;
       Vector vecList = new Vector();
       try {
          conn = DriverManager.getConnection(JDBC_URL,USER,PASS);
          String strQuery = "select * from membertbl";
          stmt = conn.createStatement();
          rs = stmt.executeQuery(strQuery);
		  while (rs.next()) {
             RegisterBean regBean = new RegisterBean();
		 	 regBean.setMemberID (rs.getString("memberid"));
			 regBean.setPassword (rs.getString("password"));
 			 regBean.setName (rs.getString("name"));
 			 regBean.setEmail (rs.getString("email"));
             vecList.add(regBean);
          }
       } catch (Exception ex) {
          System.out.println("Exception" + ex);
       } finally {
          if(rs!=null)   try{rs.close();}  catch(SQLException e){}
		  if(stmt!=null) try{stmt.close();}catch(SQLException e){}
	      if(conn!=null) try{conn.close();}catch(SQLException e){}
       }
       return vecList;
    }
    public void insertMember(RegisterBean mem) {

 	   Connection conn = null;
 	   Statement stmt = null;
       ResultSet rs = null;
        try {
           conn = DriverManager.getConnection(JDBC_URL,USER,PASS);
           stmt =  conn.createStatement();
           stmt.executeUpdate("insert into membertbl values ("+ mem.getMemberID() +", "+ mem.getPassword() + ", "+ 
                   mem.getName() + "," + mem.getEmail() + ")" );

        } catch (Exception ex) {
           System.out.println("Exception" + ex);
        } finally {
           if(rs!=null)   try{rs.close();}  catch(SQLException e){}
 		  if(stmt!=null) try{stmt.close();}catch(SQLException e){}
 	      if(conn!=null) try{conn.close();}catch(SQLException e){}
        }
        return ;
     }
 }
private final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
private final String JDBC_URL = "jdbc:mysql://127.0.0.1:3307/jsp?characterEncoding=utf-8";

먼저 com.mysql.jdbc.Driver 저장해주시고

jdbc:mysql://아이피:포트번호/DB명?characterEncoding=utf-8 이렇게 작성하시면 됩니다.

 

저기에선 localhost:3306이나 127.0.0.1:3307 인 것이죠

 	private final String USER = "root";
 	private final String PASS = "1234";

아이디를 USER에 넣고 비밀번호를 PASS에 넣습니다.

 

Class.forName(JDBC_DRIVER); 는 jar파일을 이용하는 과정입니다.

 

지금은 삽입과정이니까 삽입부분만 보도록 하겠습니다.

 

public void insertMember(RegisterBean mem) {

 	   Connection conn = null;
 	   Statement stmt = null;
       ResultSet rs = null;
        try {
           conn = DriverManager.getConnection(JDBC_URL,USER,PASS);
           stmt =  conn.createStatement();
           stmt.executeUpdate("insert into membertbl values ("+ mem.getMemberID() +", "+ mem.getPassword() + ", "+ 
                   mem.getName() + "," + mem.getEmail() + ")" );

        } catch (Exception ex) {
           System.out.println("Exception" + ex);
        } finally {
           if(rs!=null)   try{rs.close();}  catch(SQLException e){}
 		  if(stmt!=null) try{stmt.close();}catch(SQLException e){}
 	      if(conn!=null) try{conn.close();}catch(SQLException e){}
        }
        return ;
     }

DriverManager.getConnection(내가 연결할 서버, 아이디, 비밀번호)로 내가 만든 서버와 연결합니다.

DriverManager.getConnection(JDBC_URL,USER,PASS);

 

DB연결객체.createStatement();

conn.createStatement();

 

쿼리문을 작성할 장소를 만들어 줍니다.

 

stmt.executeUpdate("insert into membertbl values ("+ mem.getMemberID() +", "+ mem.getPassword() + ", "+ 
                   mem.getName() + "," + mem.getEmail() + ")" );

 

쿼리문 작성장소.executeUpdate("쿼리문") 이런식으로 작성하면 됩니다.

getMemberID(), getMemberPassword(), getMemberName(), getMemberEmail()을 이용해

회원가입에 적은 값을 불러와서 저장하면 됩니다. 쿼리문은 " 내용 " 으로 작성되어야 하니까 

더블쿼테이션을 많이 씁니다. mem.getMeberID()의 경우는 자바코드이기 때문에 더블 쿼테이션을 뺀 것이고요

 

이제 회원목록을 누르면 DB에 저장된 걸 SELECT문으로 불러오도록 하겠습니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<html>
<head><title>MEMBER 테이블 레코드 삽입</title></head>
<body>
<header>
	<%@ include file="topMenu.jsp" %>   
</header>
<contents>
	<%@ include file="viewMemberList.jsp"  %>
</contents>

</body>
</html>

memberList.jsp 입니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import= "java.sql.* , java.util.*, com.member.*" %>
<jsp:useBean class="com.member.RegisterMgr" id="regMgr" scope="session" />

MEMBMER 테이블의 내용
<table width="100%" border="1">
<tr>
	<td>아이디</td><td>비번</td><td>이름</td><td>이메일</td>
</tr>
<%
        Vector vResult= regMgr.getMemberList();
		
		for(int i=0; i<vResult.size(); i++){
		RegisterBean rs = (RegisterBean)vResult.get(i);
		%>
		<tr> 
		<td align="center"><%= rs.getMemberID() %></td>
		<td align="center"><%= rs.getPassword() %></td>
		<td align="center"><%= rs.getName() %></td>
		<td align="center"><%= rs.getEmail()%></td>
		
		</tr>
		<%}%>


</table>

viewMemberList.jsp 입니다.

 

public Vector getMemberList() {
	   Connection conn = null;
	   Statement stmt = null;
       ResultSet rs = null;
       Vector vecList = new Vector();
       try {
          conn = DriverManager.getConnection(JDBC_URL,USER,PASS);
          String strQuery = "select * from membertbl";
          stmt = conn.createStatement();
          rs = stmt.executeQuery(strQuery);
		  while (rs.next()) {
             RegisterBean regBean = new RegisterBean();
		 	 regBean.setMemberID (rs.getString("memberid"));
			 regBean.setPassword (rs.getString("password"));
 			 regBean.setName (rs.getString("name"));
 			 regBean.setEmail (rs.getString("email"));
             vecList.add(regBean);
          }
       } catch (Exception ex) {
          System.out.println("Exception" + ex);
       } finally {
          if(rs!=null)   try{rs.close();}  catch(SQLException e){}
		  if(stmt!=null) try{stmt.close();}catch(SQLException e){}
	      if(conn!=null) try{conn.close();}catch(SQLException e){}
       }
       return vecList;

똑같이 getConnection을 이용해 서버와 쓸 DB를 연결합니다.

createStatement쿼리문을 쓸 공간을 만들어주세요

executeQuery(쿼리문)SELECT문을 안에 작성합니다.

 

executeQuery문SELECT문을 쓸 경우에만 쓰고 나머지는 executeUpdate를 씁니다.

 

그 결과를 ResultSet이라는 걸로 주게 되는게 테이블에 대한 정보가 들어있는 자료형입니다.

그리고 getString을 이용해 해당 필드명에 있는 값을 가져올 수 있습니다.

그걸 지금 Vector에다가 regBean객체를 넣는 것입니다. 왜냐하면 값이 여러개 일테니깐요

 

Vector vResult= regMgr.getMemberList();
		
		for(int i=0; i<vResult.size(); i++){
		RegisterBean rs = (RegisterBean)vResult.get(i);
		%>
		<tr> 
		<td align="center"><%= rs.getMemberID() %></td>
		<td align="center"><%= rs.getPassword() %></td>
		<td align="center"><%= rs.getName() %></td>
		<td align="center"><%= rs.getEmail()%></td>
		
		</tr>
<%}%>

Vector에 받은 값은 인덱스 하나에 RegisterBean형식이기 때문에 하나씩 받아서 각각 출력시키는 형태입니다.

 

반응형
반응형
<%@ page contentType="text/html;charset=utf-8" %>

<html>
<head><title>MEMBER 테이블 레코드 삽입</title></head>
<body>

<form action="usingBean_insert.jsp" method="post">
	<table border="1">
		<tr>
			<td>아이디</td>
			<td><input type="text" name="memberid" size="10"></td>
			<td>암호</td>
			<td><input type="text" name="password" size="10"></td>
		</tr>
		<tr>
			<td>이름</td>
			<td><input type="text" name="name" size="10"></td>
			<td>이메일</td>
			<td><input type="text" name="email" size="10"></td>
		</tr>
		<tr>
			<td colspan="4"><input type="submit" value="삽입"></td>
		</tr>
	</table>
</form>
</body>
</html>

메인 페이지입니다.

package ch06.memberRegister;

public class RegisterBean {
	private String memberid;
	private String password;
	private String name;
	private String email;
	
	public String getMemberid() {
		return memberid;
	}
	public void setMemberid(String memberid) {
		this.memberid = memberid;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	
} // private은 본인 클래스 내에서만 접근 가능
<%@ page contentType="text/html; charset=utf-8" %>
<%@ page import = "java.sql.*" %>
<%  request.setCharacterEncoding("utf-8");%>

<jsp:useBean class = "ch06.memberRegister.RegisterBean" id = "regBean" scope = "session"/>
<!-- 위는 이와 같다 RegisterBean regBean = new RegisterBean(); 
class는 src 자바파일을 의미함-->

<jsp:setProperty name = "regBean" property = "memberid" value = "chang"/>
<!-- 위는 이와 같다 regBean.memberid = "chang" 기본값이 chang 넘어온 거에서 값이 있으면 getProperty에서 바뀜-->

<jsp:setProperty name ="regBean" property = "*" />
<!-- insertForm에 name과 RegisterBean에 필드명하고 같아야한다 -> *를 쓰면 다 입력할 필요 없음 

	private String memberid;
	private String password;
	private String name;
	private String email;
	<input type="text" name="memberid" size="10"></td>....
-->

<html>
<head><title>삽입</title></head>
<body>
<h3>회원정보</h3>
<table bordercolor="#0000ff" border="1">
<tr>
   <td><strong>ID</strong></td>
   <td><strong>PASSWD</strong></td>
   <td><strong>NAME</strong></td>
   <td><strong>EMAIL</strong></td>
</tr>
<td> <jsp:getProperty property="memberid" name="regBean"/>  </td> <!-- regBean.memberid를 가져옴 -->
<td> <jsp:getProperty property="password" name="regBean"/> </td>
<td> <%= regBean.getName() %></td> <!-- regBean 객체를 만들었으니 거기에 있는 값을 가져온다 -->
<td> <%= regBean.getEmail() %> </td> <!-- inserForm name과 regBean.java에 필드명하고 같아야함 email = private String email -->
</tr>
</table>
 


</body>
</html>

 

자바빈 자바빈의 사용이유에 대해서 알아보겠습니다.

 

HTML안의 JAVA인 JSP로 웹 어플리케이션을 작성하다 보면 html 코드와 java 코드가 겹쳐지기 때문에 

가독성이 매우 떨어지게 됩니다. (스크립트릿으로 작성된 걸 의미)

또, JSP 페이지에 뷰(View)와 로직(Logic)을 공존시키면 코드의 재사용성도 현저히 떨어집니다.

JSP라는 녀석이 본래 View의 역할을 담당하기 때문에 이를 분리하여 

빈으로 작성하는 것이 코드의 가독성과 재사용성을 높이는 것이 좋습니다. 

 

이러한 이유로 JavaBean이라고 불리게 되는 것입니다.

 

일단 src에는 클래스를 만드는 곳이죠 여기에는 자바코드가 들어가게 되는 곳입니다.

직접 스크립트릿으로 로직을 짜는게 아니라 여기에서 로직을 짜서 이용할 수 있게 만드는 것이죠

일단 간단하게 id, password, name, email의 getter와 setter를 만들어서 사용해보겠습니다.

 

<jsp:useBean class = "ch06.memberRegister.RegisterBean" id = "regBean" scope = "session"/>

jsp:useBean을 이용해 우리가 만든 클래스를 사용한다고 선언을 해줘야합니다. 

class에는 경로를 적어줍니다. 자기가 만든 경로와 동일하게 적어주시면 됩니다.

scope영역을 지정할 수 있고 id객체명을 지정해줄 수 있습니다.

 

이걸로 RegisterBean 클래스의 regBean라는 객체를 생성한 것과 동일하다고 생각하시면 됩니다.

 

그리고 여기에서 선언한 변수명은 메인페이지의 name과 똑같이 만들어야합니다.

 

<jsp:setProperty name = "regBean" property = "memberid" value = "chang"/>

<jsp:setProperty name = "useBean에서 설정한 name" property = "저장된 변수" value ="defualt값">

 

<jsp:setProperty name ="regBean" property = "*" />

또한 이렇게 property에 *를 쓰면 자동적으로 RegisterBean.java의 변수를 사용할 수 있게 됩니다.

 

<jsp:getProperty property="memberid" name="regBean"/>

<jsp:getProperty property ="저장된 변수" name = "useBean에서 설정한 name"/>

이걸 통해 저장된 변수를 출력할 수 있습니다.

 

<%= regBean.getName() %>

이런식으로 스크립트릿으로 사용도 가능합니다. 하지만 이렇게 쓰면 useBean을 쓰는 이유가 없죠

로직과 뷰를 구분하기 위해서 쓰는 것인데 말이죠

반응형
반응형
<%@ 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>
</head>
<body>
	<%-- page 영역(pageContext)[1개 JSP파일] <= 
		 request 영역(request)[1개 화면에 해당되는 크기] <
		 session 영역(session)[[웹브라우저영역]  <
		 application 영역[그 상위버전 새 브라우저 열어도 남아있음, 서버에 남아 있어서](application) 
	--%>
	<h5> 4개의 영역과 속성 알아보기</h5>
	
	<% application.setAttribute("testId", "Yongmi"); %> 
	<%-- testId(속성) = "Yongmi" 
	pageContext는 jsp 한 페이지기 때문에 범위를 굳이 안 해줘도 된다 --%>  
	<form method = "post" action = "second.jsp">
		<input type ="submit" value = "2번째 페이지로">
	</form>
</body>
</html>
<%@ 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>
</head>
<body>
<h1> 2번째 페이지</h1>

<h3> setAttribute 내용 : <%= (String)application.getAttribute("testId") %> </h3>
<h3> setAttribute 내용 : <%= (String)application.getAttribute("wrongAttribute") %> </h3>
<%-- index에 선언한 session 범위 testId를 가져올때 사용 법 --%>

</body>
</html>

지금까지 name을 이용해 getParameter로 값을 받았습니다.

이번에는 변수를 선언하는 거처럼 값을 넘기는 걸 배우도록 하겠습니다.

 

JSP에는 페이지에 대한 영역이라는게 있는데 총 4개가 있습니다.

page 영역(pageContext)[1개 JSP파일] <= 
request 영역(request)[1개 화면에 해당되는 크기] <
session 영역(session)[[웹브라우저영역]  <
application 영역[그 상위버전 새 브라우저 열어도 남아있음, 서버에 남아 있어서](application)

📝1. page 영역

page영역으로 값을 선언하면 그 값은 그 JSP페이지에서만 남아 있습니다.

굳이 이러한 방법을 쓸 필요가 없이 그냥 스크립트릿으로 선언하던가 선언문으로 선언하면 되기 때문에

이 영역은 잘 안 쓰이게 됩니다.

 

📝2. request 영역

request영역으로 값을 선언하면 그 값은 1개 화면에 그 변수를 쓸 수 있습니다.

그 화면에는 JSP파일이 여러개로 만들어 졌을수도 1개로 이루어졌을 수도 있습니다. (모듈화 이야기)

 

📝3. session 영역

session영역으로 값을 선언하면 그 값은 웹브라우저내에 계속 남아있습니다.

웹브라우저 영역이라는 건 구글 크롬을 키고 새 페이지를 열고 어디 페이지를 가든 남아있다는 소리입니다.

예시를 들자면 로그인 해놓고 다른 작업을 하다 새페이지를 키고 다시 거기로 들어가면 로그인이 되어있는 거라고

이해하시면 이해하기 쉬울 것입니다.

 

📝4. application 영역

application영역으로 값을 선언하면 그 값은 서버내에 계속 남아있습니다. 

서버를 끄지 않는 이상 그 값은 계속 남아있죠 예를 들자면 크롬을 껏다켜도 서버가 켜져있기 때문에

그 값은 사라지지 않습니다. 우리가 지금 하는 작업으로는 톰캣을 껐다켜야지면 그 값이 사라지게 되는 것이죠

 

 

이제 선언하는 법에 대해서 알아보도록 하겠습니다.

 

영역.setAttribute("속성명", "속성값");

<% application.setAttribute("testId", "Yongmi"); %> 

이런식으로 선언하면 됩니다.

 

(형변환)영역.getAttribute("속성명")

<%= (String)application.getAttribute("testId") %>

이렇게 속성값을 출력하거나 가져올 수있습니다.

또한 만약 속성명이 없다고 해도 에러가 나오는게 아니라 null값을 출력해줍니다.

반응형