1.1.1 User
package springbook.user.domain;
public class User {
String id;
String name;
String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
/*
사용자 정보를 저장할 때는 자바빈 규약을 따르는 오브젝트를 이용하면 편리하다.
사용자 정보를 저장할 User 클래스를 만든다.
id, name, password 세 개의 프로퍼티를 가진 User클래스
*/
User 오브젝트가 담긴 정보가 실제로 보관될 DB의 테이블 생성하기
필드명 | 타입 | 설정 |
Id | VARCHAR(10) | Primary key |
Name | VARCHAR(20) | Not Null |
Password | VARCHAR(20) | Not Null |
특정 DB에 종속적이지 않으므로 사용하기 편한 DB를 이용해도 좋다라고 책이 적혀있어서 일단 Mysql 8버전으로 진행하려고 한다. 버전 문제가 발생하면 사용해본적 없는 Docker에 Mysql 5.1버전을 적재시켜서 사용해 봐야겠다.
![](https://blog.kakaocdn.net/dn/b7GLwi/btrR2skBgym/0N2w5SvWUs0lo6WYPmB76k/img.png)
![](https://blog.kakaocdn.net/dn/dPCJA4/btrR30NUORc/yaD5KB1nE6yXhqJmXZZ8f0/img.png)
CREATE DATABASE IF NOT EXISTS 'springbook'
USE 'springbook'
create table users {
id varchar(10) primary key,
name varchar(20 not null,
password varchar(10) not null
}
위 쿼리문을 사용해 users 테이블을 생성하였다.
자바빈
디폴트 생성자와 프로퍼티 관례를 따라 만들어진 오브젝트
디폴트 생성자 : 파라미터가 없는 디폴트 생성자를 갖고 있어야한다. 툴이나 프레임워크에서 리플렉션을 이용해 오브젝트를 생성하기 때문에 필요하다.
프로퍼티: 자바빈이 노출하는 이름을 가진 속성을 프로퍼티라고 한다. 프로퍼티는 set으로 시작하는 수정자 메소드(setter)와 get으로 시작하는 접근자 메소드(getter)를 이용해 수정 또는 조회할 수 있다.
1.1.2 UserDao
사용자 정보를 DB에 넣고 관리할 수 있는 DAO 클래스를 만들어보자.
일단 사용자를 생성, 아이디로 사용자 정보를 읽어오는 두 개의 메소드를 먼저 만들어보자.
JDBC 이용을 위한 작업의 일반적인 순서
- DB 연결을 위한 Connection을 가져온다.
- SQL을 담은 Statement(또는 PreparedStatement)를 만든다.
- 만들어진 Statement를 실행한다.
- 조회의 경우 SQL 쿼리의 실행 결과를 ResultSet으로 받아서 정보를 저장할 오브젝트에 옮겨준다.
- 작업 중에 생성된 Connection, Statement, ResultSet 같은 리소스는 작업을 마친 후 반드시 닫아준다.
- JDBC API가 만들어내는 예외(exception)를 잡아서 직접 처리하거나, throws를 선언해서 예외가 발생시 메소드 밖으로 던지게 한다.
JDBC를 이용한 등록과 조회 기능이 있는 UserDao 클래스
package springbook.user.domain;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDao {
// DB 관련 상수
/*
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost/springbook?serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false";
private static final String USER = "spring";
private static final String PASSWORD = "book";
*/
public void add(User user) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false", "spring", "book");
PreparedStatement ps = c.prepareStatement("insert into users(id, name, password) values(?,?,?)");
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
ps.executeUpdate();
ps.close();
c.close();
}
public User get(String id) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false", "spring", "book");
PreparedStatement ps = c.prepareStatement("select * from users where id = ?");
ps.setString(1, id);
ResultSet rs = ps.executeQuery();
rs.next();
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
rs.close();
ps.close();
c.close();
return user;
}
}
1.1.3 main()을 이용한 DAO 테스트 코드
클래스 동작 확인을 위해 일반적으로 웹 어플리케이션을 만들어 서버에 배치, 웹 브라우저를 통해 DAO 기능을 사용해보는 것이 일반적이나 배보다 배꼽이 더 크다.
그래서 main() 메서드를 활용하여 DAO의 코드를 테스트 해보자.
만들어진 코드의 기능을 검증하고 할 때 사용할 수 있는 가장 간단한 방법은 오브젝트 스스로 자신을 검증하도록 만들어 주는 것이다.
모든 클래스에는 자신을 엔트리 포인트로 설정해 직접 실행이 가능하게 해주는 스태틱 메소드 main()이 있지 않은가.
main 메소드를 만들고 그 안에서 UserDao의 오브젝트를 생성해 add()와 get() 메소드를 검증해보자.
1. User 오브젝트 생성 및 프로퍼티에 값을 넣고 add() 메소드를 이용하여 DB에 등록
2. get() 메소드를 사용해 DB에 저장된 결과를 가져와 확인
리스트 1-3 테스트용 main() 메소드
package springbook.user.domain;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDao {
// DB 관련 상수
/*
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost/springbook?serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false";
private static final String USER = "spring";
private static final String PASSWORD = "book";
*/
public static void main(String[] args) throws ClassNotFoundException, SQLException {
UserDao dao = new UserDao();
User user = new User();
user.setId("whiteship");
user.setName("백기선");
user.setPassword("married");
dao.add(user);
System.out.println(user.getId() + " 등록 성공");
User user2 = dao.get(user.getId());
System.out.println(user2.getName());
System.out.println(user2.getPassword());
System.out.println(user2.getId());
}
public void add(User user) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false", "spring", "book");
PreparedStatement ps = c.prepareStatement("insert into users(id, name, password) values(?,?,?)");
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
ps.executeUpdate();
ps.close();
c.close();
}
public User get(String id) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?serverTimezone=Asia/Seoul&useSSL=false&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false", "spring", "book");
PreparedStatement ps = c.prepareStatement("select * from users where id = ?");
ps.setString(1, id);
ResultSet rs = ps.executeQuery();
rs.next();
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
rs.close();
ps.close();
c.close();
return user;
}
}
https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.21
오랜만에 src에 java build path로 external library를 직접 걸어줘서 사용한다.
GRANT ALL PRIVILESGES ON *.* TO spring@localhost IDENTIFIED BY 'book with grant option;
위 구문이 버전문제 때문인지 먹히지 않아 아래와 같이 유저를 선언했다.
create user 'spring'@'localhost' identified by 'book';
grant all privileges on *.* to 'spring'@'localhost';
FLUSH PRIVILEGES;
실행결과는
whiteship 등록 성공
백기선
married
whiteship
![](https://blog.kakaocdn.net/dn/bpxlWS/btrSpmo6oRe/uZuQ6qHbLiOZ9ikJty4UOK/img.png)
이 UserDao 클래스 코드에는 여러가지 문제가 있다. 실제 프로젝트에서 이렇게 짜면 쫓겨나지 않을까 한심한 코드이다.이제 이 문제 많은 초난감 DAO코드를 객체지향 기술의 원리에 충실한 멋진 스프링 스타일 코드로 개선해보자.그런데 이 코드는 돌아가니까 사실 괜찮은 코드가 아닐까? 잘 돌아가는 코드를 고치는 이유는? 코드를 개선했을때 장점은?당장, 미래에 주는 이득은? 객체지향 설계의 원칙과는 무슨 상관이 있을까?스프링을 공부한다는 건 이런 문제 제기와 의문에 대한 답을 찾아나가는 과정이다.스프링을 이용해 개발자 스스로가 만들어내는 것이지, 스프링이 주는것이 아니다.
'BackEnd > Spring & Springboot Study' 카테고리의 다른 글
[토비의 스프링] 1.3 DAO의 확장 (0) | 2022.11.29 |
---|---|
[토비의 스프링] 1.2 DAO의 분리 (0) | 2022.11.28 |
[토비의 스프링] 토비의 스프링 프로젝트 생성 (0) | 2022.11.22 |
[토비의 스프링] 토비의 스프링 - 스프링을 효과적으로 익히기 위한 세 가지 (0) | 2022.11.22 |
[토비의 스프링] 토비의 스프링 시작하기 (0) | 2022.11.22 |