Dev/Java

JDBC 처음부터 끝까지 사용해 보기(proj-Bookmall)-2

OK-가자 2021. 10. 7. 18:11

 

https://github.com/stpn94/mariadb-practices/tree/master/jdbc-practices/src/main/java/bookmall
- bookmall VO DAO TEST 들이 있는 git 주소
https://github.com/stpn94/mariadb-practices/tree/master/jdbc-practices
이거는 SQL TEST한것과 워크벤치로만든 ERD가 있다.

 

 

 

JDBC

필자는 maven을 써서 프로젝트를 만들었다.

pom.xml에 디펜던시를 추가했다.

<dependencies>
    <dependency>
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
        <version>2.7.2</version>
    </dependency>
</dependencies>

JUnit을 사용해서 TEST 안해서
test패키지않에 main으로 test 한다.

요구사항

  1. 회원 리스트 – 2명
    • 출력은 이름, 번호, 이메일, 비번
  2. 카테고리 리스트 – 3개
    • 번호, 이름
  3. 상품리스트 – 3개
    • 제목, 서적
  4. 카트 리스트 – 2개
    • 도서 제목, 수량, 가격
  5. 주문 리스트 – 1개
    • 주문 번호, 주문자(이름or이메일 ), 결제금액
  6. 주문 도서 리스트 – 2개
    • 도서번호, 도서제목, 수량

위의 사항을 출력하기위해
insert와 select만 하면 된다.

모델링 한 것은 계속 보면서 해야한다.

VO를 만들어 보자

book.vo

public class BookVo {

    private int no;            //insert 하기위해
    private String title;    //insert 하기위해
    private int price;      //insert 하기위해 
    private int categoryNo; //insert 하기위해

데이터 Vo는 DB에 sql을 날리기위해 객체를 담아두는 변수이다.

위의 테이블과 비교하면서 VO를 만들어야 한다.

잘못 만들면 수정해야하고 심각하면 다시 DB를 짜야하기때문에 꼭

뭐를 할때 뭐가 필요한지 생각하면서 만들자.

참조 클레스를 써도 되는데 안쓰는걸 추천한다.

cart.vo

public class CartVo {
    private int bookNo;          //insert
0    private int memberNo;        //insert
    private int quantity;        //insert

    private String memberName;   //select
    private String bookTitle;    //select
    private int price;             //select

cart 테이블에는 book테이블과 연결된 book_no member테블과 연결괸 member_no 그리고 quantity(수량)이 있다.

테이블에는 속성이 3개밖에 없는데
VO의 멤버는 왜 이렇게 많을까?

다른 테이블과 연결(조인)되어 있어서, 다른 테이블의 속성을 담을 변수를 만들어 준 것이다.

setter,getter,tostring,기본생성자,사용할 생성자 만들어주자

Vo는 위 부분만 봐도 만들수 있을거 같다. 나머지는 git 확인 바란다.

DAO를 만들어 보자

Data Access Object = DB에 접극하는 객체 이다.
DAO는 많으니까 대표적으로 하나만 보자

public class OrderDao {

    private Connection getConnection() throws SQLException {
        //JDBC에서 제공해 주는 Connection은 말그대로 DB와 연결하는 역활이다.
        Connection conn = null;
        try {
            // 아래부분은 DB 연결을 위해 설정해야하는 부분이다.
            Class.forName("org.mariadb.jdbc.Driver");
            // "jdbc:mysql://local/(DB이름)?charset=utf8"
            String url = "jdbc:mysql://local/bookmall?charset=utf8";
            // getConnection(url, (DB이름), (DB비밀번호))
            conn = DriverManager.getConnection(url, "bookmall", "bookmall");
            System.out.println("ok:");
        } catch (ClassNotFoundException e) {
            System.out.println("드라이버 로딩 실패:" + e);
        } 
        // 위에정보를 담은 커넥셔 conn을 return
        return conn;
    }






    // 주문 목록 조회
        public List<OrderVo> findAllOrders() {
            // 쿼리 결과를 리스트 형식으로 result에 담아둔다. 나중에 리스트 안에꺼는 빼내서 보면 되니까.
            List<OrderVo> result = new ArrayList<>();

            // DB와 연결할 커넥션 선언
            Connection conn = null;
            // PreparedStatement 말그대로 준비 상태 이다. pstmt에 sql을 담는다
            PreparedStatement pstmt = null;
            // ResultSet rs안에 쿼리를 실행시켜주는 executeQuery를 담는다.
            ResultSet rs = null;

            try {
                // 커넥션 가져오기
                conn = getConnection();
                // sql 작성 
                // 꼭 DB에서 잘 되는지 확인하고 가져오자
                String sql ="SELECT a.no , a.price , a.location , a.order_no , a.member_no \r\n"
                        + "from bookmall.order a  ";
                //pstmt에 담고
                pstmt = conn.prepareStatement(sql);
                // rs에 담아서 날려준다.
                rs = pstmt.executeQuery();

                // 자바 VO에 담기 작업을 할껀데 rs.next는 결과값이 없을때 까지 담는다는 의미다.
                while(rs.next()) {
                    // 1열 쿼리를 담는다
                    int no = rs.getInt(1);
                    // 2열 쿼리를 담는다
                    int price = rs.getInt(2);
                    // 3열 쿼리를 담는다
                    String location = rs.getString(3);
                    // 4열 쿼리를 담는다
                    int unit = rs.getInt(4);
                    // 5열 쿼리를 담는다
                    int orderNo = rs.getInt(5);
                    // 6열 쿼리를 담는다
                    int memberNo = rs.getInt(6);

                    // 위에 변수들에 담긴 값들을 Vo 객체안에 넣어준다.
                    OrderVo vo = new OrderVo();
                    vo.setNo(no);
                    vo.setPrice(price);
                    vo.setLocation(location);
                    vo.setUnit(unit);
                    vo.setOrderNo(orderNo);
                    vo.setMemberNo(memberNo);
                    result.add(vo);

                }
            } catch (SQLException e) {
                System.out.println("error:" + e);
            } finally {
                try {
                    if(rs != null) {
                        rs.close();
                    }
                    if(pstmt != null) {
                        pstmt.close();
                    }
                    if(conn != null) {
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            return result;
        }

        //주문 추가
        public Boolean insertorders(OrderVo vo) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        boolean result = false;

        try {
            conn = getConnection();
            //주문 추가는 select문과 다르게 ?표가 들어간다.
            //쿼리문의 ?표는 사용자가 직접 넣어줄수 있다.
            String sql = "insert into bookmall.order values(null, ?, ?, ? , ?)";
            pstmt = conn.prepareStatement(sql);
            //pstmt에 있는 쿼리의 1번째 물음표에 넣을값
            pstmt.setInt(1, vo.getPrice());
            //pstmt에 있는 쿼리의 2번째 물음표에 넣을값
            pstmt.setString(2, vo.getLocation());
            //pstmt에 있는 쿼리의 3번째 물음표에 넣을값
            pstmt.setInt(3, vo.getOrderNo());
            //pstmt에 있는 쿼리의 4번째 물음표에 넣을값
            pstmt.setInt(4, vo.getMemberNo());

            int count = pstmt.executeUpdate();
            result = count == 1;

        } catch (SQLException e) {
            System.out.println("error:" + e);
        } finally {
            try {
                // 자원정리(clean-up)
                if(pstmt != null) {
                    pstmt.close();
                }
                if(conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return result;
    }    
}

정말 별거 없지만 노가다 이다. 언젠가 배울 Mybatis에서 좀더 편하게 한다고 하니, 조금만 참자

Test 한번 해보자
BookDaoTest.class

public static void main(String[] args) {
        insertTest();
        findAllTest();

    }

    public static void findAllTest() {
        List<OrderVo> list = new OrderDao().findAll();
        for (OrderVo vo : list) {
            System.out.println(vo);
        }
    }

    public static void insertTest() {
        OrderVo vo = new OrderVo();
        vo.setPrice(10000);
        vo.setAddress("서울특별시");
        vo.setMemberNo(1);
        new OrderDao().insert(vo);
        vo.setPrice(20000);
        vo.setAddress("광주광역시");
        vo.setMemberNo(2);
        new OrderDao().insert(vo);
    }
  • 실행 결과 잘 나온다.
  • DB에 잘 추가된다.
  • 그럼 된거다.
  • 다른 DAO도 이렇게 만들면 된다.