241220 TIL

2024. 12. 20. 16:55·TIL

JDBC

  • 자바 프로그램내에서 SQL문을 실행하기 위한 자바 API
  • JAVA는 표준 인터페이스인 JDBC API를 제공
  • 데이터베이스 벤더, 또는 기타 써드파티에서는 JDBC 인터페이스를 구현한 드라이버 (driver)를 제공
  • java.sql패키지를 보면 대부분이 interface로 되어 있음
    • 이를 실제로 구현하는 것은 DBMS를 만든 회사

JDBC 드라이버 설치-build.gradle

dependencies {
    implementation group: 'com.mysql', name: 'mysql-connector-j', version: '8.3.0'

}

maven,gradle이 없었으면 드라이버(라이브러리)를 하나 씩 찾아서 다운로드 해서 사용해야 함

JDBC 사용

import java.sql.*;

//드라이버 로드 (예전 버전은 필요. 8 버전에선 필요없다.)
Class.forName( "com.mysql.cj.jdbc.Driver" );

//Connection 얻기
String dburl = "jdbc:mysql://localhost/dbName";
Connection con = DriverManager.getConnection ( dburl, ID, PWD );

 

insert

public class InsertTest {
    public static void main(String[] args) {
        //1.선언
        Connection conn =null;
        PreparedStatement ps =null;
        //Statement객체와 다르게 값을 바인딩 해줌 , 값이 바뀔 때마다 문장을 새로 번역 할 필요가 없어 성능이 좋음
        try {
        String url="jdbc:mysql://localhost:3306/socott";
        String user="like";
        String password="lion";

        int deptno=90;
        String sql="insert into dept(deptno,dname,loc) values (?,?,?)";
        try {
            //Class.forName("com.mysql.cj.jdbc.Driver"); //드라이버 로딩(객체 생성)
            //3.접속 (Connection)
            conn= DriverManager.getConnection(url, user, password);
            //4.sql작성(Statement 객체 이용)
            ps=conn.prepareStatement(sql);
            //?에 해당하는 값을 바인딩 해줄 필요가 있다
            ps.setInt(1, deptno);
            ps.setString(2,"교육부");
            ps.setString(3, "일산");
            //5.실행
            int count=ps.executeUpdate();
            //6.결과 얻기
            System.out.println(count+"건 입력했습니다");

        }catch (Exception e){
            System.out.println(e);

        }finally {
            //2.닫는다
            if(ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if ((conn!=null)){
                try {
                    conn.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }
}

 

update

public class UpdateTest {
    public static void main(String[] args) {
        Connection conn =null;
        PreparedStatement ps =null;
        String url="jdbc:mysql://localhost:3306/socott";
        String user="like";
        String password="lion";
        String sql="update dept set dname=? where deptno=?";

        try {
            conn = DriverManager.getConnection(url, user, password);
            ps=conn.prepareStatement(sql);

            ps.setString(1, "마케팅");
            ps.setInt(2, 90);

            int count=ps.executeUpdate();

            System.out.println(count+"건 수정했어요");

        } catch (SQLException e) {
            System.out.println(e);
        }

    }
}

 

delete

public class DeleteTest {
    public static void main(String[] args) {
        String url= "jdbc:mysql://localhost:3306/socott";
        String user = "like";
        String password = "lion";
        String sql = "delete from dept where deptno=?";

        try(
                //1.접속
                Connection conn = DriverManager.getConnection(url,user,password);
                //2. sql문작성
                PreparedStatement ps = conn.prepareStatement(sql);
        ){

            ps.setInt(1, 80);
            //3. 실행!!
            int count = ps.executeUpdate();
            System.out.println(count + " 건 삭제했습니다.");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

 

select

//기본키 검색으로 한 행만 조회 할 때
public class SelectTest {
    public static void main(String[] args) {
        //1. 선언
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null; //결과를 얻어오는 객체 
        //조건에 맞는 데이터 1권조회   와   여러건 조회 !!
        String sql = "select deptno, dname, loc from dept where deptno=?";
        try{
            //3. 접속
            conn = DBUtil.getConnection();
            //4. 쿼리 작성
            ps = conn.prepareStatement(sql);
            ps.setInt(1,200);
            //5. 쿼리실행
            rs = ps.executeQuery();
            //6. 결과 얻어오기!!
            if(rs.next()){ // 실행할 행 있다면(한줄 씩 행을 가져옴) 
                System.out.println(rs.getInt(1));
                System.out.println(rs.getString("dname"));
                System.out.println(rs.getString(3));
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            //2.닫는코드
            DBUtil.close(conn,ps,rs);
        }
    }
}
//전체 테이블을 조회할 때 
public class SelectManyTest {
    public static void main(String[] args) {
        //1. 선언
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        //조건에 맞는 데이터 1권조회   와   여러건 조회 !!
        String sql = "select deptno, dname, loc from dept";
        try{
            //3. 접속
            conn = DBUtil.getConnection();
            //4. 쿼리 작성
            ps = conn.prepareStatement(sql);
            //5. 쿼리실행
            rs = ps.executeQuery();
            //6. 결과 얻어오기!!
            while(rs.next()){ //행이 있을 때까지 
                System.out.println(rs.getInt(1));
                System.out.println(rs.getString("dname"));
                System.out.println(rs.getString(3));
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            //2.닫는코드
            DBUtil.close(conn,ps,rs);
        }
    }
}

 

기능  Statement  PreparedStatement  CallableStatement
SQL 매개변수화 없음 예 (? 플레이스홀더) 예 (입력 및 출력 매개변수)
사전 컴파일 없음 예 예
보안 적절히 처리하지 않으면 SQL 인젝션에 취약 SQL 인젝션 방지 SQL 인젝션 방지
사용 사례 단순하고 정적인 SQL 쿼리 매개변수가 있는 반복 쿼리 저장 프로시저 실행
성능 반복 실행 시 비효율적 반복 실행 시 효율적 저장 프로시저 복잡도에 따라 다름
유연성 동적 쿼리에 덜 유연 동적 매개변수에 더 유연 저장 프로시저에 특화됨

DAO (Data Access Object)

  • 데이터베이스와 같은 영속성 저장소에 접근하는 로직을 캡슐화하여 비즈니스 로직과 분리하는 디자인 패턴
public class DeptDAO {
    // 기본 CRUD

    //insert -- c
    //dept 테이블에 데이터를 한건 입력하는 메소드
    public boolean addDept(DeptDTO deptDTO){
        //1.객체 선언
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        String sql="insert into dept(deptno,dname,loc) values (?,?,?)";
        try {
             connection=DBUtil.getConnection();
             preparedStatement=connection.prepareStatement(sql);
             preparedStatement.setInt(1,deptDTO.getDeptno());
             preparedStatement.setString(2, deptDTO.getDname());
             preparedStatement.setString(3, deptDTO.getLoc());

             int count=preparedStatement.executeUpdate();

             if(count==1){
                 return true;
             }else {
                 return false;
             }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //2. 선언한 객체 닫기
            DBUtil.close(connection,preparedStatement);
        }

    }
    //update -- u
    public int updateDept(DeptDTO deptDTO){
        //1.객체 선언
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        String sql="update dept set dname=? where deptno=?";
        try {
            connection=DBUtil.getConnection();
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1, deptDTO.getDname());
            preparedStatement.setInt(2, deptDTO.getDeptno());

            int count=preparedStatement.executeUpdate();

            return count;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //2. 선언한 객체 닫기
            DBUtil.close(connection,preparedStatement);
        }

    }

    //delete -- d
    public void deleteDept(int deptno){
        //1.객체 선언
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        String sql="delete from dept where deptno=?";
        try {
            connection=DBUtil.getConnection();
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setInt(1,deptno);

            int count=preparedStatement.executeUpdate();

            System.out.println(count + " 건 삭제했습니다.");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //2. 선언한 객체 닫기
            DBUtil.close(connection,preparedStatement);
        }

    }
    //여러건 조회
    public List<DeptDTO> getDeptList(){
        List<DeptDTO> deptList = new ArrayList<>();

        //선언
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            conn = DBUtil.getConnection();
            ps = conn.prepareStatement("select deptno,dname,loc from dept");
            rs = ps.executeQuery();
            while (rs.next()){
                DeptDTO deptDTO = new DeptDTO();
                deptDTO.setDeptno(rs.getInt(1));
                deptDTO.setDname(rs.getString(2));
                deptDTO.setLoc(rs.getString(3));

                deptList.add(deptDTO);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            DBUtil.close(conn,ps,rs);
        }

        return deptList;
    }

    //1건 조회
    public DeptDTO getDept(int deptno){
        DeptDTO deptDTO = new DeptDTO();
        //선언
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        String sql = "select deptno, dname, loc from dept where deptno=?";
        try{
            conn = DBUtil.getConnection();
            ps = conn.prepareStatement(sql);
            ps.setInt(1, deptno);
            rs = ps.executeQuery();
            if(rs.next()){
                deptDTO.setDeptno(rs.getInt("deptno"));
                deptDTO.setDname(rs.getString("dname"));
                deptDTO.setLoc(rs.getString("loc"));
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            DBUtil.close(conn,ps,rs);
        }
        return deptDTO;
    }
}

DTO (Data Transfer Object)

  • 계층 간에 데이터를 전송하기 위해 사용하는 객체로, 주로 네트워크를 통해 데이터를 전송하거나, 애플리케이션의 여러 계층 간에 데이터를 전달할 때 사용
  • 값을 가지고 다닐 목적을 사용하는 객체
public class DeptDTO {
    private int deptno;
    private String dname;
    private String loc;

    public DeptDTO() {
    }

    public DeptDTO(int deptno, String dname, String loc) {
        this.deptno=deptno;
        this.dname=dname;
        this.loc=loc;
    }

    public int getDeptno() {
        return deptno;
    }

    public void setDeptno(int deptno) {
        this.deptno = deptno;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }

    @Override
    public String toString() {
        return "DeptDTO{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\\'' +
                ", loc='" + loc + '\\'' +
                '}';
    }
}

 

DBUtil

DB접속과 종료 메서드를 static으로 호출하여 간편하게 쓸 수 있음

public class DBUtil {
    //DB 접속
    public static Connection getConnection() throws SQLException {
        String url="jdbc:mysql://localhost:3306/socott";
        String user="like";
        String password="lion";
        Connection conn = DriverManager.getConnection(url, user, password);
        return conn;
    }
    public static Connection getConnection(String user,String password) throws SQLException {
        String url="jdbc:mysql://localhost:3306/socott";

        Connection conn = DriverManager.getConnection(url, user, password);
        return conn;
    }
    //close
    public static void close(Connection connection)  {
        if(connection!=null)
        try {
            connection.close();
        } catch (SQLException e) {
            System.out.println(e);
        }
    }
    public static void close(Connection connection, PreparedStatement preparedStatement)  {
        if(preparedStatement!=null)
        try {
            preparedStatement.close();
        } catch (SQLException e) {
            System.out.println(e);
        }
        close(connection);
    }
    public static void close(Connection conn, PreparedStatement ps, ResultSet rs){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        close(conn,ps);
    }
}

 

사용예제

public class DeptDaoUser {
    public static void main(String[] args) {
        DeptDAO deptDAO=new DeptDAO();

        DeptDTO deptDTO=new DeptDTO();
        deptDTO.setDeptno(110);
        deptDTO.setDname("Test 부서");
        deptDTO.setLoc("판교");

        //Insert
        boolean result=deptDAO.addDept(deptDTO);

        if(result=true){
            System.out.println("성공");
        }else{
            System.out.println("실패");
        }

        deptDTO.setDeptno(110);
        deptDTO.setDname("그냥 부서");
        //update
        int count=deptDAO.updateDept(deptDTO);
        System.out.println(count+"건을 업데이트 했습니다");*/

        //delete
        deptDAO.deleteDept(110);

        //select
        List<DeptDTO> list =  deptDAO.getDeptList();
        for(DeptDTO dto : list){
            System.out.println(dto);
        }
    }
}

try-with-resources

  • 자원을 자동으로 관리하고 닫아주는 기능을 제공
  • finally안에서 접속을 close해줄 필요 없음
try (자원 선언) {
    // 자원을 사용하는 코드
} catch (예외 처리) {
    // 예외 처리 코드
}

MYSQL 락

  • 트랜잭션이 데이터를 처리할 때 다른 트랜잭션의 접근을 제어하기 위해 사용
  • 쿼리 문을 처리(커밋&롤백) 할 때 까지 같은 쿼리 문을 실행 할 수 없음
  • 데이터 무결성 유지
-- 트랜잭션 1
START TRANSACTION;
SELECT * FROM users WHERE id = 1 FOR UPDATE;

-- 트랜잭션 2
START TRANSACTION;
SELECT * FROM users WHERE id = 1 FOR UPDATE;
-- 트랜잭션 2는 트랜잭션 1이 커밋하거나 롤백할 때까지 대기

'TIL' 카테고리의 다른 글

241223 TIL  (6) 2024.12.24
241224 TIL  (3) 2024.12.24
241219 TIL  (1) 2024.12.19
241218 [멋쟁이사자처럼 부트캠프 TIL 회고] Back-End school  (2) 2024.12.18
241217 [멋쟁이사자처럼 부트캠프 TIL 회고] Back-End school  (1) 2024.12.17
'TIL' 카테고리의 다른 글
  • 241223 TIL
  • 241224 TIL
  • 241219 TIL
  • 241218 [멋쟁이사자처럼 부트캠프 TIL 회고] Back-End school
Jiyuuuuun
Jiyuuuuun
  • Jiyuuuuun
    Hello, World!
    Jiyuuuuun
  • 전체
    오늘
    어제
    • 분류 전체보기 (112)
      • TIL (56)
      • CS (17)
        • Network (4)
        • Algorithm (10)
      • JAVA (5)
      • Project (10)
        • HakPle (3)
        • JUSEYO (4)
      • Spring (2)
      • C (3)
      • C++ (16)
      • Snags (2)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Docker
    back-end
    JDBC
    react
    CSS
    my_favorite_place
    springboot
    JPA
    db
    Kubernetes
    nginx
    SQL
    HTML
    node.js
    java
    멋쟁이사자처럼
    juseyo
    hakple
    javascript
    front-end
    부트캠프
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Jiyuuuuun
241220 TIL
상단으로

티스토리툴바