[JDBC] 2021.01.04. day_48 ResultSetMetaData, java swing으로 view생성하고, 테이블의 컬럼 정보 조회하기

2021. 1. 4. 14:05Web_Back-end/JDBC

 

◎ ResultSetMetaData

DataDictionary를 사용하지 않고 조회하는 테이블컬럼정보를 얻을 때 사용하는 객체

연결 가능한 모든 DBMS에서 정보를 얻을 수 있다

사용법

1. select 쿼리를 실행한 ResultSet에서 ResultSetMetaData 를 얻는다
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");

//1. select 쿼리를 실행한 ResultSet에서 ResultSetMetaData 를 얻는다
ResultSetMetaData rsmd = rs.getMetaData();

 

※ ResultSetMetaData method 사용하기

컬럼의 갯수
int count = rsmd.getColumnCount();
컬럼명 : 인덱스는 1번부터 시작
int index = 1; // 인덱스 1부터 시작

String columnName = rsmd.getColumnName(index);
컬럼데이터형
String columntypeName = rsmd.getColumnTypeName(1)
컬럼의 크기
int precision = rsmd.getPrecision(1)
null 허용 : 0 = null, 1 = not null
int flag = rsmd.isNullable(index); //0 Null , 1 not Null

※ java swing으로 view생성하고, 테이블의 컬럼 정보 조회하기

Class Diagram

▽▼ View ▼▽

package day0104;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

@SuppressWarnings("serial")
public class ColumnView extends JFrame {

	private JComboBox<String> jcbTableName;
	private DefaultComboBoxModel<String> dcbmTableName;
	private JTable jtabColumnView;
	private DefaultTableModel dtmColumnView;
	private JButton jbtnSearch;

	public ColumnView() {
		super("테이블 컬럼 조회");
		// Model이 먼저 만들어져야한다
		dcbmTableName = new DefaultComboBoxModel<String>();
		jcbTableName = new JComboBox<String>(dcbmTableName);

		String[] columnNames = { "번호", "컬럼명", "데이터형", "크기", "null허용" };
		dtmColumnView = new DefaultTableModel(columnNames, 6);
		jtabColumnView = new JTable(dtmColumnView);

		// 컬럼의 넓이 설정
		jtabColumnView.getColumnModel().getColumn(0).setPreferredWidth(40);
		jtabColumnView.getColumnModel().getColumn(1).setPreferredWidth(270);
		jtabColumnView.getColumnModel().getColumn(2).setPreferredWidth(140);
		jtabColumnView.getColumnModel().getColumn(3).setPreferredWidth(100);
		jtabColumnView.getColumnModel().getColumn(4).setPreferredWidth(100);
		// 컬럼의 높이 설정
		jtabColumnView.setRowHeight(30);
		jbtnSearch = new JButton("조회");

		JPanel jpNorth = new JPanel();
		jpNorth.add(new JLabel("테이블명"));
		jpNorth.add(jcbTableName);
		jpNorth.add(jbtnSearch);

		JScrollPane jspCenter = new JScrollPane(jtabColumnView);
		add("North", jpNorth);
		add("Center", jspCenter);

		// 이벤트처리
		ColumnViewEvt cvEvt = new ColumnViewEvt(this);
		jbtnSearch.addActionListener(cvEvt);

		setBounds(100, 100, 650, 500);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public JComboBox<String> getJcbTableName() {
		return jcbTableName;
	}

	public DefaultComboBoxModel<String> getDcbmTableName() {
		return dcbmTableName;
	}

	public JTable getJtabColumnView() {
		return jtabColumnView;
	}

	public DefaultTableModel getDtmColumnView() {
		return dtmColumnView;
	}

	public JButton getJbtnSearch() {
		return jbtnSearch;
	}

	public static void main(String[] args) {

		new ColumnView();

	}

}

▽▼ Event▼▽

package day0104;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

public class ColumnViewEvt implements ActionListener {

	private ColumnView cv;

	public ColumnViewEvt(ColumnView cv) {
		this.cv = cv;
		setAllTableName();
	}

	public void setAllTableName() {
		// JComboBox에 값을 설정하는 Model 객체를 얻는다
		DefaultComboBoxModel<String> dcbm = cv.getDcbmTableName();
		// DBMS에서 조회된 테이블명을 얻는다
		ColumnViewDAO cvDAO = ColumnViewDAO.getInstance();
		try {
			List<String> list = cvDAO.selectAllTableName();
			// Model객체에 조회된 결과를 설정
			for (String tname : list) {
				dcbm.addElement(tname);
			}

		} catch (SQLException e) {
			JOptionPane.showMessageDialog(cv, "죄송합니다\n테이블명을 조회할 수 없습니다");
			e.printStackTrace();
		}
	};

	public void setTableColumn(String tname) {
		try {
			// 입력된 테이블에 컬럼 정보를 조회하여
			List<ColumnVO> columnData = ColumnViewDAO.getInstance().selectOneTable(tname);

			// Model에 설정
			DefaultTableModel dtm = cv.getDtmColumnView();
			dtm.setRowCount(0); // 행을 조회해서, 보여주기 전에 초기화한다

			// 행의 값을 설정하기 위한 Object[] 선언
			Object[] rowData = null;
			ColumnVO cv = null;
			for (int i = 0; i < columnData.size(); i++) {
				cv = columnData.get(i);
				rowData = new Object[5];
				rowData[0] = Integer.valueOf(i + 1);
				rowData[1] = cv.getColumnName();
				rowData[2] = cv.getDataType();
				rowData[3] = cv.getPrecision();
				rowData[4] = (cv.getAboutNull()==0? "not null":"null");
				
				
				dtm.addRow(rowData);
			}

		} catch (SQLException e) {
			JOptionPane.showMessageDialog(cv, tname + "죄송합니다\n테이블의 정보를 조회할 수 없습니다");
			e.printStackTrace();
		}

	}

	@Override
	public void actionPerformed(ActionEvent ae) {
		String tableName = cv.getDcbmTableName().getElementAt(cv.getJcbTableName().getSelectedIndex());
		switch (JOptionPane.showConfirmDialog(cv, tableName + "테이블을 조회하시겠습니까?")) {
		case JOptionPane.OK_OPTION:
			setTableColumn(tableName);
			break;
		}

	}

}

▽▼ VO▼▽

package day0104;

public class ColumnVO {

	private String columnName, dataType;
	private int precision, aboutNull;

	public ColumnVO() {
		super();
	}
	
	
	public ColumnVO(String columnName, String dataType, int precision, int aboutNull) {
		super();
		this.columnName = columnName;
		this.dataType = dataType;
		this.precision = precision;
		this.aboutNull = aboutNull;
	}

	public int getAboutNull() {
		return aboutNull;
	}

	public void setAboutNull(int aboutNull) {
		this.aboutNull = aboutNull;
	}

	public String getColumnName() {
		return columnName;
	}

	public void setColumnName(String columnName) {
		this.columnName = columnName;
	}

	public String getDataType() {
		return dataType;
	}

	public void setDataType(String dataType) {
		this.dataType = dataType;
	}

	public int getPrecision() {
		return precision;
	}

	public void setPrecision(int precision) {
		this.precision = precision;
	}


	@Override
	public String toString() {
		return "ColumnVO [columnName=" + columnName + ", dataType=" + dataType + ", precision=" + precision
				+ ", aboutNull=" + aboutNull + "]";
	}


}

▽▼ DAO▼▽

package day0104;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ColumnViewDAO {

	private static ColumnViewDAO cvDAO;

	private ColumnViewDAO() {

	}

	public static ColumnViewDAO getInstance() {
		if (cvDAO == null) {
			cvDAO = new ColumnViewDAO();
		}

		return cvDAO;
	}

	private Connection getConnection() throws SQLException {
		Connection con = null;
		// 1. 드라이버로딩
		try {
			Class.forName("oracle.jdbc.OracleDriver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 2. 커넥션얻기
		String url = "jdbc:oracle:thin:@localhost:1521:orcl";
		String id = "scott";
		String pass = "tiger";

		con = DriverManager.getConnection(url, id, pass);

		return con;
	}

	public List<String> selectAllTableName() throws SQLException {
		List<String> list = new ArrayList<String>();

		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			// 1. 드라이버로딩
			// 2. 커넥션얻기
			con = getConnection();
			// 3. 쿼리문 생성 객체 얻기
			String selectTable = "select tname from tab";
			pstmt = con.prepareStatement(selectTable);
			// 4. 바인드변수에 값넣기

			// 5. 쿼리문 실행 후 결과얻기
			rs = pstmt.executeQuery();
			while (rs.next()) {
				list.add(rs.getString("tname"));
			}

		} finally {
			// 6. 연결끊기
			if (rs != null) {
				rs.close();
			}
			if (pstmt != null) {
				pstmt.close();
			}
			if (con != null) {
				con.close();
			}
		}
		return list;
	}

	public List<ColumnVO> selectOneTable(String tableName) throws SQLException {
		List<ColumnVO> list = new ArrayList<ColumnVO>();

		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		try {
			// 1. 드라이버로딩
			// 2. 커넥션얻기
			con = getConnection();
			// 3. 쿼리문 생성객체 얻기
//			String selectTable = "select * from ?";// 테이블명을 바인드변수(?)로 처리 ==> 안됨
			StringBuilder selectTable = new StringBuilder();
			// 테이블명이나 컬럼명은 바인드변수로 사용하지 않고 쿼리문에 직접 넣어 코딩
			selectTable.append("select * from ").append(tableName);

			pstmt = con.prepareStatement(selectTable.toString());

			// 4. 바인드변수에 값 넣기
//			pstmt.setString(1, tableName); // 바인드변수에 테이블명 넣기

			// 5. 쿼리문 수행 후 결과얻기
			rs = pstmt.executeQuery();

			/////////////////////////// ResultSetMetaDate 의 사용
			ResultSetMetaData rsmd = rs.getMetaData();
//			System.out.println(rsmd.getColumnCount());
//			System.out.println(rsmd.getColumnName(1));
//			System.out.println(rsmd.getColumnTypeName(1));
//			System.out.println(rsmd.getPrecision(1));
//			System.out.println(rsmd.isNullable(1));
			ColumnVO cVO = null;

			for (int i = 1; i <= rsmd.getColumnCount(); i++) {
//				System.out.println(rsmd.getColumnName(i) + " / " + rsmd.getColumnTypeName(i) + " / " + rsmd.getPrecision(i)
//				+ " / " + (rsmd.isNullable(i) == 0? "not null":"null"));

				cVO = new ColumnVO(rsmd.getColumnName(i), rsmd.getColumnTypeName(i), rsmd.getPrecision(i), rsmd.isNullable(i));
				list.add(cVO);
			}

		} finally {
			// 6. 연결끊기
			if (rs != null) {
				rs.close();
			}
			if (pstmt != null) {
				pstmt.close();
			}
			if (con != null) {
				con.close();
			}
		}

		return list;
	}

}

실행 후, emp table 조회화면