Java 정리 44
17 Jan 2019
Reading time ~4 minutes
Java 정리 44 - 도시락 주문 프로그램(4)
개발
-
도시락 수정 시 유효성 검증
public void modifyLunch() {
// 유효성 검증 : 도시락명, 가격, 특장점이 ""이 아닐 때, 가격은 숫자인지,
// 이미지가 변경되지 않았는지(변경 안되었다면 다시 올릴 필요가 없음),
// 변경되었다면 s_가 붙은 이미지가 존재하는 이미지인지 검증(검증 완료 후 업데이트 처리)
JTextField tfName = ldv.getJtfLunchName();
JTextField tfPrice = ldv.getJtfLunchPrice();
JTextArea taSpec = ldv.getJtaLunchSpec();
if(tfName.getText().trim().equals("")) {
tfName.setText("");
JOptionPane.showMessageDialog(ldv, "도시락명을 입력해주세요.");
tfName.requestFocus();
return;
}
if(tfPrice.getText().trim().equals("")) {
tfPrice.setText("");
JOptionPane.showMessageDialog(ldv, "도시락의 가격을 입력해주세요.");
tfPrice.requestFocus();
return;
}
if(taSpec.getText().trim().equals("")) {
taSpec.setText("");
JOptionPane.showMessageDialog(ldv, "도시락의 특장점을 입력해주세요.");
taSpec.requestFocus();
return;
}
int price = 0;
try {
price = Integer.parseInt(tfPrice.getText().trim());
} catch (NumberFormatException nfe) {
tfPrice.setText("");
JOptionPane.showMessageDialog(ldv, "도시락 가격은 숫자만 입력가능합니다.");
tfPrice.requestFocus();
return;
}
// 선택한 이미지 파일과 접두사 s_를 가진 동일한 이미지파일이 없는 경우
// ->이미지 작업이 되어있지 않은 경우. uploadImage를 사용
if (!uploadImage.equals("")) { // 이미지 변경을 수행한 경우
File tempFile = new File(uploadImage); // 큰 이미지
File smallFile = new File(tempFile.getParent()+"/s_"+tempFile.getName()); // 작은 이미지
if (!smallFile.exists()) {
JOptionPane.showMessageDialog(ldv, "선택하신 파일은 작은 이미지가 존재하지 않습니다.");
uploadImage = "";
return;
}
}
...
}
-
다이나믹 쿼리
- 조건에 따라 다른 쿼리를 작성할 때 쓰임
StringBuilder updateLunch = new StringBuilder();
updateLunch
.append("UPDATE LUNCH ")
.append("SET LUNCH_NAME=?, PRICE=?, SPEC=? ");
if (!luvo.getImg().equals("")) { // 이미지명이 변경되었다면 이미지 업데이트
updateLunch.append(", IMG=? ");
}
updateLunch.append("WHERE LUNCH_CODE=?");
pstmt = con.prepareStatement(updateLunch.toString());
pstmt.setString(1, luvo.getLunchName());
pstmt.setInt(2, luvo.getPrice());
pstmt.setString(3, luvo.getSpec());
if (!luvo.getImg().equals("")) {
pstmt.setString(4, luvo.getImg());
pstmt.setString(5, luvo.getLunchCode());
} else {
pstmt.setString(4, luvo.getLunchCode());
}
// 위 pstmt에 값을 넣는 코드는 이렇게 줄일 수 있다.
int index = 4;
if (!luvo.getImg().equals("")) {
pstmt.setString(index++, luvo.getImg());
}
pstmt.setString(index, luvo.getLunchCode());
- 중복된 기능을 하는 method들은 utility 패키지를 새로 만들어서 같이 모아 관리하는게 좋음
- 예를 들어 AddController와 DetailController 둘 다 사용된 uploadImg 메소드
public void uploadImg(File file) throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// 큰 이미지 업로드
fis = new FileInputStream(file);
byte[] readData = new byte[512];
int len = 0;
String uploadPath = "C:/Users/owner/youngRepositories/SSangYoung/dev/workspace/lunch_prj/src/kr/co/sist/lunch/admin/img/";
fos = new FileOutputStream(new File(uploadPath+file.getName()));
while((len = fis.read(readData)) != -1) {
fos.write(readData, 0, len);
fos.flush();
}
fis.close();
fos.close();
// 작은 이미지 업로드
fis = new FileInputStream(file.getParent()+"/s_"+file.getName());
len = 0;
fos = new FileOutputStream(new File(uploadPath+"s_"+file.getName()));
while((len = fis.read(readData)) != -1) {
fos.write(readData, 0, len);
fos.flush();
}
} finally {
if (fis != null) { fis.close(); }
if (fos != null) { fos.close(); }
}
}
- 정산을 위한 쿼리작성
-- 다음과 같은 결과를 보여주는 쿼리를 작성하시오
-- 포크칠리, L_00000001, 총 판매수량 4, 총액 18000
-- 돈가스, L_00000002, 총 판매수량 1, 총액 3800
-- 내가 짠 쿼리
SELECT l.lunch_name, l.lunch_code, quan, o.quan*l.price total
FROM (SELECT lunch_code, sum(quan) quan
FROM ordering
GROUP BY lunch_code) o, lunch l
WHERE o.lunch_code = l.lunch_code;
-- 강사님이 짜신 쿼리
SELECT l.lunch_name, l.lunch_code, sum(o.quan) total, sum(o.quan)*l.price price
FROM lunch l, ordering o
WHERE o.lunch_code = l.lunch_code
AND TO_CHAR(o.order_date, 'yyyy-mm-dd') = TO_CHAR(TO_DATE('2019-1-15', 'yyyy-mm-dd'), 'yyyy-mm-dd')
GROUP BY l.lunch_code, l.lunch_name, l.price
ORDER BY l.lunch_code;
- 자바에서 ‘2019-1-1’형태로 바인드변수가 들어가도 함수를 통해 ‘2019-01-01’형태로 바뀌어야 한다..
- 따라서 아래와 같은 오라클 함수를 사용하여 형식을 맞춰준다.
"TO_CHAR(TO_DATE(?, 'yyyy-mm-dd'), 'yyyy-mm-dd')"
// ?가 바인드 변수로 '2019-1-1'이 들어가도 '2019-01-01'로 바뀜
- DB클라이언트에서 쿼리 실행 확인 후 (다 짠 후) 자바에 적용
- 적용 시 미리 얖 뒤로 공백을 주고 붙여서 사용한다.
- 자바에선 쿼리 끝에 ‘;’를 꼭 빼야 에러가 안남!
selectCalc
.append(" SELECT l.lunch_name, l.lunch_code, sum(o.quan) total, sum(o.quan)*l.price price ")
.append(" FROM lunch l, ordering o ")
.append(" WHERE o.lunch_code = l.lunch_code ")
.append(" AND TO_CHAR(o.order_date, 'yyyy-mm-dd') = TO_CHAR(TO_DATE(?, 'yyyy-mm-dd'), 'yyyy-mm-dd') ")
.append(" GROUP BY l.lunch_code, l.lunch_name, l.price ")
.append(" ORDER BY l.lunch_code; ");
- Swing 탭 클릭 이벤트 처리
@Override
public void mouseClicked(MouseEvent me) {
if (me.getSource() == lmv.getJtb()) { // 탭에서 클릭이 발생했을 때만
if (lmv.getJtb().getSelectedIndex() == 1) { // 처음 탭에서 이벤트 발생
System.out.println("------"); // 수행할 내용
}
}
}
- 마우스 우클릭 처리
@Override
public void mouseClicked(MouseEvent me) {
if (me.getSource() == lmv.getJtOrder() && me.getButton() == MouseEvent.BUTTON3) {
System.out.println("우클릭");
}
}
- 벡터를 이용하여 DefaultTableModel에 값 넣기
OrderVO ovo = null;
Vector<Object> vec = null;
for(int i=0; i<list.size(); i++) {
ovo = list.get(i);
vec = new Vector<Object>();
vec.add(new Integer(i+1));
vec.add(ovo.getOrderNum());
vec.add(ovo.getLunchCode());
vec.add(ovo.getLunchName());
vec.add(ovo.getOrderName());
vec.add(new Integer(ovo.getQuan()));
vec.add(new Integer(ovo.getPrice()));
vec.add(ovo.getOrderDate());
vec.add(ovo.getPhone());
vec.add(ovo.getIpAddress());
vec.add(ovo.getStatus());
dtmOrder.addRow(vec);
}
- 우클릭 시 메뉴 컴포넌트를 구현할 땐 JPopupMenu와 JMenuItem을 사용
if (me.getSource() == lmv.getJtOrder() && me.getButton() == MouseEvent.BUTTON3) {
JPopupMenu jp = lmv.getJpOrderMenu();
jp.setLocation(me.getXOnScreen(), me.getYOnScreen());
jp.setVisible(true);
} else {
JPopupMenu jp = lmv.getJpOrderMenu();
jp.setVisible(false);
}
-
우클릭은 클릭이 아님
- 따라서 테이블에서 우클릭하면 getSelectRow()를 사용할 수 없는 문제가 발생
- 마우스 포인터가 클릭되면 테이블에서 클릭한 행을 선택하는 코드
int r = jt.rowAtPoint(me.getPoint()); // jt는 JTable, me는 MouseEvent
if (r >= 0 && r < jt.getRowCount()) {
jt.setRowSelectionInterval(r, r); // 선택된 행 사이를 선택
} else {
jt.clearSelection();
}