Java

Java 기초(Thread, Singleton, DB 연결)- AWS 풀스택 과정 56일차

awspspgh 2024. 10. 15. 18:15
목차
1. Thread
2. Signeton
3. DB 연결

 

1. Thread

▣ Thread01

package day11;

public class Thread01 {

	public static void main(String[] args) {
		/* Thread(쓰레드) : 실제 작업을 수행하는 단위
		 * - 프로그램이 실행되면 OS로부터 메모리를 할당 받아 process의 상태 됨
		 * - 하나의 process는 하나 이상의 Thread를 가지게 됨
		 * - Thread는 실제 작업을 수행하는 단위이다
		 * - thread가 실제 CPU가 작업을 처리하는 단위
		 * - multi-thread : 여러 개의 thread가 동시에 수행되는 프로그램
		 * - CPU는 시간을 잘게 쪼개서 threa를 번갈아 수행함. (시분할 처리)
		 * - thread는 각자 자신만의 작업공간을 가짐 (context)
		 * - 각 thread는 공유하는 자원이 있을 수 있음. (자바에서는 static instance)
		 * - 여러 thread가 공유하는 자원을 사용하려고 경쟁이 발생함
		 * - 경쟁이 발생하는 구역 critical section(임계영역)
		 * - 임계영역에서 교착상태(deadlock)가 발생하지 않도록 동기화(순차적 수행) 구현하여 오류를 막음.
		 */
		/* Thread를 구현하는 2가지 방법
		 * 1. Thread 클래스를 상속하여 만들기
		 * 2. Runnable 인터페이스를 구현하여 만들기
		 * 자바는 다중상속을 허용하지 않기 때문에, 다른 클래스를 상속 중이라면 2번으로 구현
		 */
		// 현재 실행중인 스레드 이름
		System.out.println(Thread.currentThread().getName());
		
		MyThread th = new MyThread();
		th.start(); // run() 메서드 실행
		
		MyThread th2 = new MyThread();
		th2.start();
		
		System.out.println("thread end~!!");
	}
}
	
	class MyThread extends Thread{
		// 반드시 run()이라는 메서드를 구현해야 함.
		@Override
		public void run() {
			// 0 ~ 500까지 반복하여 실행하는 구문수행
			for(int i = 0; i <= 500; i++) {
				System.out.println(i + "번째 thread > " + getName());
			}
		}
	}

 

▷ 출력

출력 (1)

 

▣ Thread02

package day11;

class MyThread2 implements Runnable {

	@Override
	public void run() {
		// run은 반드시 구현해야 함
		// 0 ~ 500까지 반복하여 실행하는 구문수행
		for (int i = 0; i <= 500; i++) {
			System.out.println(i + "번째 thread > " + Thread.currentThread().getName());
		}
	}

}

public class Thread02 {

	public static void main(String[] args) {
		// 2. runnable 구현하는 방법
		// join() : 동시에 여러 개의 스레드가 실행될 때 다른 스레드의 결과를
		// 참조하여 실행되어야 할 경우 join() 메서드를 사용
		// join() : try~catch 필요
		
		System.out.println(Thread.currentThread().getName());

		System.out.println("main thread start");
		
		MyThread2 th2 = new MyThread2();
		Thread th = new Thread(th2);
		th.start();
		try {
			th.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Thread th3 = new Thread(new MyThread2());
		th3.start();
		try {
			th3.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println("main thread end");
	}

}

 

▷ 출력

출력 (2)

 

▣ Thread03

package day11;

class JoinTest extends Thread{
	int start;
	int end;
	int total;

	public JoinTest(int start, int end) {
		this.start = start;
		this.end = end;
	}
	
	@Override
	public void run() {
		for(int i = start; i <= end; i++) {
			System.out.println(i);
			this.total += i;
		}
	}

}


public class Thread03 {

	public static void main(String[] args) {
		// 1 ~ 50, 51 ~ 100까지의 합을 구하는 두 개의 Thread를 생성
		// 그 결과를 확인
		// Thread.sleep() : 기다렸다가 실행
		// millisecond 단위  1초=1000
		
		// 두 개의 Thread가 실행되고 난 후
		// Thread-0 1~50까지의 합계 출력
		// Thread-1 51~100까지의 합계 출력
		// Thread-0 + Thread-1의 합계 출력
		System.out.println("main thread start");
		
		JoinTest th1 = new JoinTest(1, 50);
		JoinTest th2 = new JoinTest(51, 100);

		th1.start();		
		try {
			th1.join();
			Thread.sleep(1000);
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
		
		th2.start();
		try {
			th2.join();
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
		
		
		System.out.println("---------------------");
		System.out.println("thread1 total > " + th1.total);
		System.out.println("thread2 total > " + th2.total);
		System.out.println("thread1 + thread2 total > " + th1.total + th2.total);
	}

}

 

▷ 출력

출력 (3)

 

▣ Thread04

package day11;

class Bank{
	private int money = 20000;
	
	// 입금 : synchronized : 동기화(순차접근)
	public synchronized void saveMoney(int save) {
		int m = this.money;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.money = m + save;
	}
	
	// 출금
	public synchronized void minusMoney(int minus) {
		int m = this.money;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.money = m - minus;
	}

	public int getMoney() {
		return money;
	}

	public void setMoney(int money) {
		this.money = money;
	}
	
}

class Hong extends Thread{

	@Override
	public void run() {
		System.out.println("홍길동 입금 시작");
		Thread04.myBank.saveMoney(10000);
		System.out.println("saveMoney(1000) > " + Thread04.myBank.getMoney());
	}
	
}

class HongWife extends Thread{
	
	@Override
	public void run() {
		System.out.println("홍길동 와이프 출금 시작");
		Thread04.myBank.minusMoney(10000);
		System.out.println("minusMoney(5000) > " + Thread04.myBank.getMoney());
	}
	
}

public class Thread04 {
	// 계좌 생성 : 공유영역에 생성
	public static Bank myBank = new Bank();
	
	public static void main(String[] args) {
		Hong h = new Hong();
		h.start();
		
		HongWife hw = new HongWife();
		hw.start();
		
		/* critical section(임계영역)은 두 개 이상의 thread가
		 * 동시에 접근할 수 있는 영역 (공유영역)
		 * 동시에 여러 개의 thread가 접근하여 공유영역을 가지려고하면 문제가 생길 수 있음.
		 * 교착상태(deadlock)가 발생
		 * 한 순간에는 하나의 thread만 사용가능 : 세마포어(semaphore)
		 * 세마포어를 얻은 스레드만 접근이 가능 / 나머지는 대기상태가 됨
		 * 
		 * 동기화(순서화) : synchronized
		 * 동기화가 필요한 메서드 앞에 선언
		 */

		/* bank 클래스 생성
		 * 계좌 1개 생성 => 공유영역 (static)
		 * hong / hongwife
		 * 잔액 : 10000
		 */
	}

}

 

▷ 출력

출력 (4)

 

2. Singleton

▣ Network01

package day11;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;

public class Network01 {

	public static void main(String[] args) throws IOException {
		// 인터넷 주소의 정보를 확인
		InetAddress ip = null;
		ip = InetAddress.getByName("www.naver.com");
		System.out.println("HostAddress > " + ip.getHostAddress());
		System.out.println("HostName > " + ip.getHostName());
		System.out.println(ip.toString());

		URL url = new URL("https://view.asiae.co.kr/article/2024101410052492395?utm_source=newsstand.naver.com&utm_medium=referral&utm_campaign=bottom1");
		
		System.out.println(url.getContent());
		System.out.println(url.getAuthority());
		System.out.println(url.getDefaultPort());
		System.out.println(url.getPort());
		System.out.println(url.getHost());
		System.out.println(url.getQuery());
		System.out.println(url.getPath());
		
	}

}

 

▷ 출력

출력 (1)

 

▣ Network02

package day11;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

public class Network02 {

	public static void main(String[] args) {
		// http://www.moulian.com/
		URL url = null;
		String addr = "http://www.moulian.com/";
		BufferedReader input = null;
		String line = "";
		
		try {
			url = new URL(addr);
			input = new BufferedReader(new InputStreamReader(url.openStream()));
			
			while((line = input.readLine()) != null) {
				System.out.println(line);
			}
			input.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

 

▷ 출력

(생략)

 

▣ Singleton01

package day11;

import java.util.Calendar;

public class Singleton01 {

	public static void main(String[] args) {
		/* 디자인 패턴 : 개발자들이 개발 과정에서 하나의 패턴으로 묶어놓은 코드 조합
		 * https://refactoring.guru/ko/design-patterns/what-is-pattern
		 * 디자인 패턴 중 하나
		 * 싱글톤 : 단 1개만 존재해야하는 객체를 새엇ㅇ하여 => 공유하고자 할 떄 사용
		 */
		
		// Singeton 객체 생성
//		Singeton s = new Singeton(); // 생성자가 private라서 생성이 안 됨
		// static 메서드 / 멤버변수는 클래스명으로부터 바로 접근
		Singeton s = Singeton.getInstance();
		Singeton s1 = Singeton.getInstance();
		// 하나의 객체를 공유 (주소가 같음)
		System.out.println(s);
		System.out.println(s1);
		
		Calendar c = Calendar.getInstance();
		System.out.println(c);
		Calendar c1 = Calendar.getInstance();
		System.out.println(c1);
	}

}

class Singeton{
	
	// 단 1개만 존재하기 위해 객체의 인스턴스 생성 (공유)
	
	private static Singeton instance;
	// 생성자를 통해 객체 생성을 막기 위해 생성자를 private 설정
	private Singeton() {}
	
	// getInstance() 메서드를 사용하여 instance를 생성 리턴
	// instance가 있으면 기존 instance를 리턴
	// instance가 없으면 새로 생성해서 리턴
	public static Singeton getInstance() {
		if(instance == null) {
			instance = new Singeton();
		}
		return instance;
	}
}

 

▷ 출력

출력 (2)

 

▣ Singleton02

package day11;

class Counter{
	// 싱글톤으로 생성
	private int count;
	// 내 객체를 저장하는 멤버변수 (static)
	private static Counter instance;
	
	// 생성자 private
	private Counter() {}
	
	// 인스턴스를 1개만 생성해주는 메서드
	public static Counter getInstance() {
		if(instance == null) {
			instance = new Counter();
		}
		return instance;
	}
	
	// count가 하나 올라가는 메서드 생성 countMethod()
	public int countMethod() {
		count++;
		return this.count;
	}
}

public class Singleton02 {

	public static void main(String[] args) {
		// Counter 객체를 2개 생성하여 각각 countMethod() 호출
		// 1개의 객체가 공유되기 때문에 1개의 변수만 변화
		
		Counter c1 = Counter.getInstance();
		Counter c2 = Counter.getInstance();
		System.out.println("c1 > " + c1.countMethod());
		System.out.println("c1 > " + c1.countMethod());
		System.out.println("c1 > " + c1.countMethod());
		System.out.println("c2 > " + c2.countMethod());
		System.out.println("c2 > " + c2.countMethod());
		System.out.println("c2 > " + c2.countMethod());
	}

}

 

▷ 출력

출력 (3)

 

3. DB 연결

■ 라이브러리 다운로드

- mvnrepository에서 다운로드

(JDBC 필요 - mysql용 8.0.39버전 => 버전은 Workbench에서 왼쪽 하단의 Session에서 확인 가능)

mvnrepository

 

DB 테이블 생성 및 권한 부여 (cmd or Workbench)

DB 생성 -> 유저 생성 -> 테이블 생성

상품 정보를 담을 수 있는 DB 생성

 

mysql -uroot -p비번


유저 : javaUser
create user 'javaUser'@'localhost' identified by '비번';

DB : javadb
create database javadb;

권한 부여
grant all privileges on javadb.* to 'javaUser'@'localhost' with grant option;
flush privileges;

exit;
mysql -ujavaUser -p비번
use javadb

테이블 : product
create table product(
pno int auto_increment,
pname varchar(50) not null,
price int default 0,
regdate datetime default now(),
madeby text,
primary key(pno));

 

cmd (1)

 

cmd (2)

 

cmd (3)

 

cmd (4)

 

■ eclipse 라이브러리 추가

eclipse (1)

 

eclipse (2)

 

■ 이론

이론 (1)

 

이론 (2)

 

▣ ProductMain

package jdbc;

public class ProductMain {

	public static void main(String[] args) {
		new ProductController();

	}

}

 

▣ Product

package jdbc;

public class Product {
	// DB의 테이블과 일치하는 객체 생성
//	pno int auto_increment,
//	pname varchar(50) not null,
//	price int default 0,
//	regdate datetime default now(),
//	madeby text,
	
	private int pno; // 자동 생성
	private String pname;
	private int price;
	private String regdate;	// now()
	private String madeby;
	
	// 생성자 / getter setter / toString
	public Product() {}
	
	// 상품등록 -> pname, price, madeby
	public Product(String pname, int price, String madeby) {
		this.pname = pname;
		this.price = price;
		this.madeby = madeby;
	}
	// 상품리스트 -> pno, pname, price
	public Product(int pno, String pname, int price) {
		this.pno = pno;		
		this.pname = pname;
		this.price = price;
	}
	// 상품상세보기 -> 전부
	public Product(int pno, String pname, int price, String regdate, String madeby) {
		this.pno = pno;
		this.pname = pname;
		this.price = price;
		this.regdate = regdate;
		this.madeby = madeby;
	}
	// 상품수정 -> pname, price, madeby, pno
	public Product(String pname, int price, String madeby, int pno) {
		this.pname = pname;
		this.price = price;
		this.madeby = madeby;		
		this.pno = pno;
	}
	
	public int getPno() {
		return pno;
	}

	public void setPno(int pno) {
		this.pno = pno;
	}

	public String getPname() {
		return pname;
	}

	public void setPname(String pname) {
		this.pname = pname;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}

	public String getMadeby() {
		return madeby;
	}

	public void setMadeby(String madeby) {
		this.madeby = madeby;
	}
	
	public String print() {
		return pno + ". " + pname + "(" + price + ")";
	}
	
	@Override
	public String toString() {
		return pno + ". " + pname + "(" + price + ") / " + regdate + "["
				+ madeby + "]";
	}
	
}

 

sqlFile

-- 기록용 나중에 유저와 비번 db를 확인한 목적
create user 'javaUser'@'localhost' identified by 'mysql';
create database javadb;
grant all privileges on javadb.* to 'javaUser'@'localhost' with grant option;
flush privileges;

exit;
mysql -ujavaUser -pmysql
use javadb

create table product(
pno int auto_increment,
pname varchar(50) not null,
price int default 0,
regdate datetime default now(),
madeby text,
primary key(pno));
-- db는 수정되거나 추가되면 변경 구문을 써놓아야함

 

 ProductController

package jdbc;

import java.util.List;
import java.util.Scanner;

public class ProductController {
	/* Controller <-> Service <-> DAO <-> DB 
	 * Controller 모든 메뉴 분기 처리
	 */
	
	private Scanner scan;
	private Service svc; // 아직 없음 interface
	private boolean flag;

	public ProductController() {
		scan = new Scanner(System.in);
		svc = new ProductServiceImpl(); // service interface 구현체
		flag = true;
		printMenu();
	}

	private void printMenu() {
		while(flag) {
			System.out.println("--상품관리프로그램--");
			System.out.println("1.상품등록|2.상품목록|3.상품검색(상세보기)|4.상품수정|5.상품삭제|6.종료");
			System.out.println("menu > ");
			int menu = scan.nextInt();
			
			switch(menu) {
			case 1: register(); break;
			case 2: list(); break;
			case 3: search(); break;
			case 4: modify(); break;
			case 5: delete(); break;
			case 6: 
				flag = false;
				System.out.println("종료");
				break;
			default: System.out.println("잘못된 메뉴");
			}
		}
		
	}

	private void delete() {
		// 상품 삭제
		// 삭제할 번호(pno) isOk return
		System.out.println("검색할 번호 입력:");
		int pno = scan.nextInt();
		// 메서드 명은 상관없음. (기능과 관련있게 명명)
		// set get insert register add update modify remove delete
		int isOk = svc.delete(pno);
		System.out.println("상품삭제 > " +(isOk > 0 ? "성공" : "실패"));
	}

	private void modify() {
		// 상품 수정 : 이름, 가격, 상세내용
		System.out.println("검색할 번호 입력:");
		int pno = scan.nextInt();
		System.out.println("상품이름:");
		String name = scan.next();
		System.out.println("상품가격:");
		int price = scan.nextInt();
		scan.nextLine();
		System.out.println("상품상세내역:");
		String madeby = scan.nextLine(); // 공백포함
		
		Product p = new Product(name, price, madeby, pno);
		int isOk = svc.update(p);
		System.out.println("상품등록 > " +(isOk > 0 ? "성공" : "실패"));
	}

	private void search() {
		// 특정 상품 검색(세부 내용 madeby / regdate)
		// pno가 필요
		// select * from product where pno = ?
		// pno 값을 입력받아 매개변수로 전달 Product 객체 리턴
		System.out.println("검색할 번호 입력:");
		int pno = scan.nextInt();
		Product p = svc.getProduct(pno);
		System.out.println(p);
		
	}

	private void list() {
		// 상품 전체 리스트
		// 매개변수는 없고, 리턴 List
		// select * from product order by pno desc
		List<Product> list = svc.getList();
		// 출력
		for(Product p : list) {
			System.out.println(p.print());
		}
		
	}

	private void register() {
		// 상품등록
		System.out.println("상품이름:");
		String name = scan.next();
		System.out.println("상품가격:");
		int price = scan.nextInt();
		scan.nextLine();
		System.out.println("상품상세내역:");
		String madeby = scan.nextLine(); // 공백포함
		
		Product p = new Product(name, price, madeby);
		// service에게 p 객체 등록 요청 (메서드 작성)
		// 1 row(s) affected 0.016 sec
		// isOk = 1 (DB에 성공적으로 들어감) / isOk = 0 (실패)
		int isOk = svc.insert(p);
		System.out.println("상품등록 > " +(isOk > 0 ? "성공" : "실패"));
	}
	
}

 

Service

package jdbc;

import java.util.List;

public interface Service {

	int insert(Product p);

	List<Product> getList();

	Product getProduct(int pno);

	int update(Product p);

	int delete(int pno);
}

 

 ProductService

package jdbc;

import java.util.List;

public class ProductServiceImpl implements Service {
	/* service <-> DAO */
	// 생성자로 DAO 객체와 연결
	private DAO dao; // interface
	public ProductServiceImpl() {
		dao = new ProductDAOImpl(); // DAO 구현체
	}
	
	@Override
	public int insert(Product p) {
		// 실제 구현 영역
		System.out.println("상품등록 serviceImpl Success");
		// DAO에게 DB 저장을 요청
		// dao 요청시 메서드명은 sql구문과 비슷하게 작성하는 것이 일반적
		return dao.insert(p);
	}

	@Override
	public List<Product> getList() {
		// TODO Auto-generated method stub
		System.out.println("list serviceImpl Success");
		return dao.selectList();
	}

	@Override
	public Product getProduct(int pno) {
		System.out.println("product serviceImpl Success");
		return dao.selectProduct(pno);
	}

	@Override
	public int update(Product p) {
		System.out.println("update serviceImpl Success");
		return dao.update(p);
	}

	@Override
	public int delete(int pno) {
		System.out.println("delete serviceImpl Success");
		return dao.delete(pno);
	}

}

 

 DAO

package jdbc;

import java.util.List;

public interface DAO {

	int insert(Product p);

	List<Product> selectList();

	Product selectProduct(int pno);

	int update(Product p);

	int delete(int pno);

}

 

 ProductDAOImpl

package jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ProductDAOImpl implements DAO {
	/* DAO <-> DB
	 */
	// DB 연결객체 
	private Connection conn;
	// sql 구문을 실행시키는 기능을 가진 객체
	private PreparedStatement pst;
	// 쿼리문 저장 스트링
	private String query = "";
	
	public ProductDAOImpl() {
		// DBConnection class 생성(싱글톤) 연걸
		DatabaseConnection dbc = DatabaseConnection.getInstance();
		conn = dbc.getConnection();
	}
	
	// sql 처리
	
	@Override
	public int insert(Product p) {
		// product 객체를 등록하고, isOk를 리턴
		System.out.println("insert DAOImpl success");
		query = "insert into product(pname, price, madeby) values(?, ?, ?)";
		try {
			pst = conn.prepareStatement(query);
			// ? 반드시 순서대로 처리 (자료형을 기재) 1부터 시작
			pst.setString(1, p.getPname());
			pst.setInt(2, p.getPrice());
			pst.setString(3, p.getMadeby());
			// insert, update, delete => 처리만... (1 row(s) affected)
			// 결과의 행 수만 리턴 => executeUpdate(); int 리턴
			// select => 목록 => executeQuery(); ResultSet으로 리턴
			return pst.executeUpdate();
		} catch (SQLException e) {
			// insert error
			System.out.println("insert error");
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public List<Product> selectList() {
		// DB에서 리스트를 가져와서 리턴
		System.out.println("list DAOImpl success!!");
		query = "select * from product order by pno desc";
		List<Product> list = new ArrayList<>();
		try {
			pst = conn.prepareStatement(query);
			// select => 목록 => executeQuery(); ResultSet으로 리턴
			ResultSet rs = pst.executeQuery();
			// ResultSet => List로 변환 (pno, pname, price)
			while(rs.next()) {
				list.add(new Product(rs.getInt("pno"), rs.getString("pname"), rs.getInt("price")));
			}
			return list;
		} catch (SQLException e) {
			System.out.println("list error");
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Product selectProduct(int pno) {
		System.out.println("product DAOImpl success!!");
		query = "select * from product where pno = ?";
		try {
			pst = conn.prepareStatement(query);
			pst.setInt(1, pno);
			ResultSet rs = pst.executeQuery();
			if(rs.next()) {				
				Product p = new Product(rs.getInt("pno"), rs.getString("pname"), rs.getInt("price"), rs.getString("regdate"), rs.getString("madeby"));
				return p;
			}
		} catch (SQLException e) {
			System.out.println("product error");
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public int update(Product p) {
		System.out.println("update DAOImpl success!!");
		query = "update product set pname = ?, price = ?, madeby = ?, regdate = now() where pno = ?";
		try {
			pst = conn.prepareStatement(query);
			pst.setString(1, p.getPname());
			pst.setInt(2, p.getPrice());
			pst.setString(3, p.getMadeby());
			pst.setInt(4, p.getPno());
			return pst.executeUpdate();
		} catch (SQLException e) {
			System.out.println("update error");
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public int delete(int pno) {
		System.out.println("delete DAOImpl success!!");
		query = "delete from product where pno = ?";
		try {
			pst = conn.prepareStatement(query);
			pst.setInt(1, pno);
			return pst.executeUpdate();
		} catch (SQLException e) {
			System.out.println("delete error");
			e.printStackTrace();
		}
		return 0;
	}

}

 

 DatabaseConnection

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseConnection {
	/* DB 접속 객체
	 * DB Driver, url, user, password
	 * com.mysql.cj.jdbc.Driver
	 * jdbc:myㄴql://localhost:3306/DB명
	 */
	private static DatabaseConnection dbc = new DatabaseConnection();
	private Connection conn = null;
	
	private String jdbDriver = "com.mysql.cj.jdbc.Driver";
	private String jdbUrl = "jdbc:mysql://localhost:3306/javadb";
	
	// 생성자
	private DatabaseConnection() {
		try {
			// 드라이버를 로드하기 위한 메서드
			Class.forName(jdbDriver);
			// 연결을 위해서 url, user, password
			conn = DriverManager.getConnection(jdbUrl, "javaUser", "mysql");
		} catch (ClassNotFoundException e) {
			// 드라이버를 찾을 수 없을 경우
			System.out.println("드라이버를 찾을 수 없습니다");
			e.printStackTrace();
		} catch (SQLException e) {
			// con 연결정보가 잘못되었을 경우
			System.out.println("연결정보가 정확하지 않습니다.");
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static DatabaseConnection getInstance() {
		return dbc;
	}
	
	public Connection getConnection() {
		return conn;
	}
}

 

▷ 출력

출력 (1)