15.7 用JDBC 连接数据库
15.7 用JDBC 连接数据库
据估算,将近一半的软件开发都要涉及客户(机)/服务器方面的操作。
数据库最主要的一个问题就是各家公司之间的规格大战。确实存在一种“标准”数据库语言,即“结构查询语言”(SQL-92
和
为实现这一“与平台无关”的特点,
为打开一个数据库,必须创建一个“数据库
(2) “子协议”:驱动程序的名字或者一种数据库连接机制的名称。由于
所有这些信息都统一编译到一个字串里,即“数据库
String dbUrl = "jdbc:odbc:people"
如果通过一个网络连接,数据库
准备好同数据库连接后,可调用静态方法
下面这个例子将打开一个联络信息数据库,并根据命令行提供的参数查询一个人的姓(Last Name
//: Lookup.java
// Looks up email addresses in a
// local database using JDBC
import java.sql.*;
public class Lookup {
public static void main(String[] args) {
String dbUrl = "jdbc:odbc:people";
String user = "";
String password = "";
try {
// Load the driver (registers itself)
Class.forName(
"sun.jdbc.odbc.JdbcOdbcDriver");
Connection c = DriverManager.getConnection(
dbUrl, user, password);
Statement s = c.createStatement();
// SQL code:
ResultSet r =
s.executeQuery(
"SELECT FIRST, LAST, EMAIL " +
"FROM people.csv people " +
"WHERE " +
"(LAST='" + args[0] + "') " +
" AND (EMAIL Is Not Null) " +
"ORDER BY FIRST");
while(r.next()) {
// Capitalization doesn't matter:
System.out.println(
r.getString("Last") + ", "
+ r.getString("fIRST")
+ ": " + r.getString("EMAIL") );
}
s.close(); // Also closes ResultSet
} catch(Exception e) {
e.printStackTrace();
}
}
} ///:~
可以看到,数据库
就
- 步骤
1 :寻找JDBC 驱动程序
上述程序包含了下面这条语句:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
这似乎暗示着一个目录结构,但大家不要被它蒙骗了。在我手上这个
若装载语句出错,会在这个时候得到一个异常。为了检验驱动程序装载语句是不是能正常工作,请将该语句后面直到
- 步骤
2 :配置数据库
同样地,我们只限于在
首先打开控制面板。其中可能有两个图标都含有“ODBC”字样,必须选择那个“
最有趣的数据库是我们已经使用过的一个。标准
大家会注意到在进行这些工作的时候,并没有实际指定一个文件,只是一个目录。那是因为数据库通常是由某个目录下的一系列文件构成的(尽管也可能采用其他形式
- 步骤
3 :测试配置
为了对配置进行测试,需用一种方式核实数据库是否可由查询它的一个程序“见到”。当然,可以简单地运行上述的
Connection c = DriverManager.getConnection(
dbUrl, user, password);
若掷出一个异常,表明你的配置有误。
然而,此时很有必要使用一个自动化的查询生成工具。我使用的是与
做完这些工作后,再用查询工具创建一个新查询时,便会发现自己的数据库可以使用了。
- 步骤
4 :建立自己的SQL 查询
我用
查询结果会向我们展示出是否能得到自己希望的东西。
现在可以按下
SELECT people.FIRST, people.LAST, people.EMAIL
FROM people.csv people
WHERE (people.LAST='Eckel') AND
(people.EMAIL Is Not Null)
ORDER BY people.FIRST
若查询比较复杂,手工编码极易出错。但利用一个查询工具,就可以交互式地测试自己的查询,并自动获得正确的代码。事实上,亲手为这些事情编码是难以让人接受的。
- 步骤
5 :在自己的查询中修改和粘贴
我们注意到上述代码与程序中使用的代码是有所区别的。那是由于查询工具对所有名字都进行了限定,即便涉及的仅有一个数据表(若真的涉及多个数据表,这种限定可避免来自不同表的同名数据列发生冲突
SELECT FIRST, LAST, EMAIL
FROM people.csv people
WHERE (LAST='Eckel') AND
(EMAIL Is Not Null)
ORDER BY FIRST
此外,我们不希望“硬编码”这个程序,从而只能查找一个特定的名字。相反,它应该能查找我们在命令行动态提供的一个名字。所以还要进行必要的修改,并将
"SELECT FIRST, LAST, EMAIL " +
"FROM people.csv people " +
"WHERE " +
"(LAST='" + args[0] + "') " +
" AND (EMAIL Is Not Null) " +
"ORDER BY FIRST");
从这个例子可以看出,利用目前找得到的工具——特别是查询构建工具——涉及
最好的方法是让查找程序一直保持运行,要查找什么东西时只需简单地切换到它,并键入要查找的名字即可。下面这个程序将查找程序作为一个“application/applet”创建,且添加了名字自动填写功能,所以不必键入完整的姓,即可看到数据:
//: VLookup.java
// GUI version of Lookup.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.sql.*;
public class VLookup extends Applet {
String dbUrl = "jdbc:odbc:people";
String user = "";
String password = "";
Statement s;
TextField searchFor = new TextField(20);
Label completion =
new Label(" ");
TextArea results = new TextArea(40, 20);
public void init() {
searchFor.addTextListener(new SearchForL());
Panel p = new Panel();
p.add(new Label("Last name to search for:"));
p.add(searchFor);
p.add(completion);
setLayout(new BorderLayout());
add(p, BorderLayout.NORTH);
add(results, BorderLayout.CENTER);
try {
// Load the driver (registers itself)
Class.forName(
"sun.jdbc.odbc.JdbcOdbcDriver");
Connection c = DriverManager.getConnection(
dbUrl, user, password);
s = c.createStatement();
} catch(Exception e) {
results.setText(e.getMessage());
}
}
class SearchForL implements TextListener {
public void textValueChanged(TextEvent te) {
ResultSet r;
if(searchFor.getText().length() == 0) {
completion.setText("");
results.setText("");
return;
}
try {
// Name completion:
r = s.executeQuery(
"SELECT LAST FROM people.csv people " +
"WHERE (LAST Like '" +
searchFor.getText() +
"%') ORDER BY LAST");
if(r.next())
completion.setText(
r.getString("last"));
r = s.executeQuery(
"SELECT FIRST, LAST, EMAIL " +
"FROM people.csv people " +
"WHERE (LAST='" +
completion.getText() +
"') AND (EMAIL Is Not Null) " +
"ORDER BY FIRST");
} catch(Exception e) {
results.setText(
searchFor.getText() + "\n");
results.append(e.getMessage());
return;
}
results.setText("");
try {
while(r.next()) {
results.append(
r.getString("Last") + ", "
+ r.getString("fIRST") +
": " + r.getString("EMAIL") + "\n");
}
} catch(Exception e) {
results.setText(e.getMessage());
}
}
}
public static void main(String[] args) {
VLookup applet = new VLookup();
Frame aFrame = new Frame("Email lookup");
aFrame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(applet, BorderLayout.CENTER);
aFrame.setSize(500,200);
applet.init();
applet.start();
aFrame.setVisible(true);
}
} ///:~
数据库的许多逻辑都是相同的,但大家可看到这里添加了一个
阅览
正如早先指出的那样,数据库起初一直处于一种混乱状态。这主要是由于各种数据库应用提出的要求造成的,所以数据库工具显得非常“强大”——换言之
当然,这并不是
在