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;
}
}