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 설정
사용자ID, 이름, PW를(-VO 필요) JDBC API를 이용해서(-DAO) DB에 저장+조회 하는 코드를 작성해보자
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;
}
}
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?
- 분리
- 확장
=> 이 두가지를 고려한 설계를 통해 구현이 이뤄어져야 함
: SoC(Seperation of Concern) 관심사의 분리
: 같은 concern(주제)이 한 곳에 분리되어 존재해야함. 여기저기 나타나면 곤란 !!
=> 코드를 refactoring
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)" 시켜야함
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로 분리
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
인터페이스를 통한 오버라이딩을 해서..바꿀 수 있음
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을 생성하면 됨
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처럼)
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()); // 홍길동
}
}
: 제어의 역전
: Spring은 IoC container
앞에서 step6까지 진행한 코드를 보면, UserDaoTest -> UserDao의 기능이 정상적으로 동작하는지 확인하는 기능 !
여기에 기능이 추가됨(객체간의 Runtime 연관성) --> 분리해야함
class
① 분리(SoC)
② 확장
before
: main() 시작 -> 객체를 어떤 class에서 이용/생성할 건지 결정 -> 객체 생성 -> method 호출
- servlet
: class 위에 @webServlet 같은 걸 말함- Annotation
: @정해져있는 키워드(Java) / @개발자가 만들 수도 있음
이런 annotation은 주석이라고 해석되는데, 주석은 아님 -> 로직에는 영향을 주지 않음. 대신 program의 구조에 영향을 줌
: Spring은 상당히 방대한 기능을 가지고 있음. 기능핵심을 담당하는 기능은 Bean Factory 기능 => Application Context : DaoFactory와 같은 Ioc기능을 일반화시킨 container
-> Spring이 제어권을 가지고 직접 만들고, 관계를 부여하는 객체 : Bean
: Applicaton Context는 설정 정보를 통해서 Bean을 관리 !
: 설정정보는 xml
에 추가 or annotation
으로 코드에 기입
: Application Context라고 불리는 Bean Factory에서 관리하는 Java객체
① class
: Bean으로 등록한 Java class(full package)
② id
: Bean의 고유 식별자
③ scope
: 해당 bean의 동작 범위(방식?)
: singleton, prototype,
: request, session - web에서 주로 사용
④ constructor -arg
: Bean생성시 생성자에게 전달할 인자를 표현
⑤ property : Bean 생성시 setter에게 전달할 인자를 표현할 때 사용하는 구성요소
=> 이와 같은 내용을 기반으로 Bean을 등록하고, Bean을 singleton으로 생성해서 관리함
: 수동방법(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으로 생성