Java 创建表结构
## 技术要点
获取数据库和数据表元数据的技术要点如下:
* 通过create table表名(字段名字段类型长度)的sql形式创建表结构。
* ResultSetMetaData接口的作用是获取ResultSet对象中列的类型和属性信息。由于ResultSetMetaData是接口,所以没有构造方法,故不能使用new来创建ResultSetMetaData对象,但是可以通过ResultSet的getMetaData()方法创建,如ResultSetMetaData md=rs.getMetaData()。
* 调用ResultSetMetaData的getColumnCount()可以返回ResultSet对象中的列数。
* 调用ResultSetMetaData的getColumnName(int column)可以获取指定列的名称,其中column指的是列数。
* 调用ResultSetMetaData的getColumnTypeName(int column)返回检索指定列的数据库特定的类型名称,其中column指的是列数。
* 调用ResultSetMetaData的isNullable(int column)的作用是说明指定列中的值是否可以为null,其中column指的是列数。
## 代码实现
```java
package net.xsoftlab.baike;
import java.sql.Connection;
import java.sql.*;
import java.sql.DriverManager;
public class Structure {
// 在myuser数据库中创建了一个名字为staff的数据表。
public static void Create_Data(Connection con, String tableName) {
String sql = "create table if not exists " + tableName + "(id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,"// 主键
+ "name VARCHAR(50)NOT NULL UNIQUE,"// 姓名
+ "age INT(3)UNSIGNED NOT NULL,"// 年龄
+ "sex VARCHAR(3)NOT NULL,"// 性别
+ "address VARCHAR(50)NOT NULL,"// 居住地址
+ "depart VARCHAR(50)NOT NULL,"// 部门
+ "worklen VARCHAR(10)NOT NULL,"// 工龄
+ "wage VARCHAR(20)"// 工资
+ ")";
Statement sm = null;
try {
sm = con.createStatement();
sm.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭Statement
if (sm != null) {
try {
sm.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
}
// 显示数据表的元数据,主要是列的信息 con 与数据库的连接 tableName 数据表名
public static void Show_Data(Connection con, String tableName) {
String sql = "SELECT * FROM " + tableName;
Statement sm = null;
try {
sm = con.createStatement();
ResultSet rs = sm.executeQuery(sql);// 首先获得表的所有数据
ResultSetMetaData md = rs.getMetaData();// 得到结果集的元数据
System.out.println("数据表" + tableName + "的表结构如下:");
int columnCount = md.getColumnCount();// 表的列数
System.out.println();
StringBuffer sbf = new StringBuffer("");
sbf.append("序号 列名 ").append("类型 ");
sbf.append("是否为空 ");
System.out.println(sbf);
sbf.delete(0, sbf.length());
// 输出列的属性信息
for (int i = 1; i <= columnCount; i++) {
sbf.append(i).append(" ");
sbf.append(md.getColumnName(i)).append(" ");
sbf.append(md.getColumnTypeName(i)).append(" ");
sbf.append(md.isNullable(i));
System.out.println(sbf);
sbf.delete(0, sbf.length());
}
System.out.println("此表共有 " + columnCount + " 列");
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭Statement
if (sm != null) {
try {
sm.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
}
public static void main(String[] args) throws ClassNotFoundException, SQLException {
String tableName = "staff";
Connection con = null;
try {
// 获得数据库连接
con = getConnection();
System.out.println();
// 创建表
Create_Data(con, tableName);
// 显示数据表的元信息
Show_Data(con, tableName);
} finally {
// 关闭数据库连接
if (con != null) {
try {
con.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
}
public static Connection getConnection() {
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/myuser", "root", "123456");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
}
```
## 程序解读
1. Show_Data()方法实现了获取数据表元数据的功能。首先调用Connection的createStatement方法,创建一个java.sql.Statement对象,它用于执行静态SQL语句并返回执行结果;调用Statement的executeQuery方法,执行查询操作,获得数据表的所有数据,得到的结果集是一个ResultSet对象,该对象里包含了数据表的所有列和行的数据;调用ResultSet的getMetaData方法,获得描述结果集元数据的ResultSetMetaData对象,该对象实质上描述了数据表的元数据。
2. ResultSetMetaData的getColumnCount方法获得数据表定义的列数,getColumnName方法获得某列的列名,getColumnTypeName方法获得某列的类型名,isNullable方法判断某列是否允许为null。ResultSetMetaData还提供了很多方法,这里不一一列出。
**注意**
在读取完结果集中的数据后,需要调用ResultSet的close方法关闭该结果集,因为,每个ResultSet都与数据库存在一个连接,然后调用Statement的close方法,再调用Connection的close方法,即可彻底地关闭连接。这三个关闭是数据库编程中必须注意的,先后顺序不能改变。