DB 연결을 위한 스키마, 테이블 생성

  • spring-db 스키마 생성
  • users 테이블 생성

CREATE TABLE `spring-db`.`users` (
  `id` VARCHAR(10) NOT NULL,
  `name` VARCHAR(20) NOT NULL,
  `password` VARCHAR(10) NOT NULL,
  PRIMARY KEY (`id`));

 

IntelliJ에서 domain Package 생성

public class User {
    private String id;
    private String name;
    private String password;

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getPassword() {
        return password;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

 

IntelliJ를 DB Client로 사용하기

접속정보에 자신의 DB 정보 넣기

 

생성했던 users 테이블 확인 가능, 쿼리 콘솔로 명령어 입력도 가능

 

📌 스팟 인스턴스로 인해 종료 후 다시 인스턴스를 생성할 경우 넣어주었던 DB 정보에서 host 주소를 변경해주어야 한다.

 

dao Package 아래 UserDao 클래스 생성

DAO란 (Data Access Object)?

데이터를 연결하는 오브젝트로 db에 쿼리를 실행하는 기능을 가지고 있다.

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;

import static java.lang.System.getenv;

public class UserDao {
   public void add() throws ClassNotFoundException, SQLException {
       Map<String, String> env = getenv();
       String dbHost = env.get("DB_HOST");
       String dbUser = env.get("DB_USER");
       String dbPassword = env.get("DB_PASSWORD");

       Class.forName("com.mysql.cj.jdbc.Driver");
       Connection conn = DriverManager.getConnection(
               dbHost, dbUser, dbPassword
       );
       // (?, ?, ?) 자리에 값을 변경할 수 있다.
       PreparedStatement pstmt = conn.prepareStatement("insert into users(id, name, password) values(?, ?, ?)");
       pstmt.setString(1, "1");
       pstmt.setString(2, "hn");
       pstmt.setString(3, "12345678");

       pstmt.executeUpdate();
       pstmt.close();
       conn.close();

   }

   public static void main(String[] args) throws SQLException, ClassNotFoundException {
       UserDao userDao = new UserDao();
       userDao.add();
   }
}

 

 

Intellij에서 DB접속 정보를 변수 처리 하기

관련 글 application.yml의 필드를 environment variable로 넘기는 법. https://krksap.tistory.com/2183 SpringBoot Intellij에서 Environment Variable을 application.yml에 넣기 application.yml에 민감 정보가 들어가는 경우 실수로 git

krksap.tistory.com

 

  • PreparedStatement : Java의 JDBC (Java Database Connectivity) API에서 SQL 쿼리를 실행할 때 사용하는 인터페이스
일반적인 Statement와 다르게 PreparedStatement는 동일한 SQL 쿼리를 반복적으로 실행하거나 사용자 입력과 같은 변수 데이터를 SQL 쿼리를 쉽게 삽입 가능하다.

 

  • getenv() : 자바의 System 클래스에 있는 정적 메소드로 현재 실행되고 있는 프로세스의 환경 변수 반환
Map<String, String> env = getenv(); -> 이 코드는 getenv() 메서드를 호출하여 모든 환경 변수(이름이 부여된 값들의 집합)를 가져오는 역할로 반환되는 Map 객체는 각 환경 변수의 이름을 키로, 해당 환경 변수의 값을 값으로 가진다.

 

실행 후 DB 확인 결과

 

  • 테이블 생성 시 id를 AI로 설정했다면 아래와 같이 수정 가능
PreparedStatement pstmt = conn.prepareStatement(
   "insert into users(name, password) values (?, ?)"
);
pstmt.setString(1, "hn");
pstmt.setString(2, "1234");

 

User를 Parameter로 받도록 수정

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;

import static java.lang.System.getenv;

public class UserDao {
   public void add(User user) throws ClassNotFoundException, SQLException {
       Map<String, String> env = getenv();
       String dbHost = env.get("DB_HOST"); //DB_HOST=jdbc:mysql://localhost:3306/spring-db
       String dbUser = env.get("DB_USER");
       String dbPassword = env.get("DB_PASSWORD");

       Class.forName("com.mysql.cj.jdbc.Driver");
       Connection conn = DriverManager.getConnection(
               dbHost, dbUser, dbPassword
       );
       PreparedStatement pstmt = conn.prepareStatement("insert into users(id, name, password) values(?, ?, ?)");
       pstmt.setString(1, user.getId());
       pstmt.setString(2, user.getName());
       pstmt.setString(3, user.getPassword());

       pstmt.executeUpdate();

       pstmt.close();
       conn.close();
   }

   public static void main(String[] args) throws SQLException, ClassNotFoundException {
       UserDao userDao = new UserDao();
       UserDao userDao = new UserDao();
       User user = new User();
       user.setId("2");
       user.setName("hn2");
       user.setPassword("1234");
       userDao.add(user);
   }
}

 

실행 후 DB 확인 결과

 

get 메소드 생성

public User get(String id) throws ClassNotFoundException, SQLException {
       Map<String, String> env = getenv();
       String dbHost = env.get("DB_HOST"); //DB_HOST=jdbc:mysql://localhost:3306/spring-db
       String dbUser = env.get("DB_USER");
       String dbPassword = env.get("DB_PASSWORD");

       Class.forName("com.mysql.cj.jdbc.Driver");
       Connection con = DriverManager.getConnection(
               dbHost, dbUser, dbPassword
       );
        PreparedStatement pstmt = con.prepareStatement("select id, name, password from users where id = ?");
        // 다 보더라도 웬만하면 다 select해서 적어주자
        pstmt.setString(1, id);

        ResultSet rs = pstmt.executeQuery();
        rs.next(); // Ctrl + Enter랑 같은거라고 보면 됨

        User user = new User();
        user.setId(rs.getString("id"));
        user.setName(rs.getString("name"));
        user.setPassword(rs.getString("password"));

        // 안닫아주면 계속 연결되어 있음
        // 물론 지금은 크게 문제가 없지만 나중에 계속 실행되어있으면 안닫아주면 connection 만 늘어남
        // 순서 중요 [{()}] <- 이런거와 비슷
        rs.close();
        pstmt.close();
        con.close();

        return user;
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
        UserDao userDao = new UserDao();
        User user = new User();
        user.setId("2");
        user.setName("hanule2");
        user.setPassword("12345");
//        userDao.add(user);

        User selectedUser = userDao.get("2");
        System.out.println(selectedUser.getId());
        System.out.println(selectedUser.getName());
        System.out.println(selectedUser.getPassword());
}

 

실행결과

 

Connection 분리

Connection 만드는 부분을 getConnection() 메소드로 분리

import com.example.tobyspring3.domain.User;
import java.sql.*;
import java.util.Map;
import static java.lang.System.getenv;

public class UserDao {
    public Connection getConnection() throws ClassNotFoundException, SQLException {
        // 커넥션 만드는 함수 생성해서 중복된 코드 작성 방지
        Map<String, String> env = getenv();
        String dbHost = env.get("DB_HOST");
        String dbUser = env.get("DB_USER");
        String dbPassword = env.get("DB_PASSWORD");
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection con =DriverManager.getConnection(
                dbHost, dbUser, dbPassword
        );
        return con;
    }
    public void add(User user) throws ClassNotFoundException, SQLException {
        Connection con = getConnection();
        PreparedStatement pstmt = con.prepareStatement("insert into users(id, name, password)" +
                "values (?, ?, ?)");
        pstmt.setString(1, user.getId());
        pstmt.setString(2, user.getName());
        pstmt.setString(3, user.getPassword());
        pstmt.executeUpdate();

        pstmt.close();
        con.close();
    }
    public User get(String id) throws ClassNotFoundException, SQLException {
        Connection con = getConnection();
        PreparedStatement pstmt = con.prepareStatement("select id, name, password from users where id = ?");
        // 다 보더라도 웬만하면 다 select해서 적어주자
        pstmt.setString(1, id);

        ResultSet rs = pstmt.executeQuery();
        rs.next(); // Ctrl + Enter랑 같은거라고 보면 됨

        User user = new User();
        user.setId(rs.getString("id"));
        user.setName(rs.getString("name"));
        user.setPassword(rs.getString("password"));

        // 안닫아주면 계속 연결되어 있음
        // 물론 지금은 크게 문제가 없지만 나중에 계속 실행되어있으면 안닫아주면 connection 만 늘어남
        // 순서 중요 [{()}] <- 이런거와 비슷
        rs.close();
        pstmt.close();
        con.close();

        return user;
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        UserDao userDao = new UserDao();
        User user = new User();
        user.setId("2");
        user.setName("hanule2");
        user.setPassword("12345");
//        userDao.add(user);

        User selectedUser = userDao.get("2");
        System.out.println(selectedUser.getId());
        System.out.println(selectedUser.getName());
        System.out.println(selectedUser.getPassword());
    }
}

 

복사했습니다!