数据库通用组装与异常

我怎么这么好看-大张伟

分析SQL异常

每个SQLException都有一个由多个SQLException对象构成的链,这些对象可以通过getNextException方法获取。我们需要用两个嵌套的循环来完全枚举所有的异常。

幸好,java 6改进了SQLException类,让其实现了Iterable< Throwable>接口,其iterator方法可以产生一个Iterator< Throwable>对象,这个迭代器可以迭代这两个链,首先迭代SQLException成因链,然后迭代下一个SQLException。我们可以使用下面的代码

1
2
3
for(Throwable t : sqlException){
do something with t
}

可以在SQLException上调用getSQLState和getErrorCode方法来进一步分析它。

数据库驱动程序可以将非致命的错误作为警告报告,我们可以从连接、语句和结果集中取出这些警告。SQLWarning类是SQLException的子类(尽管它不会被当作异常抛出)。警告也是串成链的,我们可以调用getSQLState和getErrorCode来获取有关警告的更多信息:

1
2
3
4
5
SQLWarning w=stat.getWarning();
while(w!=null){
do something with w
w = w.nextWarning();
}

当数据从数据库中读出并发生意外被截断时,SQLWarning的DataTruncation子类就派上用场了,如果截断发生在更新语句中,那么DataTruncation将会被当作异常抛出。

组装数据库

  1. 连接数据库
  2. 使用sql命令打开文件
  3. 使用通用的execute方法执行每条命令。如果它返回true,则说明该命令产生了一个结果集。
  4. 如果产生了结果集,则打印结果。因为这是一个通用方法执行的结果,我们需要使用元数据来确定该结果的列数。
  5. 如果运行过程出现了异常,则打印这个异常链
  6. 关闭数据库连接

示例程序如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import java.io.*;
import java.util.*;
import java.sql.*;

/**
* Executes all SQL statements in a file. Call this program as <br>
* java -classpath driverPath:. ExecSQL commandFile
* @version 1.30 2004-08-05
* @author Cay Horstmann
*/
class ExecSQL
{
public static void main(String args[])
{
try
{
Scanner in;
if (args.length == 0) in = new Scanner(System.in);
else in = new Scanner(new File(args[0]));

Connection conn = getConnection();
try
{
Statement stat = conn.createStatement();

while (true)
{
if (args.length == 0) System.out.println("Enter command or EXIT to exit:");

if (!in.hasNextLine()) return;

String line = in.nextLine();
if (line.equalsIgnoreCase("EXIT")) return;
if (line.trim().endsWith(";")) // remove trailing semicolon
{
line = line.trim();
line = line.substring(0, line.length() - 1);
}
try
{
boolean hasResultSet = stat.execute(line);
if (hasResultSet) showResultSet(stat);
}
catch (SQLException ex)
{
for (Throwable e : ex)
e.printStackTrace();
}
}
}
finally
{
conn.close();
}
}
catch (SQLException e)
{
for (Throwable t : e)
t.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}

/**
* Gets a connection from the properties specified in the file database.properties
* @return the database connection
*/
public static Connection getConnection() throws SQLException, IOException
{
Properties props = new Properties();
FileInputStream in = new FileInputStream("database.properties");
props.load(in);
in.close();

String drivers = props.getProperty("jdbc.drivers");
if (drivers != null) System.setProperty("jdbc.drivers", drivers);

String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");

return DriverManager.getConnection(url, username, password);
}

/**
* Prints a result set.
* @param stat the statement whose result set should be printed
*/
public static void showResultSet(Statement stat) throws SQLException
{
ResultSet result = stat.getResultSet();
ResultSetMetaData metaData = result.getMetaData();
int columnCount = metaData.getColumnCount();

for (int i = 1; i <= columnCount; i++)
{
if (i > 1) System.out.print(", ");
System.out.print(metaData.getColumnLabel(i));
}
System.out.println();

while (result.next())
{
for (int i = 1; i <= columnCount; i++)
{
if (i > 1) System.out.print(", ");
System.out.print(result.getString(i));
}
System.out.println();
}
result.close();
}
}
Donate comment here