저번시간에 JFrame의 기초를 알아보았습니다. 이번시간에는 JFram에 Dao, Dto를 사용해서 DB와 연동을 해봅시다.
저번 게시글 링크 -> [JAVA] JFrame 사용해보기 #1 - 예제로 다양한 기능 알아보기
Dto와 Dao의 자세한 설명과 예제는 여기를 참고해주세요!
- [JAVA] DTO vs DAO vs VO 개념 정리
- [JAVA] JDBC 사용해보기 #3 - DTO, DAO와 같이 사용해보기 ( Select, Insert, Update, Delete )
기능
- 이름, 직책을 텍스트 필드에 적고 추가 버튼 누르면 추가
- 삭제하고싶은 내용을 클릭해서 삭제 버튼을 누르면 삭제
- 변경하고 싶은 내용을 클릭해서 변경하면 변경됨
- 일정시간마다 내용 새로고침
위 기능을 구현해봅시다!
DBConnect.java
package test.util;
import java.sql.Connection;
import java.sql.DriverManager;
/*
* 객체를 생성해서 메소드를 호출하면 Connection 객체를 리턴하는 객체를 생성할 클래스 설계하기
*/
public class DBConnect {
//Connection 객체의 참조값을 담을 필드 선언
private Connection conn;
//생성자에서 Connection 객체를 얻어오는 작업을 한다.
public DBConnect() {
try {
//오라클 드라이버 클래스 로딩(OracleDriver 클래스를 사용할 준비를 한다)
Class.forName("oracle.jdbc.driver.OracleDriver");
//접속할 DB 의 정보
String url="jdbc:oracle:thin:@localhost:1521:xe";
//DB 연결 객체의 참조값 얻어와서 필드에 담기
conn=DriverManager.getConnection(url, "scott", "tiger");
//예외가 발생하지 않고 여기까지 실행순서가 진행이되면 접속 성공이다.
System.out.println("Oracle DB 접속 성공!");
}catch(Exception e){
}
}
//Connection 객체를 리턴하는 메소드
public Connection getConn() {
return conn;
}
}
CompanyDto.java
package test.dto;
public class CompanyDto {
private int empno;
private String ename;
private String job;
private String hiredate;
public CompanyDto() {
super();
}
public CompanyDto(int empno, String ename, String job, String hiredate) {
super();
this.empno = empno;
this.ename = ename;
this.job = job;
this.hiredate = hiredate;
}
public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getHiredate() {
return hiredate;
}
public void setHiredate(String hiredate) {
this.hiredate = hiredate;
}
}
CompanyDao.java
package test.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import test.dto.CompanyDto;
import test.util.DBConnect;
public class CompanyDao {
public boolean insert(CompanyDto dto) {
//필요한 객체를 담을 지역 변수 미리 만들기
Connection conn = null;
PreparedStatement pstmt = null;
int flag = 0;
try {
//Connection 객체의 참조값 얻어오기
conn = new DBConnect().getConn();
//실행할 sql 문의 뼈대 미리 준비하기
String sql = "INSERT INTO company"
+ " (empno,ename,job,hiredate)"
+ " VALUES(company_seq.NEXTVAL,?,?,SYSDATE)";
//PreparedStatement 객체의 참조값 얻어오기
pstmt = conn.prepareStatement(sql);
//? 에 필요한값 바인딩하기
pstmt.setString(1, dto.getEname());
pstmt.setString(2, dto.getJob());
//sql 문 실행하기 (INSERT, UPDATE, DELETE)
flag = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
}
}
if (flag > 0) {
//성공
return true;
} else {
//실패
return false;
}
}
public boolean update(CompanyDto dto) {
//필요한 객체를 담을 지역 변수 미리 만들기
Connection conn = null;
PreparedStatement pstmt = null;
int flag = 0;
try {
//Connection 객체의 참조값 얻어오기
conn = new DBConnect().getConn();
//실행할 sql 문의 뼈대 미리 준비하기
String sql = "UPDATE Company"
+" SET ename=?, job=?"
+" WHERE empno=?";
//PreparedStatement 객체의 참조값 얻어오기
pstmt = conn.prepareStatement(sql);
//? 에 필요한값 바인딩하기
pstmt.setString(1, dto.getEname());
pstmt.setString(2, dto.getJob());
pstmt.setInt(3, dto.getEmpno());
//sql 문 실행하기 (INSERT, UPDATE, DELETE)
flag = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
}
}
if (flag > 0) {
//성공
return true;
} else {
//실패
return false;
}
}
public boolean delete(CompanyDto dto) {
//필요한 객체를 담을 지역 변수 미리 만들기
Connection conn = null;
PreparedStatement pstmt = null;
int flag = 0;
try {
//Connection 객체의 참조값 얻어오기
conn = new DBConnect().getConn();
//실행할 sql 문의 뼈대 미리 준비하기
String sql = "DELETE FROM Company"
+" WHERE empno=?";
//PreparedStatement 객체의 참조값 얻어오기
pstmt = conn.prepareStatement(sql);
//? 에 필요한값 바인딩하기
pstmt.setInt(1, dto.getEmpno());
//sql 문 실행하기 (INSERT, UPDATE, DELETE)
flag = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
}
}
if (flag > 0) {
//성공
return true;
} else {
//실패
return false;
}
}
public CompanyDto getData(int empno) {
//필요한 객체를 담을 지역 변수 미리 만들기
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
CompanyDto dto = null;
try {
//Connection 객체의 참조값 얻어오기
conn = new DBConnect().getConn();
//실행할 sql 문의 뼈대 미리 준비하기
String sql = "SELECT ename, job, TO_CHAR(hiredate,'YYYY.mm.dd') as hiredate"
+" FROM Company"
+ " WHERE empno = ?";
//PreparedStatement 객체의 참조값 얻어오기
pstmt = conn.prepareStatement(sql);
//? 에 필요한값 바인딩하기
pstmt.setInt(1, empno);
//select 문 수행하고 결과를 ResultSet 으로 받아오기
rs = pstmt.executeQuery();
if (rs.next()) {
//cursor 가 위치한 곳의 칼럼 데이터를 빼오기
dto = new CompanyDto();
dto.setEmpno(empno);
dto.setEname(rs.getString("ename"));
dto.setJob(rs.getString("job"));
dto.setHiredate(rs.getString("hiredate"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
}
}
return dto;
}
public List<CompanyDto> getList(){
//필요한 객체를 담을 지역 변수 미리 만들기
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<CompanyDto> list = new ArrayList<>();
try {
//Connection 객체의 참조값 얻어오기
conn = new DBConnect().getConn();
//실행할 sql 문의 뼈대 미리 준비하기
String sql = "SELECT empno, ename, job, TO_CHAR(hiredate,'YYYY.mm.dd') as hiredate"
+" FROM Company";
//PreparedStatement 객체의 참조값 얻어오기
pstmt = conn.prepareStatement(sql);
//? 에 필요한값 바인딩하기
//select 문 수행하고 결과를 ResultSet 으로 받아오기
rs = pstmt.executeQuery();
while (rs.next()) {
//cursor 가 위치한 곳의 칼럼 데이터를 빼오기
CompanyDto dto = new CompanyDto();
dto.setEmpno(rs.getInt("empno"));
dto.setEname(rs.getString("ename"));
dto.setJob(rs.getString("job"));
dto.setHiredate(rs.getString("hiredate"));
list.add(dto);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
}
}
return list;
}
}
이제 main 을 봅시다!
package test.frame;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import test.dao.CompanyDao;
import test.dto.CompanyDto;
public class CompanyFrame extends JFrame implements ActionListener, PropertyChangeListener{
JTextField inputEname,inputJob;
JTable table;
DefaultTableModel model;
List<CompanyDto> companys;
public CompanyFrame(){
setTitle("사원정보");
setSize(800, 500);
setLocation(100, 100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//BorderLayout 객체 전달하기
setLayout(new BorderLayout());
//필요한 UI 객체를 생성해서
JLabel labelName=new JLabel("이름");
JLabel labelAddr=new JLabel("직책");
inputEname=new JTextField(10);
inputJob=new JTextField(10);
JButton addBtn=new JButton("추가");
JButton deleteBtn=new JButton("삭제");
JButton refreshBtn = new JButton("새로고침");
//페널에 추가한 후
JPanel topPanel=new JPanel();
topPanel.add(labelName);
topPanel.add(inputEname);
topPanel.add(labelAddr);
topPanel.add(inputJob);
topPanel.add(addBtn);
topPanel.add(deleteBtn);
topPanel.add(refreshBtn);
//프레임의 상단에 페널을 배치한다.
add(topPanel, BorderLayout.NORTH);
//버튼에 리스너 등록
addBtn.addActionListener(this);
deleteBtn.addActionListener(this);
refreshBtn.addActionListener(this);
//버튼에 action command 설정
addBtn.setActionCommand("add");
deleteBtn.setActionCommand("delete");
refreshBtn.setActionCommand("refresh");
//표형식으로 정보를 출력하기 위한 JTable
table=new JTable();
//테이블의 칼럼명을 String[] 로 준비하기
String[] colNames= {"사원 번호", "사원 이름", "직책", "입사일"};
//테이블에 출력할 데이터를 가지고 있는 DefaultTableModel
model=new DefaultTableModel(colNames, 0) {
//인자로 전달되는 행(row), 열(column) 수정 가능 여부를 리턴하는 메소드
@Override
public boolean isCellEditable(int row, int column) {
//0번 칼럼만 수정 불가능하도록 false를 리턴해주고
if(column == 0 || column==3) {
return false;
}else {
//나머지는 모두 수정 가능하도록 true를 리턴한다.
return true;
}
}
};
//모델을 테이블에 연결
table.setModel(model);
//스크롤이 가능하도록
JScrollPane sc=new JScrollPane(table);
//프레임의 가운데에 배치
add(sc, BorderLayout.CENTER);
//테이블에 회원 목록 출력하기
showMembers();
//테이블 셀에 수정작업이 일어났는지 감시할 리스너 등록
table.addPropertyChangeListener(this);
autoRefresh();
setVisible(true);
}
public static void main(String[] args) {
new CompanyFrame();
}
public void showMembers() {
//DB 에서 회원 목록을 얻어와서
companys=new CompanyDao().getList();
for(CompanyDto tmp:companys) {
//테이블 row 에 출력할 데이터를 순서대로 담은 Object[] 객체를 준비해서
Object[] row= {tmp.getEmpno(),tmp.getEname(),tmp.getJob(),tmp.getHiredate()};
//모델에 추가한다.
model.addRow(row);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("add")) {
addAction();
}else if(e.getActionCommand().equals("delete")) {
deleteAction();
}else if(e.getActionCommand().equals("refresh")) {
model.setRowCount(0);
showMembers();
}
}
private void deleteAction() {
//선택된 row 의 인덱스를 얻어와서
int index=table.getSelectedRow();
if(index == -1)return;
//DB 에서 삭제하고
CompanyDto dto = new CompanyDto();
dto.setEmpno(companys.get(index).getEmpno());
new CompanyDao().delete(dto);
//다시 출력
model.setRowCount(0);
showMembers();
}
private void addAction() {
//1. 입력한 이름과 주소를 읽어온다.
String ename=inputEname.getText();
String job=inputJob.getText();
//2. DB 에 저장한다.
CompanyDto dto=new CompanyDto();
dto.setEname(ename);
dto.setJob(job);
//작업의 성공여부를 리턴 받는다.
boolean isSuccess=new CompanyDao().insert(dto);
if(isSuccess) {
JOptionPane.showMessageDialog(this, "저장 했습니다.");
//행의 갯수를 강제로 0 로 만들고
model.setRowCount(0);
//다시 출력하기
showMembers();
}else {
JOptionPane.showMessageDialog(this, "저장 실패!");
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("propertyChange()");
System.out.println(evt.getPropertyName());
if(evt.getPropertyName().equals("tableCellEditor")) {
//선택된 row 의 index 를 얻어와서
int index=table.getSelectedRow();
//인덱스에 해당하는 model 에서 입력된 이름과 주소를 읽어온다.
int empno=(int)model.getValueAt(index, 0); //0번째 인덱스의 번호를 읽어온다.
String ename=(String)model.getValueAt(index, 1); //1번째 인덱스의 이름을 읽어온다.
String job=(String)model.getValueAt(index, 2); //2번째 인덱스의 주소를 읽어온다.
String hiredate=(String)model.getValueAt(index, 3); //3번째 인덱스의 입사일을 읽어온다.
//DB 에 수정 반영
CompanyDto dto=new CompanyDto(empno,ename,job,hiredate);
new CompanyDao().update(dto);
}
}
//주기적으로 refresh 하는 메소드
public void autoRefresh() {
new Thread() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
model.setRowCount(0);
showMembers();
}
}
}.start();
}
}
구현 방법
- showMembers() : DB에서 회원 목록 얻어옴
- actionPerformed(ActionEvent e) : 버튼 액션을 제어함
- addAction() : 데이터를 DB에 추가, 성공하면 저장했습니다. 라는 Dialog 띄워줌
- deleteAction() : 선택한 행 데이터를 삭제
- propertyChange(PropertyChangeEvent evt) : 텍스트 변경을 감지한다. 변경되면 DB내용을 업데이트해줌 , PropertyChangeListener를 implements해주어야한다.
- autoRefresh() : 주기적으로 새로고침을 해주는 메소드
'Languages > JAVA' 카테고리의 다른 글
[JAVA] String VS StringBuilder VS StringBuffer (2) | 2022.07.20 |
---|---|
[JAVA] Thread 사용해보기 - Thread / Runnable 예제 (0) | 2021.11.17 |
[JAVA] JFrame 사용해보기 #1 - 예제로 다양한 기능 알아보기 (0) | 2021.11.16 |
[JAVA] 상속 알아보기 #2 - this, super (0) | 2021.11.15 |
[JAVA] 상속 알아보기 #1 - 기본 개념, 오버라이딩, 생성자 호출, 다형성 (0) | 2021.11.15 |