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 추가/변경 코드
- 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(250, 85));
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(250, 85));
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 추가 코드
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 |
댓글