Cute Apple
본문 바로가기
개발/java

java 쇼핑몰 GUI(4)

by 미댕댕 2021. 5. 25.

step 17

1. 엑셀등록 중 하나라도 등록 실패한다면 commit을 하면안된다

  - jdbc는 pstmt.executeUpdate(); 시 자동으로 커밋이 되므로 자동으로 커시되지 않도록 con.setAutoCommit(false)로 지정해준다. 

  - 그리고 모두 등록완료되었을떄 commit 명령어를 넣는다.

 

- ProductMain.java 추가/변경 코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    public void registByExcel() {
        //유저가 선택한 엑셀파일의 경로를 구한다
        String path=null;
        if(chooser.showOpenDialog(this.getAppMain())==JFileChooser.APPROVE_OPTION) {
            File file=chooser.getSelectedFile(); //파일정보얻기
            path=file.getAbsolutePath();
        }else {
            JOptionPane.showMessageDialog(this.getAppMain(), "엑셀파일을 선택해주세요");
            return//이하 라인을 못지나가게.. 함수 호출한 곳으로 실행부를 돌려보냄
        }
        
        //1) 엑셀에 접근부터 해야한다 (즉 빨대를 꽃아야한다)
        FileInputStream fis=null;
        XSSFWorkbook workbook=null;
        PreparedStatement  pstmt=null;
        
        Connection con=this.getAppMain().getCon();
//        con.setAutoCommit(false);//자동커밋하지마라~~ 커밋은 내가 주도해서 할거야
//        con.setAutoCommit(true);//매 DML 마다 무조건 커밋해라
        
        
        try {
            con.setAutoCommit(false);
            
            fis=new FileInputStream(path);
            //이 스트림을 통해 내부데이터를 엑셀로 이해할수 있도록 해석
            //액셀파일을 처리하기 위한 객체 XSSFWorkbook
            workbook=new XSSFWorkbook(fis);
            
            XSSFSheet sheet=workbook.getSheetAt(0); //우리가 부여한 sheet 명을 이용하여 쉬트로 접근
            
            //쉬트객체를 이용해서 원하는 레코드에 접근해보자
            for (int i = 1; i < sheet.getLastRowNum(); i++) {
                XSSFRow row=sheet.getRow(i);
                
                int subcategory_id=0;
                String product_name=null;
                int price=0;
                String brand=null;
                String detail=null;
                String filename=null;
                
                
                //컬럼 수 만큼 반복
                for (int a = 0; a < row.getLastCellNum(); a++) {
                    XSSFCell cell=row.getCell(a);
                    //숫자일 경우, 문자열 경우 메서드가 틀리기 때문에 결국 자료형에 따라 조건으로 알맞는메서드 호출
                    if(a==0) {//subcategory_id
                        System.out.print(cell.getNumericCellValue());
                        subcategory_id=(int)cell.getNumericCellValue(); //double --> int
                    }else if(a==1) {
                        System.out.print(cell.getStringCellValue());
                        product_name=cell.getStringCellValue();
                    }else if(a==2) {
                        System.out.print(cell.getNumericCellValue());
                        price=(int)cell.getNumericCellValue();
                    }else if(a==3) {
                        System.out.print(cell.getStringCellValue());
                        brand=cell.getStringCellValue();
                    }else if(a==4) {
                        System.out.print(cell.getStringCellValue());
                        detail=cell.getStringCellValue();
                    }else if(a==5) {
                        System.out.print(cell.getStringCellValue());
                        filename=cell.getStringCellValue();
                    }
                }
                System.out.println();//줄바꿈
                String sql="insert into product(subcategory_id, product_name, price, brand, detail, filename)";
                sql+=" values(?,?,?,?,?,?)";
                
                
                
                pstmt=null;
                pstmt=this.getAppMain().getCon().prepareStatement(sql);
                pstmt.setInt(1, subcategory_id);
                pstmt.setString(2, product_name);
                pstmt.setInt(3, price);
                pstmt.setString(4, brand);
                pstmt.setString(5, detail);
                pstmt.setString(6, filename);
                
                //쿼리실행
                pstmt.executeUpdate();
            }
 
            con.commit();//트랜잭션 확정
            JOptionPane.showMessageDialog(this.getAppMain(), "등록완료");
            getProductList();
            
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
            //이 영역이 만일DML실패에 의한 에러를 만난 이유로실행된다면 rollback
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            
        }finally {
            if(fis!=null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(pstmt!=null) {
                this.getAppMain().release(pstmt);
            }
            
            try {
                con.setAutoCommit(true);//다시 돌려놓기
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
cs

 

step 18

1. 숫자 유효성 체크
  - 컴파일 타임이 아닌 런타임시 예외처리를 해야한다. (RuntimeException)

 

<작업 결과물>

 

- ProductMain.java 추가/변경 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
        //등록버튼 리스너 연결
        bt_regist.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                //유효성 체크 통과되면 아래의 두 매서드 호출
                //숫자값을 문자로 입력할 경우 문제가 심각.. 따라서 이부분만 체크해보자
                try {
                    Integer.parseInt(t_price.getText()); // "88888" 
                    regist();
                    getProductList();
                    
                }catch(NumberFormatException nfe){
                    JOptionPane.showMessageDialog(ProductMain.this.getAppMain(), "숫자를 입력하세요");
                    t_price.setText(""); //기존 입력값 지우고
                    t_price.requestFocus();//포커스 올려놓기
                }
                
                //예외는 에러가 발생할 가능성이 있는 우려되는 코드에 대한 안전장치인데
                //지금까지는 컴파일 타임에 즉 컴파일러에 의해 무조건 처리가 강요되는 예외만 사용해왔으나
                //이제부터는 컴파일 타임이 아닌 실행시 즉 런타임시에 관여하는 예외도 있다
                //이러한 예외를 런타임예외라 하며, RuntimeException 클래스로부터 상속받은 자식들이다.
                //강요하지 않은 예외는 개발자의 선택에 의해 처리 여부를 결정하면 된다.
                //대표적인 RuntimeException ArrayIndexOutOfBoundsException
                
            }
        });
cs

 

 

 

step 19

1. 검색결과 가져오기

  - 검색시 DB에서 검색하여 값이 table에 나오도록 한다. (조인문 활용)

  - 검색어 없이 버튼 클릭하면 모든데이터가 나오게한다.

 

<작업 결과물>

 

 

- ProductMain.java 추가/변경 코드

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    //검색결과 가져오기
    public void getListBySearch() {
        String category=ch_category.getSelectedItem();
        String keyword=t_keyword.getText();
        
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        
        String sql="select product_id, sub_name, product_name, price, brand, detail,filename";
        sql+=" from subcategory s, product p";
        sql+=" where s.subcategory_id=p.subcategory_id and "+category+" like '%"+keyword+"%'";
        
//        System.out.println(sql);
        
        try {
            pstmt=this.getAppMain().getCon().prepareStatement(sql
                    , ResultSet.TYPE_SCROLL_SENSITIVE
                    , ResultSet.CONCUR_READ_ONLY);
            rs=pstmt.executeQuery();
            rs.last(); //커서를 마지막레코드로 보냄
            int total=rs.getRow();
            
            //JTable 이 참조하고 있는 records라는 이차원배열의 값을, rs를 이용하여 갱신해보자
            records=new String[total][columns.length];
            
            rs.beforeFirst(); //커서 위치 제자리로
            int index=0;
            while(rs.next()) {
                records[index][0]=Integer.toString(rs.getInt("product_id"));
                records[index][1]=rs.getString("sub_name");
                records[index][2]=rs.getString("product_name");
                records[index][3]=Integer.toString(rs.getInt("price"));
                records[index][4]=rs.getString("brand");
                records[index][5]=rs.getString("detail");
                records[index][6]=rs.getString("filename");
                index++;
            }
            table.updateUI();
            
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            this.getAppMain().release(pstmt, rs);
        }
        
    }
cs

 

 

 

step 20

1. 항목 선택시 상세보기 오른쪽에 나오게 하기

  - 3개의 테이블을 조인문을 이용하여  sql문을 작성한다.
  - StringBuffer로 처리하여 메모리 효율을 높인다.

 

<작업 결과물>

 

- ProductMain.java 추가/변경 코드

마우스 리스너 사용

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//상세보기 구현 
    public void getDetail() {
        //선택한 레코드의 product_id
        product_id=Integer.parseInt((String)table.getValueAt(table.getSelectedRow(), 0));
        
        //String immuable 특징이 있기 때문에, 즉 문자열 상수이기에 아래와 같이 sql문을 처리하면 
        //문자열상수가 5개가 생성된다, 즉 sql이 수정되는게 아니다!!!
        //따라서 좀더 메모리 효율을 생각한다면, 수정가능한 문자열처리를 해야 한다 
        StringBuffer sb = new StringBuffer();
        
        sb.append("select product_id,top_name, sub_name, product_name, price, brand, detail,filename");
        sb.append(" from topcategory t, subcategory s, product p");
        sb.append(" where t.topcategory_id=s.topcategory_id and");
        sb.append(" s.subcategory_id = p.subcategory_id and ");
        sb.append(" product_id="+product_id);
        
//        System.out.println(sb.toString());
        
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        
        try {
            pstmt=this.getAppMain().getCon().prepareStatement(sb.toString());
            rs=pstmt.executeQuery(); //select 실행 후 결과 받기 !!!
            
            if(rs.next()) { //레코드가 있다면..
                //우측 영역에 채워넣기!!!
                t_top.setText(rs.getString("top_name"));
                t_sub.setText(rs.getString("sub_name"));
                t_product_name2.setText(rs.getString("product_name"));
                t_price2.setText(Integer.toString(rs.getInt("price")));
                t_brand2.setText(rs.getString("brand"));
                t_detail2.setText(rs.getString("detail"));
                del_file= rs.getString("filename");
                
                //우측 켄버스에 이미지 나오게!!!
                image2=kit.getImage("C:\\koreaIT\\javaworkspace\\ShoppingApp\\data\\"+rs.getString("filename"));
                can2.repaint();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            this.getAppMain().release(pstmt, rs);
        }
    }
cs

 

 

step 21

1. 선택한 항목을 삭제한다

 

<작업 결과물>

 

 

- ProductMain.java 추가/변경 코드

 

 

 

step 22

1. 테이블 클릭시 값이 변경되고 DB에서도 변경되게 하자

  - isCellEditable 메서드를 이용하여 true/false로 조절한다.
  - sql을 작성하여 DB에서 수정되도록 한다.

<작업 결과물>

 

- ProductMain.java 추가/변경 코드

 

 

 

 

step 23

1. 로그인폼과 회원가입폼 디자인

 

<작업 파일>

<작업 결과물>

 

 

 

 

- AppMain.java 추가/변경 코드

 

배열 크기를 7로 변경

- JoinForm.java 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class JoinForm extends Page{
    JPanel p_container; //BorderLayout
    JPanel p_center; //form
    JPanel p_south; //버튼 영역
    JLabel la_id, la_pass, la_name;
    JTextField t_id;
    JPasswordField t_pass;
    JTextField t_name;
    JButton bt_login, bt_join;
   
    public JoinForm(AppMain appMain) {
        super(appMain);
      
      //생성
        p_container = new JPanel();
        p_center = new JPanel();
        p_south = new JPanel();
        la_id = new JLabel("ID");
        la_pass = new JLabel("Password");
        la_name = new JLabel("Name");
        t_id = new JTextField();
        t_pass = new JPasswordField();
        t_name = new JTextField();
        bt_login = new JButton("Login");
        bt_join = new JButton("등록");
      
      //스타일 레이아웃
        p_container.setPreferredSize(new Dimension(25085));
        p_container.setLayout(new BorderLayout());
        p_center.setLayout(new GridLayout(3,2));
      
        //조립
        p_center.add(la_id);
        p_center.add(t_id);
        p_center.add(la_pass);
        p_center.add(t_pass);
        p_center.add(la_name);
        p_center.add(t_name);
 
        p_south.add(bt_login);
        p_south.add(bt_join);
      
        p_container.add(p_center);
        p_container.add(p_south, BorderLayout.SOUTH);
        
        add(p_container);
    }
}
cs

 

- LoginForm.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class LoginForm extends Page{
   JPanel p_container; //BorderLayout
   JPanel p_center; //form
   JPanel p_south; //버튼 영역
   JLabel la_id, la_pass;
   JTextField t_id;
   JPasswordField t_pass;
   JButton bt_login, bt_join;
   
   public LoginForm(AppMain appMain) {
      super(appMain);
      
      //생성
      p_container = new JPanel();
      p_center = new JPanel();
      p_south = new JPanel();
      la_id = new JLabel("ID");
      la_pass = new JLabel("Password");
      t_id = new JTextField();
      t_pass = new JPasswordField();
      bt_login = new JButton("Login");
      bt_join = new JButton("회원가입");
      
      //스타일 레이아웃
      p_container.setPreferredSize(new Dimension(25085));
      p_container.setLayout(new BorderLayout());
      p_center.setLayout(new GridLayout(2,2));
      
      //조립
      p_center.add(la_id);
      p_center.add(t_id);
      p_center.add(la_pass);
      p_center.add(t_pass);
 
      p_south.add(bt_login);
      p_south.add(bt_join);
      
      p_container.add(p_center);
      p_container.add(p_south, BorderLayout.SOUTH);
      
      add(p_container);
    }
}
cs

 

 

step 24

1. AppMain에서 로그인했는지 안했는지 확인하는 기능을 구현하자

  - 로그인을 안하면 session을 false로 변경하여 다른탭에 접근 불가능

  - 관리자로 인증을 거치지 않은 사람은 로그인페이지를 먼저 보게 함

 

 

- AppMain.java 추가 코드

 

 

actionperformed 안에있던 코드를 함수로 따로 저장
로그인 안한 상태에서는 로그인 창을 먼저 보여준다
private boolean session을 사용하기 위한 getter/setter

 

step 25

1. 로그인폼에서 회원가입 버튼 클릭시 회원가입폼으로 이동

  - 회원가입 등록 버튼 클릭시 DB연동

 

<작업 결과물>

 

- LoginForm.java 추가 코드

회원가입버튼 클릭시 회원가입 폼으로 넘어감

 

- JoinForm.java 추가 코드

 

 

 

 

 

step 26

1. 로그인시 DB에서 가입된 회원을 찾아 로그인

  - 로그인성공시 session을 true 로 변경하여 다른 탭에도 접근 가능함

 

<작업 결과물>

 

 

- LoginForm.java 추가 코드

 

반응형

'개발 > java' 카테고리의 다른 글

java 쇼핑몰 GUI(3)  (0) 2021.05.24
java 쇼핑몰 GUI(2)  (0) 2021.05.24
java 쇼핑몰 GUI (1)  (0) 2021.05.23
java Editplus / Eclipse에 .jar 추가 방법  (0) 2021.05.23
java 갤러리  (0) 2021.05.17

댓글