Java连接SqlServer读取数据并显示到JTable

Java连接SqlServer读取数据并显示到JTable

内容概述

1. Java通过SqlServer连接数据库,以下用的是与jdk1.8匹配的版本sqljdbc_7.4.1

2. 解压后将mssql-jdbc-7.4.1.jre8.jar导入项目中

3. 使用JTable可用不同的方法将查询数据封装后呈现到表格中

4. 注意解决以下异常:

java.lang.IllegalArgumentException: Cannot format given Object as a Number
java.lang.IllegalArgumentException: Cannot format given Object as a Date

这种异常在实现AbstractTableModel类并重写其中getColumnClass方法时会碰到,且看如下代码的解决办法

SQLServer数据库表格

/*
创建数据库 test_db
create database test_db;
use test_db;
*/
if exists(select * from sysobjects where id=object_id('tb_test')) drop table tb_test
create table tb_test(
num int identity(100,1),
name varchar(10) default '请输入姓名',
weight float default 56.5200000,
birth date default GETDATE(),
primary key(num));
insert tb_test(birth) values('1994-9-1');
insert tb_test(birth) values('1996-2-1');
insert tb_test(birth) values('1999-2-3');
insert tb_test(birth) values('1994-7-8');
insert tb_test(birth) values('1993-2-6');
insert tb_test(birth) values('1999-12-20');
select * from tb_test;
Java代码
package table;

import java.awt.*;
import java.awt.event.*;
import java.math.BigDecimal;

import javax.swing.*;

import java.sql.*;
import java.sql.Date;
import java.time.LocalDate;
import java.util.*;

import javax.swing.table.*;
/**
 * @author wonzeng
 * 2020年6月27日
 */
public class JDBCJTable extends JFrame {
	// 声明一个类AbstractTableModel对象
	AbstractTableModel model;
	// 声明一个类JTable对象
	JTable table;
	// 声明一个滚动面板对象
	JScrollPane scrollpane;
//	声明表头
	String titles[];
	Class<?> colClasses[];
	// 二维表列的类型
	// 声明一个二维向量存储每一行数据
	Vector<Vector<String>> records;

	public void initTablModel() {
		records = new Vector<>(); // 实例化向量
		model = new AbstractTableModel() {
			private static final long serialVersionUID = 1L;

			public int getColumnCount() {
				return titles.length; // 取得表格列数
			}

			public int getRowCount() {
				return records.size(); // 取得表格行数
			}

			public String getValueAt(int row, int column) {
				if (!records.isEmpty()) // 取得单元格中的属性值
					return records.elementAt(row).elementAt(column);
				else
					return null;
			}

			public String getColumnName(int column) {
				return titles[column]; // 设置表格列名
			}

//			目前测试发现该方法去掉不重写仍然没有问题,但如果重写了,需要注意:
//				1.Double类型需要转为 import java.math.BigDecimal;
//				2.Date需要导入import java.sql.Date进行类型判断,并转为LocalDate;
			public Class<?> getColumnClass(int column) {
//				System.out.println("getColumnClass(int column):" + colClasses[column]);
				return colClasses[column];
			}

			public void setValueAt(Object value, int row, int column) {
				// 数据模型不可编辑,该方法设置为空
			}

			public boolean isCellEditable(int row, int column) {
				return false;// 设置单元格不可编辑,为缺省实现
			}
		};
	}

	public Connection getConnect() {
		Connection connect = null;
		// 加载驱动程序
		try {
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("JDBCJTable.getConnect():加载驱动失败");
			e.printStackTrace();
		}
		System.out.println("JDBCJTable.getConnect():");
		// 得到与数据库的连接
		String connString = "jdbc:sqlserver://localhost:1433;DatabaseName=test_db";
		try {
			connect = DriverManager.getConnection(connString, "sa", "666666");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println("JDBCJTable.getConnect():连接sqlserver数据库失败");
			e.printStackTrace();
		}
		return connect;
	}

	public void showData() throws SQLException, ClassNotFoundException {

		// 执行查询
		Statement stmt = getConnect().createStatement();
		ResultSet rs = stmt.executeQuery("select * from tb_test");
		// 得到元数据
		ResultSetMetaData meta = rs.getMetaData();
		// 返回列的数量
		int colCnt = meta.getColumnCount();
		System.out.println(colCnt);
		titles = new String[colCnt];
//		提供数据类型,重写 public Class<?> getColumnClass(int column) 
		colClasses = new Class[colCnt];
		for (int i = 0; i < colCnt; i++) {
			// 得到列名,注意下标是从1开始的
			titles[i] = meta.getColumnName(i + 1);
			String className = meta.getColumnClassName(i + 1);
//			如果是日期,返回:java.sql.Date
//			如果是浮点数,返回:java.sql.Date
			System.out.println("类型:" + className);
			// 得到数据类型
			Class<?> clz = Object.class;
			if (className != null)
				try {
					clz = Class.forName(className);
				} catch (Exception ex) {
					ex.printStackTrace();
				}
//			Double对象需要转为 import java.math.BigDecimal;
			if (clz == Double.class) {
				clz = BigDecimal.class;
			}
//			Date转为LocalDate需要导入import java.sql.Date,import java.time.LocalDate;
			if (clz == Date.class) {
				clz = LocalDate.class;
			}
			colClasses[i] = clz;
		}
//		records 二维向量,记录每一行查询所得,已被初始化 records = new Vector<>();
		records.removeAllElements();
		while (rs.next()) {
//			每一行
			Vector<String> rec_vector = new Vector<>();
//			 从结果集中取数据放入向量rec_vector中
			for (int i = 0; i < titles.length; i++) {
				Object obj = rs.getObject(i + 1);
				System.out.print(obj + ";");
				rec_vector.addElement(obj == null ? null : obj.toString());
			}
			records.addElement(rec_vector);
			System.out.println();

		}

		// 实例化JTable对象
//		table = new JTable();
//		使用继承JTable类的子类MTable实例化JTable对象
		table = new MTable();
		// 设置帮助提示
		table.setToolTipText("显示全部查询结果");
		// 设置表格调整尺寸模式
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		// 设置单元格选择方式
		table.setCellSelectionEnabled(true);
		table.setShowVerticalLines(true);
		table.setShowHorizontalLines(true);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		table.setSelectionBackground(Color.YELLOW);
		table.setSelectionForeground(Color.gray);
		table.setRowHeight(40);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
//		设置表格模型
		table.setModel(model);
		// 将表格放在滚动面板中
		scrollpane = new JScrollPane(table);
		getContentPane().add(scrollpane);
		// 更新表格
		model.fireTableStructureChanged();

		// 注:设定数据,也可以用以下的构造方法
		// JTable(TableModel dm)
		// JTable(Object[][] rowData, Object[] columnNames) )
		// JTable(Vector rowData, Vector columnNames)
	}

	public static void main(String[] args) {
		SwingUtilities.invokeLater(() -> {
			JDBCJTable f = new JDBCJTable();
			f.initTablModel();
			try {
				f.showData();
			} catch (Exception e) {
				e.printStackTrace();
			}

			f.setSize(560, 480);
			f.setLocationRelativeTo(null);
			f.setTitle("数据库查询");
			f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			f.setVisible(true);
		});
	}

}
//继承JTable
//设置表格内容居中
class MTable extends JTable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
//	public MTable(Vector<Vector<String>>rowData,Vector<String>columnNames) {
//		super(rowData,columnNames);
//	}
	public JTableHeader getTableHeader() {
		JTableHeader tableHeader=super.getTableHeader();
		tableHeader.setReorderingAllowed(false);
		DefaultTableCellRenderer hr=(DefaultTableCellRenderer)tableHeader.getDefaultRenderer();
		hr.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
		return tableHeader;
	}
	public TableCellRenderer getDefaultRenderer(Class<?>columnClass) {
		DefaultTableCellRenderer cr=(DefaultTableCellRenderer)super.getDefaultRenderer(columnClass);
		cr.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
		return cr;
	}
	public boolean isCellEditable(int row,int column) {
		return false;
	}	
}

实现效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值