02월20일(월) Spring

하이·2023년 2월 20일
0

수업

목록 보기
26/41
post-custom-banner

Spring

개발 환경 setting

eclipse에 spring plugin을 설치
STS(Spring Tool Suite)
Spring
Spring Boot
https://dist.springsource.com/release/STS/index.html

C드라이브-tools폴더 생성-

워크스페이스 : springedu/sts-workspace


UTF-8 설정


Project 생성

Spring

사용자ID, 이름, PW를(-VO 필요) JDBC API를 이용해서(-DAO) DB에 저장+조회 하는 코드를 작성해보자

JavaBeans

JavaBeans라는 규약이 있음
: class를 작성하는 규칙 !
1. 인자가 없는 기본 생성자가 존재해야 함
2. field는 private으로 설정함
3. getter&setter가 존재해야 하고, public으로 설정되어야 함

db


-- DB(Schema) 생성
CREATE SCHEMA spring;

-- spring db 선택
USE spring;

-- table 생성
CREATE TABLE users(
	id			VARCHAR(10) PRIMARY KEY,
    password	VARCHAR(10) NOT NULL,
    name		VARCHAR(10) NOT NULL
);

SELECT * FROM USERS;

UserVO.java

package step1.vo;

// JavaBeans라는 규약이 있음
// => class를 작성하는 규칙 !
// 3가지 정도 기억해야 함
//	1. 인자가 없는 기본 생성자가 존재해야 함
//	2. field는 private으로 설정함
//	3. getter&setter가 존재해야 하고, public으로 설정되어야 함 
public class User {

	public User() {
		// TODO Auto-generated constructor stub
	}
	
	private String id;
	private String password;
	private String name;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	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;
	}
	
	
}

STEP1

UserDao.java
주석을 잘 읽으시오

package step1.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import step1.vo.User;

// Database 처리하는 코드
// 2개의 method를 작성할 거에요
// 사용자 입력, 조회
public class UserDao {
	
	public void insert(User user) throws Exception{
		
		// pure JDBC를 이용해서 DB처리를 해보자
		// 6단계 !!
		
		// 1. Driver Loading
		Class.forName("com.mysql.cj.jdbc.Driver");
		
		// 2. 연결
		String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spring?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
		String id = "root";
		String pw = "test1234";
		
		Connection con = DriverManager.getConnection(jdbcUrl, id, pw);
		
		// 3. PreparedStatement를 만들자
		String sql = "INSERT INTO users VALUES (?, ?, ?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, user.getId());
		pstmt.setString(2, user.getPassword());
		pstmt.setString(3, user.getName());

		// 4. SQL구문 실행
		int result = pstmt.executeUpdate();
		
		// 5. 결과처리
		if(result == 1) {
			System.out.println("정상적으로 입력되었어요");
		}
		
		// 6. resource 해제
		pstmt.close();
		con.close();
		
	}// insert
	
	
	
	public User select(String userId) throws Exception{
		
		// 1. Driver Loading
		Class.forName("com.mysql.cj.jdbc.Driver");
		
		// 2. 연결
		String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spring?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
		String id = "root";
		String pw = "test1234";
		
		Connection con = DriverManager.getConnection(jdbcUrl, id, pw);
		
		// 3. PreparedStatement를 만들자
		String sql = "SELECT * FROM users WHERE id = ?";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, userId);


		// 4. SQL구문 실행
		ResultSet result = pstmt.executeQuery();
		
		
		// 5. 결과처리
		result.next();
		User user = new User();
		user.setId(result.getString("id"));
		user.setPassword(result.getString("password"));
		user.setName(result.getString("name"));
		
		// 6. resource 해제
		pstmt.close();
		con.close();
		
		return user;

	} // select
}

UserDaoTest.java

package step1;

import step1.dao.UserDao;
import step1.vo.User;

public class UserDaoTest {
	
	public static void main(String[] args) throws Exception {
		// 1. 사용자를 입력해보자
		User user = new User();
		user.setId("hong");
		user.setPassword("1234");
		user.setName("홍길동");
		
		// 2. DAO 생성
		UserDao dao = new UserDao();
		
		// 3. 사용자 입력
		dao.insert(user);
		System.out.println("사용자 등록성공");
		
		// 4. 사용자 조회
		User result = dao.select("hong");
		System.out.println(result.getName()); // 홍길동
		
	}
	
}

  • code를 작성할 때 항상 염두해야하는 사항
    : 요구사항이 변화함에 따라 코드가 이런 변화에 잘 대응할 수 있도록 작성돼야 함
  • HOW?
  1. 분리
  2. 확장
    => 이 두가지를 고려한 설계를 통해 구현이 이뤄어져야 함

① 분리

: SoC(Seperation of Concern) 관심사의 분리
: 같은 concern(주제)이 한 곳에 분리되어 존재해야함. 여기저기 나타나면 곤란 !!
=> 코드를 refactoring

STEP2

package step2.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import step2.vo.User;

// Database 처리하는 코드
// 2개의 method를 작성할 거에요
// 사용자 입력, 조회
public class UserDao {

	// 중복된 코드를 method형식으로 분리시키자
	private Connection getConnection() throws Exception {
		// 1. Driver Loading
		Class.forName("com.mysql.cj.jdbc.Driver");

		// 2. 연결
		String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spring?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
		String id = "root";
		String pw = "test1234";

		Connection con = DriverManager.getConnection(jdbcUrl, id, pw);
		return con;
	}

	
	
	public void insert(User user) throws Exception {

		// pure JDBC를 이용해서 DB처리를 해보자
		// 6단계 !!

		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = getConnection();
		// 3. PreparedStatement를 만들자
		String sql = "INSERT INTO users VALUES (?, ?, ?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, user.getId());
		pstmt.setString(2, user.getPassword());
		pstmt.setString(3, user.getName());

		// 4. SQL구문 실행
		int result = pstmt.executeUpdate();

		// 5. 결과처리
		if (result == 1) {
			System.out.println("정상적으로 입력되었어요");
		}

		// 6. resource 해제
		pstmt.close();
		con.close();

	}// insert
	
	

	public User select(String userId) throws Exception {
		
		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = getConnection();

		// 3. PreparedStatement를 만들자
		String sql = "SELECT * FROM users WHERE id = ?";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, userId);

		// 4. SQL구문 실행
		ResultSet result = pstmt.executeQuery();

		// 5. 결과처리
		result.next();
		User user = new User();
		user.setId(result.getString("id"));
		user.setPassword(result.getString("password"));
		user.setName(result.getString("name"));

		// 6. resource 해제
		pstmt.close();
		con.close();

		return user;

	} // select

}

DELETE FROM USERS; 하고, 실행

② 확장

(UserDao를 확장)
: 혼자 쓰는데는 무리가 없지만, UserDao를 판매해야함
=> (.class file을 제공함 - source code는 제공 X)

HOW?
: Java에 class 기능 확장 => Inheritance
: 변할 수 있는 여지가 있는 코드(concern)를 "추상화(abstract)" 시켜야함

STEP3

UserDao.java

package step3.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import step3.vo.User;

// Database 처리하는 코드
// 2개의 method를 작성할 거에요
// 사용자 입력, 조회
public abstract class UserDao {

	// 중복된 코드를 method형식으로 분리시키자
	protected abstract Connection getConnection() throws Exception;

	public void insert(User user) throws Exception {

		// pure JDBC를 이용해서 DB처리를 해보자
		// 6단계 !!

		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = getConnection();
		// 3. PreparedStatement를 만들자
		String sql = "INSERT INTO users VALUES (?, ?, ?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, user.getId());
		pstmt.setString(2, user.getPassword());
		pstmt.setString(3, user.getName());

		// 4. SQL구문 실행
		int result = pstmt.executeUpdate();

		// 5. 결과처리
		if (result == 1) {
			System.out.println("정상적으로 입력되었어요");
		}

		// 6. resource 해제
		pstmt.close();
		con.close();

	}// insert
	
	

	public User select(String userId) throws Exception {
		
		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = getConnection();

		// 3. PreparedStatement를 만들자
		String sql = "SELECT * FROM users WHERE id = ?";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, userId);

		// 4. SQL구문 실행
		ResultSet result = pstmt.executeQuery();

		// 5. 결과처리
		result.next();
		User user = new User();
		user.setId(result.getString("id"));
		user.setPassword(result.getString("password"));
		user.setName(result.getString("name"));

		// 6. resource 해제
		pstmt.close();
		con.close();

		return user;

	} // select

}

NUserDao.java

package step3.dao;

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

public class NUserDao extends UserDao {

	@Override
	protected Connection getConnection() throws Exception {
		// UserDao를 구입한 회사에서 나름대로의 DB연결 코드를 여기에 넣어서 우리 UserDao를 확장시켜 사용 가능 !
		// 1. Driver Loading
		Class.forName("com.mysql.cj.jdbc.Driver");

		// 2. 연결
		String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spring?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
		String id = "root";
		String pw = "test1234";

		Connection con = DriverManager.getConnection(jdbcUrl, id, pw);
		return con;
	}
}
package step3;

import step3.dao.NUserDao;
import step3.dao.UserDao;
import step3.vo.User;

public class UserDaoTest {
	
	public static void main(String[] args) throws Exception {
		// 1. 사용자를 입력해보자
		User user = new User();
		user.setId("hong");
		user.setPassword("1234");
		user.setName("홍길동");
		
		// 2. DAO 생성
		UserDao dao = new NUserDao();
		
		// 3. 사용자 입력
		dao.insert(user);
		System.out.println("사용자 등록성공");
		
		// 4. 사용자 조회
		User result = dao.select("hong");
		System.out.println(result.getName()); // 홍길동
		
	}
	
}

상속관계에 있어서 UserDao가 있고, 얘를 상속 받아서 NUserDao getConnection() -> 객체 생성
: 추상화시켜서 직접 생성하지 X
: 하위 class -> NUserDao getConnection() -> 직접 객체 생성
=> 구체적인 객체 생성 방법을 하위 class에서 결정하는 Design pattern : Factory Method Pattern

확장 - Inheritance(상속)
단점
① Java single Inheritance(단일 상속)만을 지원
② 상속은 class가 tightly coupled 됨

-> 그럼 Inheritacne를 사용하지 않고 확장성을 가지려면 UserDao를 어떻게 만들어야하나요?
: 분리를 통해 확실하게 두개의 class로 분리

step4

  • 별도의 class로 분리 !

SimpleMakeConnection.java

package step4.dao;

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

public class SimpleMakeConnection {
	
	// 별도의 class로 분리시킴
	public Connection getConnection() throws Exception {
		// 1. Driver Loading
		Class.forName("com.mysql.cj.jdbc.Driver");

		// 2. 연결
		String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spring?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
		String id = "root";
		String pw = "test1234";

		Connection con = DriverManager.getConnection(jdbcUrl, id, pw);
		return con;
	}
	
}

UserDao.java

package step4.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import step4.vo.User;



// Database 처리하는 코드
// 2개의 method를 작성할 거에요
// 사용자 입력, 조회
public class UserDao {

	SimpleMakeConnection simpleMakeConnection;
	
	public UserDao() {
		// 객체를 만들고 위의 자기 필드에 갖다 박음(?)
		simpleMakeConnection = new SimpleMakeConnection();
	}
	
	public void insert(User user) throws Exception {

		// pure JDBC를 이용해서 DB처리를 해보자
		// 6단계 !!

		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = simpleMakeConnection.getConnection();
		// 3. PreparedStatement를 만들자
		String sql = "INSERT INTO users VALUES (?, ?, ?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, user.getId());
		pstmt.setString(2, user.getPassword());
		pstmt.setString(3, user.getName());

		// 4. SQL구문 실행
		int result = pstmt.executeUpdate();

		// 5. 결과처리
		if (result == 1) {
			System.out.println("정상적으로 입력되었어요");
		}

		// 6. resource 해제
		pstmt.close();
		con.close();

	}// insert
	
	

	public User select(String userId) throws Exception {
		
		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = simpleMakeConnection.getConnection();

		// 3. PreparedStatement를 만들자
		String sql = "SELECT * FROM users WHERE id = ?";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, userId);

		// 4. SQL구문 실행
		ResultSet result = pstmt.executeQuery();

		// 5. 결과처리
		result.next();
		User user = new User();
		user.setId(result.getString("id"));
		user.setPassword(result.getString("password"));
		user.setName(result.getString("name"));

		// 6. resource 해제
		pstmt.close();
		con.close();

		return user;

	} // select

}
package step4;

import step4.dao.UserDao;
import step4.vo.User;

public class UserDaoTest {
	
	public static void main(String[] args) throws Exception {
		// 1. 사용자를 입력해보자
		User user = new User();
		user.setId("hong");
		user.setPassword("1234");
		user.setName("홍길동");
		
		// 2. DAO 생성
		UserDao dao = new UserDao();
		
		// 3. 사용자 입력
		dao.insert(user);
		System.out.println("사용자 등록성공");
		
		// 4. 사용자 조회
		User result = dao.select("hong");
		System.out.println(result.getName()); // 홍길동
		
	}
	
}

=> 결과만 보면, 확장성을 확보할 수 없었음
: 현재 UserDAO는 연결 정보를 가져오는 클래스에 대해 너무 상세히 알고 있기 때문 (class이름을 명시하고 있음)
: Tightly Coupled 되어 있음 -> 이 문제를 해결 해야함 -> Interface

Step5

  • ConnectionMaker.interface 생성

인터페이스를 통한 오버라이딩을 해서..바꿀 수 있음

before
UserDao class <-> SimpleMakeConnection class

After
userDao -> interface -> connectionMaker class

ConnectionMaker.interface

package step5.dao;

import java.sql.Connection;

public interface ConnectionMaker {
	
	Connection getConnection() throws Exception;
	
}

UserDao.java

package step5.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import step5.vo.User;



// Database 처리하는 코드
// 2개의 method를 작성할 거에요
// 사용자 입력, 조회
public class UserDao {

	// 클래스이름, 	필드명
	ConnectionMaker Connectionmaker;
	
	public UserDao() {
		// 객체를 만들고 위의 자기 필드에 갖다 박음(?)
		Connectionmaker = new SimpleMakeConnection();
	}
	
	public void insert(User user) throws Exception {

		// pure JDBC를 이용해서 DB처리를 해보자
		// 6단계 !!

		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = Connectionmaker.getConnection();
		// 3. PreparedStatement를 만들자
		String sql = "INSERT INTO users VALUES (?, ?, ?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, user.getId());
		pstmt.setString(2, user.getPassword());
		pstmt.setString(3, user.getName());

		// 4. SQL구문 실행
		int result = pstmt.executeUpdate();

		// 5. 결과처리
		if (result == 1) {
			System.out.println("정상적으로 입력되었어요");
		}

		// 6. resource 해제
		pstmt.close();
		con.close();

	}// insert
	
	

	public User select(String userId) throws Exception {
		
		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = Connectionmaker.getConnection();

		// 3. PreparedStatement를 만들자
		String sql = "SELECT * FROM users WHERE id = ?";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, userId);

		// 4. SQL구문 실행
		ResultSet result = pstmt.executeQuery();

		// 5. 결과처리
		result.next();
		User user = new User();
		user.setId(result.getString("id"));
		user.setPassword(result.getString("password"));
		user.setName(result.getString("name"));

		// 6. resource 해제
		pstmt.close();
		con.close();

		return user;

	} // select

}

: 많이 좋아짐(interface를 통해 확정성을 확보 - but, 아직 쓸 수 있는 상태는 x
: class 안에서 다른 class 이름이 나오지 않도록 처리하고 싶음
=> UserDaoTest가 SimpleMakeConnection을 생성하면 됨

step6

UserDaoTest.java

package step6;


import step6.dao.ConnectionMaker;
import step6.dao.SimpleMakeConnection;
import step6.dao.UserDao;
import step6.vo.User;

public class UserDaoTest {
	
	public static void main(String[] args) throws Exception {
		// 1. 사용자를 입력해보자
		User user = new User();
		user.setId("hong");
		user.setPassword("1234");
		user.setName("홍길동");
		
		ConnectionMaker connectionMaker = new SimpleMakeConnection();
		
		// 2. DAO 생성
		UserDao dao = new UserDao(connectionMaker);
		
		// 3. 사용자 입력
		dao.insert(user);
		System.out.println("사용자 등록성공");
		
		// 4. 사용자 조회
		User result = dao.select("hong");
		System.out.println(result.getName()); // 홍길동
		
	}
	
}

UserDao.java

package step6.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import step6.vo.User;



// Database 처리하는 코드
// 2개의 method를 작성할 거에요
// 사용자 입력, 조회
public class UserDao {

	// 클래스이름, 	필드명
	ConnectionMaker connectionMaker;
	
	// Injection이 발생 !!
	// Injection은 생성자를 통한 주입이 있고, setter를 통한 주입이 있음
	
	public UserDao(ConnectionMaker Connectionmaker) {
			this.connectionMaker = connectionMaker;
	}
	
	public void insert(User user) throws Exception {

		// pure JDBC를 이용해서 DB처리를 해보자
		// 6단계 !!

		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = connectionMaker.getConnection();
		// 3. PreparedStatement를 만들자
		String sql = "INSERT INTO users VALUES (?, ?, ?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, user.getId());
		pstmt.setString(2, user.getPassword());
		pstmt.setString(3, user.getName());

		// 4. SQL구문 실행
		int result = pstmt.executeUpdate();

		// 5. 결과처리
		if (result == 1) {
			System.out.println("정상적으로 입력되었어요");
		}

		// 6. resource 해제
		pstmt.close();
		con.close();

	}// insert
	
	

	public User select(String userId) throws Exception {
		
		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = connectionMaker.getConnection();

		// 3. PreparedStatement를 만들자
		String sql = "SELECT * FROM users WHERE id = ?";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, userId);

		// 4. SQL구문 실행
		ResultSet result = pstmt.executeQuery();

		// 5. 결과처리
		result.next();
		User user = new User();
		user.setId(result.getString("id"));
		user.setPassword(result.getString("password"));
		user.setName(result.getString("name"));

		// 6. resource 해제
		pstmt.close();
		con.close();

		return user;

	} // select

}
package step6.dao;

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

public class SimpleMakeConnection implements ConnectionMaker {
	
	// 별도의 class로 분리시킴
	public Connection getConnection() throws Exception {
		// 1. Driver Loading
		Class.forName("com.mysql.cj.jdbc.Driver");

		// 2. 연결
		String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spring?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
		String id = "root";
		String pw = "test1234";

		Connection con = DriverManager.getConnection(jdbcUrl, id, pw);
		return con;
	}
	
}
  • Template Method pattern : 상속

  • Strategy pattern(전략 패턴)
    : 자신의 기능 context의 일부분을 interface를 통해 통째로 외부로 분리시키는 design pattern
    : 스프링에서 가장 대표적인 패턴
    : 인터페이스를 통해 외부로 빼내고, 이걸 끼워넣어서 사용하는 방식

step6예제는 Strategy pattern을 이용하고 있고, 전략 pattern을 이용하는 경우는 우리 예제처럼 전략을 주입하는 또다른 객체가 필요함(UserDaoTest처럼)


Step7

ConnectionMaker.interface

package step7.dao;

import java.sql.Connection;

public interface ConnectionMaker {
	
	Connection getConnection() throws Exception;
	
}

SimpleMakeConnection.java

package step7.dao;

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

public class SimpleMakeConnection implements ConnectionMaker {
	
	@Override
	// 별도의 class로 분리시킴
	public Connection getConnection() throws Exception {
		// 1. Driver Loading
		Class.forName("com.mysql.cj.jdbc.Driver");

		// 2. 연결
		String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/spring?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
		String id = "root";
		String pw = "test1234";

		Connection con = DriverManager.getConnection(jdbcUrl, id, pw);
		return con;
	}
	
}

UserDao.java

package step7.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import step7.vo.User;



// Database 처리하는 코드
// 2개의 method를 작성할 거에요
// 사용자 입력, 조회
public class UserDao {

	// 클래스이름, 	필드명
	ConnectionMaker connectionMaker;
	
	// Injection이 발생 !!
	// Injection은 생성자를 통한 주입이 있고, setter를 통한 주입이 있음
	
	public UserDao(ConnectionMaker connectionMaker) {
			this.connectionMaker = connectionMaker;
	}
	
	public void insert(User user) throws Exception {

		// pure JDBC를 이용해서 DB처리를 해보자
		// 6단계 !!

		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = connectionMaker.getConnection();
		// 3. PreparedStatement를 만들자
		String sql = "INSERT INTO users VALUES (?, ?, ?)";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, user.getId());
		pstmt.setString(2, user.getPassword());
		pstmt.setString(3, user.getName());

		// 4. SQL구문 실행
		int result = pstmt.executeUpdate();

		// 5. 결과처리
		if (result == 1) {
			System.out.println("정상적으로 입력되었어요");
		}

		// 6. resource 해제
		pstmt.close();
		con.close();

	}// insert
	
	

	public User select(String userId) throws Exception {
		
		// 1,2단계를 위로 빼주고

		// connection 연결
		Connection con = connectionMaker.getConnection();

		// 3. PreparedStatement를 만들자
		String sql = "SELECT * FROM users WHERE id = ?";
		PreparedStatement pstmt = con.prepareStatement(sql);
		pstmt.setString(1, userId);

		// 4. SQL구문 실행
		ResultSet result = pstmt.executeQuery();

		// 5. 결과처리
		result.next();
		User user = new User();
		user.setId(result.getString("id"));
		user.setPassword(result.getString("password"));
		user.setName(result.getString("name"));

		// 6. resource 해제
		pstmt.close();
		con.close();

		return user;

	} // select

}

DaoFactory.java

package step7;

import step7.dao.ConnectionMaker;
import step7.dao.SimpleMakeConnection;
import step7.dao.UserDao;

public class DaoFactory {

	public UserDao userDao() {
		
		UserDao dao = new UserDao(connectionMaker());

		return dao;
	}
	
	public ConnectionMaker connectionMaker() {
		return new SimpleMakeConnection();
	}
}

UserDaoTest.java

package step7;

import step7.dao.ConnectionMaker;
import step7.dao.SimpleMakeConnection;
import step7.dao.UserDao;
import step7.vo.User;


public class UserDaoTest {
	
	public static void main(String[] args) throws Exception {
		
		// 1. 사용자를 입력해보자 - 사용자 VO생성
		User user = new User();
		user.setId("hong");
		user.setPassword("1234");
		user.setName("홍길동");
		
//		ConnectionMaker connectionMaker = new SimpleMakeConnection();
//		
//		// 2. DAO 생성
//		UserDao dao = new UserDao(connectionMaker);

		UserDao dao = new DaoFactory().userDao();
		
		// 3. 사용자 입력
		dao.insert(user);
		System.out.println("사용자 등록성공");
		
		// 4. 사용자 조회
		User result = dao.select("hong");
		System.out.println(result.getName()); // 홍길동
		
	}
	
}


IoC(Inversion of Control)

: 제어의 역전
: Spring은 IoC container

앞에서 step6까지 진행한 코드를 보면, UserDaoTest -> UserDao의 기능이 정상적으로 동작하는지 확인하는 기능 !
여기에 기능이 추가됨(객체간의 Runtime 연관성) --> 분리해야함

class
① 분리(SoC)
② 확장

before
: main() 시작 -> 객체를 어떤 class에서 이용/생성할 건지 결정 -> 객체 생성 -> method 호출

  • IoC는 제어의 흐름을 거꾸로 뒤집는 현상을 지칭함
    객체는 자신이 사용할 객체를 직접 선택하지 않음. 당연히 생성도 X
  • servlet
    : class 위에 @webServlet 같은 걸 말함
  • Annotation
    : @정해져있는 키워드(Java) / @개발자가 만들 수도 있음
    이런 annotation은 주석이라고 해석되는데, 주석은 아님 -> 로직에는 영향을 주지 않음. 대신 program의 구조에 영향을 줌

Spring의 IoC

: Spring은 상당히 방대한 기능을 가지고 있음. 기능핵심을 담당하는 기능은 Bean Factory 기능 => Application Context : DaoFactory와 같은 Ioc기능을 일반화시킨 container

-> Spring이 제어권을 가지고 직접 만들고, 관계를 부여하는 객체 : Bean
: Applicaton Context는 설정 정보를 통해서 Bean을 관리 !
: 설정정보는 xml에 추가 or annotation 으로 코드에 기입

Bean

: Application Context라고 불리는 Bean Factory에서 관리하는 Java객체

Bean의 구성요소

① class
: Bean으로 등록한 Java class(full package)

② id
: Bean의 고유 식별자

③ scope
: 해당 bean의 동작 범위(방식?)
: singleton, prototype,
: request, session - web에서 주로 사용

④ constructor -arg
: Bean생성시 생성자에게 전달할 인자를 표현

⑤ property : Bean 생성시 setter에게 전달할 인자를 표현할 때 사용하는 구성요소

=> 이와 같은 내용을 기반으로 Bean을 등록하고, Bean을 singleton으로 생성해서 관리함

Bean을 등록하기 위한 방법

: 수동방법(annotation으로 알아보자)

public class MyResource {

}

: 이 class의 객체를 Bean으로 관리할 거에요
: Application Context 설정정보를 바탕으로 Bean을 관리(설정정보는 xml or annotation)
: 설정class가 있어야 한다

@Configuration
public class MyResourceConfig{
	@Bean
	// 이 클래스의 instance를 뽑아내는 method
	public MyResource getResource(){
    	return new myResource();
    }
}

Spring Container는 @configuration이 붙은 class를 Bean으로 등록
-> 해당 class를 해석해서 @Bean을 찾아 해당 method에 의해 생성되는 객체를 Bean으로 생성

profile
기록의 즐거움 😆💻
post-custom-banner

0개의 댓글