java与sql数据库

更新时间:2024-01-25 15:59:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Java与数据库

建立学生管理数据库 /* 学生管理数据库 */

CREATE DATABASE xsgl ON( NAME = 'xsgl_Data',FILENAME = 'c: \\start新\\xsgl.mdf ',

SIZE = 2,FILEGROWTH = 10 %) LOG ON( NAME = 'xsgl_Log', FILENAME = 'c: \\start新\\xsgl_log.ldf',SIZE = 2,FILEGROWTH = 10%) use xsgl GO

/*创建专业表 */

CREATE TABLE speciality(specialityID int IDENTITY(l,1) PRIMARY KEY, specialityname char(10)NOT NULL) GO

/ *创建用户表* /

CREATE TABLE usertable (uid int IDENTITY (1, 1) PRIMARY KEY, uname char (10) NOT NULL, upwd char(10) NULL) GO

/*创建班级分类表*/

CREATE TABLE classclass(id int IDENTITY(1,1) PRIMARY KEY, parent int NOT NULL, name nchar(10) NOT NULL UNIQUE) GO

/*创建课程表 */

CREATE TABLE course (courseID int IDENTITY (1,1) PRIMARY KEY, courseName nchar(20) NOT NULL UNIQUE, teacher nchar( 10 ) NULL) GO

/ * 创建学生档案表* /

CREATE TABLE xsda(no int IDENTITY(1,1)PRIMARY KEY, classID int REFERENCES classclass (ID), name char (10) NOT NULL, sex nchar (1) NOT NULL, birthDate char (10) NULL, speciality int NULL, address char(30) NULL, isMember char (1) NULL, resume ntext NULL, picture image NULL) GO

/ *创建学生成绩表*/

CREATE TABLE grade (no int REFERENCES xsda (no), courseId int REFERENCES course (courseID), grade float NOT NULL, PRIMARY KEY(no, courseID) ) GO

1 数据库的连接

数据库的连接一般使用两种方法:使用JDBC-ODBC桥实现数据库的连接和使用纯Java JDBC驱动程序实现数据的连接。

1. JDBC

JDBC(Java DataBase Connection,Java数据库连接)由一组用Java语言编写的类和接口组成。JDBC为使用数据库 及其工具的开发人员提供了一个标准的API,使他们能够用Java API来编写数据库应用程序。通过使用JDBC,开发人员 可以很方便地将SQL语句传送给几乎任何一种数据库。

JDBC的作用概括起来有如下3个方面: (1)建立与数据库的连接 (2)向数据库发起查询请求 (3)处理数据库返回结果

这些作用是通过一系列API实现的,其中的几个重要类或接口如表4-1所示。 表 与数据库有关的几个重要类或接口 接口 java.sql.Drivermanager java.sql.Connection java.sql.Statement java.sql.ResultSet

2.DrverManager

DriverManager类是Java.sql包中用于数据库驱动程序管理的类,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应的驱动程序之间建立连接,也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等事务。一般的应用程序只使用它的getConnection()方法。这个方法用来建立与数据库的连接。

static Connection getConnection(String url, String username, String password):通过指定的数据的URL及用户名、密码创建数据库连接。 3.Connection

Connection是用来表示数据库连接的对象,对数据库的一切操作都是在这个连接基础上进行的。Connection类的主 要方法有:

作用 处理驱动程序的加载和建立新数据库连接 处理与特定数据库的连接 在指定连接中处理SQL语句 处理数据库操作结果集 void clearWarning( ):清除连接的所有警告信息。 Statement createStatement( ):创建一个Statement对象。

Statement CreateStatement(int resultSetType, int resultSetConcurrency):创建一个Statement对象,它将生成具有特定类型和并发性的结果集。

void commit( ):提交对数据库的改动并释放当前持有的数据库的锁。 void rollback( ):回滚当前事务中的所有改动并释放当前连接持有的数据库的锁。

String getCatalog( ):获取连接对象的当前目录。 boolean isClose( ):判断连接是否已关闭。 boolean isReadOnly():判断连接是否为只读模式。 void setReadOnly():设置连接的只读模式。 void close():立即释放连接对象的数据库和JDBC资源。 4. Statement

Java所有SQL语句都是通过陈述(Statement)对象实现的。Statement用于在已经建立的连接的基础上向数据库发送SQL语句的对象。

? Statement对象的建立

通过Connection对象的createStatement方法建立Statement对象: Statement stmt=con.createStatement();

如果要建立可滚动的记录集,需要使用如下格式的方法: public

Statement

createStatement(int

resultSetType,

int

resultSetConcurrency) throws SQLException

resultSetType可取下列常量:

ResultSet.TYPE_FORWARD_ONL:只能向前,默认值。

ResultSet.TYPE_SCROLL_INSENSITIVE:可操作数据集的游标,但不反映数据的变化。

ResultSet.TYPE_SCROLL_SENSITIVE:可操作数据集的游标,反映数据的变化。 resultSetConcurrency的取值:

ResultSet.CONCUR_READ_ONLY:不可进行更新操作。

ResultSet.CONCUR_UPDATABLE:可以进行更新操作,默认值。 Statement对象的方法

Statement对象提供了三种执行SQL语句的方法:

ResultSet executeQuery(String sql):执行SELECT语句,返回一个结果集。 int executeUpdate(String sql):执行update、insert、delete 等不需要返回结果集的SQL语句。它返回一个整数,表示执行SQL语句影响的数据行数。

boolean execute(String sql):用于执行多个结果集、多个更新结果(或者两者

都有)的SQL语句。它返回一个boolean值。如果第一个结果是ResultSet对象,返回true;如果是整数,就返回false。取结果集时可以与getMoreResultSet、getResultSet和getUpdateCount结合来对结果进行处理。

5.ResultSet

ResultSet对象实际上是一个由查询结果数据构成的表。在ResultSet中隐含着一个指针,利用这个指针移动数据行,可以取得所要的数据,或对数据进行简单的操作。其主要的方法有:

boolean absolute(int row):将指针移动到结果集对象的某一行。 void afterLast():将指针移动到结果集对象的末尾。 void beforeFrist():将指针移动到结果集对象的头部。 boolean first():将指针移动到结果集对象的第一行。 boolean next():将指针移动到当前行的下一行。 boolean previous():将指针移动到当前行的前一行。 boolean last():将指针移动到当前行的最后一行。

此外还可以使用一组getXXX()方法,读取指定列的数据。XXX是JDBC中Java语言的数据类型。这些方法的参数有两种格式,一是用int指定列的索引,二是用列的字段名(可能是别名)来指定列。如:

String strName=rs.getString(2); String strName=rs.getString(\

5.案例 使用纯Java JDBC驱动程序实现数据库的连接

在相关网站下载驱动程序,通过Class.forName()方法加载驱动程序,再通过驱动程序管理器(DriverManager)的方法getConnection()建立连接。 【代码与注释】

import java.sql.*; import javax.swing.*; class ConnectServer2 {

//连接数据类

static Connection con=null;//连接对象

public static boolean conn(String url,String username,String password) {

}

try { { } try { }

catch(SQLException e) { }

return true;//成功

e.printStackTrace(); return false;

con=DriverManager.getConnection(url,username,password);//连接e.printStackTrace();//在命令行打印异常信息在程序中出错的位置及return false;

Class.forName(\}catch(Exception e)

原因

数据库

public static boolean close() { }

public static void main(String args[]) {

//连接SQL Server数据库

if(conn(\try { { }

return true;

return false;

con.close();//关闭数据库 con=null;

}catch(SQLException e)

gl\ }

学习利用纯Java JDBC驱动程序实现数据库连接。 【应用扩展】

连接其他类型的数据库使用的驱动程序,可参考表4-2。

表4-2 常用的数据库驱动程序

数据库 MySQL Oracle 驱动类 org.git.mm.mysql.Driver oracle.jdbc.driver.OracleDriver 【相关知识】

1. 纯Java JDBC驱动程序

纯Java JDBC驱动程序是独立的连接驱动程序,不需要中间服务器,与数据库实现通信的整个过程均由Java语言 实现。这种方法目前应用较广泛,缺点是需要下载相应的类包,不同数据库的连接代码可能不同。连接SQL Server可 以在www.msdn.com网站下载。有三个类包:msbase.jar、mssqlserver.jar、msutil.jar。使用时要将这三个包放在 jdk\\jre\\lib\\ext\\目录下,或者所放的位置设置到CLASSPATH中即可。 2.使用纯Java JDBC驱动程序连接数据库 (1)加载驱动程序

在JDBC中,通常有两种加载驱动程序的方式。

一种是将驱动程序添加到java.lang.System的属性jdc.drivers中。这是一个由DriverManager类加载驱动程序类名的列表,用冒号分隔。在JDBC的java.sql.DrvierManager类初始化时,JVM的系统属性中搜索jdbc.drivers字段的内

容。如果存在以冒号分隔的驱动程序名称,则 DriverManager类加载相应的驱动程序。

另一种方式是在程序中利用Class.forName()方法加载指定的驱动程序,如: Class.forName(\

URL jdbc:mysql://localhost:3306/xsgl jdbc:oracle:thin:@127.0.0.1:1521:xsgl 下载地址 }

{ } else

JOptionPane.showMessageDialog(null,\数据库连接失败!\

JOptionPane.showMessageDialog(null,\数据库连接成功!\close();//关闭数据库

http://www.mysql.com/downlm http://ont.oracle.com/soft需要注意的是,连接不同的数据库,加载的驱动程序有所不同。 (2)创建指定数据库的URL

要建立与数据库的连接,首先要创建指定数据库的URL。数据库的URL对象类似网络资源的统一定位。其构成格 式如下:

jdbc:subProtocol:subName://hostname:port;DatabaseName=XXX 其中:jdbc表示当前通过Java的数据库连接进行数据库访问。

subProtocal表示通过某种驱动程序支持的数据库连接机制。 subName表示在当前连接机制下的具体名称。 hostName表示主机名。port表示相应的连接端口。 DatabaseName是要连接的数据库的名称。

按照上述构造规则,可以构造如下类型的数据库URL:

jdbc.microsoft:sqlserver://localhost:1433;DatabaseName=xsgl 该数据库URL表示利用Microsoft提供的机制,选择名称为sqlserver的驱动,通过1433端口访问本机上的xsgl数据库。

数据的基本操作

数据的基本操作主要是指对数据的查看、添加、修改、删除、查询等操作,利用Java的Statement对象所提供的成员方法,可以方便地实现这些操作。 案例 3 读取数据

利用Connection对象的createStatement方法建立Statement对象,在利用Statement对象的executeQuery()的方法执行SQL语句进行查询,返回结果集。再利用形如getXXX()的方法从结果集中读取数据。 【案例说明】

利用上面定义的ConnectServer类建立连接,读取学生档案(xsda)表中的数据,显示在如图4-1所示的窗体中,并且能够前后移动记录。

学习数据库的基本操作方法。

为了方便,案例中的组件采用的都是文本组件。在实际应用中,也经常使用其他组件。例如,性别用单选钮。如果改成单选钮,男和女两个单选钮要建立成组,并根据数据库中读出的数据,设置其选中状态。读者可参考下一案例。

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import java.sql.*;

public class StudentDataWindow extends JFrame implements ActionListener { ,

ResultSet.CONCUR_READ_ONLY);//创建Statment对象,指定记录集rs=stmt.executeQuery(\执行查询,返回结Container con=getContentPane();

可滚动,但只读 果集

String title[]={\班级:\学号:\姓名:\性别:\出生日期:\团员否:\JTextField txtClassID=new JTextField(2); JTextField txtNo=new JTextField(2); JTextField txtName=new JTextField(10); JTextField txtSex=new JTextField(3); JTextField txtBirthDate=new JTextField(10); JTextField txtIsMember=new JTextField(2); JTextField txtAddress=new JTextField(30); JTextArea txtResume=new JTextArea(); JButton next=new JButton(\下一页\JButton prev=new JButton(\上一页\JButton first=new JButton(\首页\JButton last=new JButton(\尾页\Statement stmt; ResultSet rs; StudentDataWindow() {

stmt=ConnectServer.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE

super(\学生档案信息查看窗口\setSize(450,395); try {

家庭地址:\简历:\

con.setLayout(new BorderLayout(0,8)); JPanel p[]=new JPanel[7]; for(int i=0;i<7;i++) { }

p[0].add(txtClassID); p[1].add(txtNo); p[2].add(txtName); p[3].add(txtSex); p[4].add(txtBirthDate); p[5].add(txtIsMember); p[6].add(txtAddress);

JPanel p1=new JPanel(new GridLayout(7,1,0,8)); JScrollPane

jp=new

JScrollPane(txtResume,

JScrollPane.HORIZONTAL_SCROLLB

p[i]=new JPanel(new FlowLayout(FlowLayout.LEFT,10,0)); p[i].add(new JLabel(title[i]));

JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, AR_NEVER);

jp.setPreferredSize(new Dimension(380,80)); for(int i=0;i<7;i++) p1.add(p[i]);

JPanel p2=new JPanel(new FlowLayout(FlowLayout.LEFT,10,0)); p2.add(new JLabel(title[7])); p2.add(jp);

JPanel p3=new JPanel(); p3.add(prev); p3.add(next); p3.add(first); p3.add(last); con.add(p1,\con.add(p2,\con.add(p3,\

next.addActionListener(this); prev.addActionListener(this); first.addActionListener(this); last.addActionListener(this);

}

{ }

rs.first(); loadData();

}catch(Exception e)

e.printStackTrace();

setVisible(true); });

public void windowClosing(WindowEvent e){ }

System.exit(0);

addWindowListener(new WindowAdapter(){

boolean loadData()

{ //读结果集中数据,并设置到相应的组件 }

public void actionPerformed(ActionEvent e) {

try {

if(e.getSource()==next)rs.next(); //下一记录 else if(e.getSource()==prev)rs.previous(); //前一记录 try { {

e.printStackTrace(); return false;

txtNo.setText(rs.getString(\

txtClassID.setText(rs.getString(\txtName.setText(rs.getString(\txtSex.setText(rs.getString(\

txtBirthDate.setText(rs.getString(\txtAddress.setText(rs.getString(\txtIsMember.setText(rs.getString(\txtResume.setText(rs.getString(\

}catch(SQLException e)

} return true;

}

}

}

else if(e.getSource()==first)rs.first(); //首记录 else if(e.getSource()==last)rs.last(); //尾记录 loadData(); //重新读取数据

catch(Exception ee){}

public static void main(String args[]) {

JFrame.setDefaultLookAndFeelDecorated(true); Font font = new Font(\

Enumeration keys = UIManager.getLookAndFeelDefaults().keys(); while (keys.hasMoreElements()) { }

Object key = keys.nextElement();

if(UIManager.get(key)instanceof Font) UIManager.put(key, font);

if(!ConnectServer.conn(\ }

{ }

StudentDataWindow mainFrame = new StudentDataWindow();

JOptionPane.showMessageDialog(null,\数据库连接不成功!\System.exit(0);

baseName=xsgl\

【应用扩展】

为了方便,案例中的组件采用的都是文本组件。在实际应用中,也经常使用其他组件。例如,性别用单选钮。如果改成单选钮,男和女两个单选钮要建立成组,并根据数据库中读出的数据,设置其选中状态。读者可参考下一案例。

案例4 数据更新 【案例说明】

数据的更新包括表的创建、删除及记录的增、删、改操作。本案例实现了对数据的更新操作,界面上的组件更加丰富。

运行界面如图 所示。

【技术要点】

利用Connection对象的createStatement方法建立Statement对象,再利用Statement对象的executeUpdate()的方法执行update语句,实现数据修改;执行insert语句,实现数据添加。 package com.test6; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import java.sql.*;

class Student2 extends JFrame implements ActionListener {

String title[]={\班级\学号\姓名\性别\出生日期\团员否\邮箱JComboBox cno=new JComboBox(); JTextField sno=new JTextField(5); JTextField name=new JTextField(10); JTextField bir=new JTextField(10); JTextField email=new JTextField(30); JTextArea resume=new JTextArea();

JRadioButton radioSexM=new JRadioButton(\男\JRadioButton radioSexF=new JRadioButton(\女\JCheckBox checkisparty=new JCheckBox(\JButton ok=new JButton(\保存\JButton cancel=new JButton(\取消\Statement stmt; ResultSet rs; int No;

Student2(int No) {

this.No=No; if(No==-1)

setTitle(\添加学生档案窗口\else setTitle(\修改学生档案窗口\

\简历\

try {

Container con=getContentPane(); con.setLayout(new BorderLayout(0,5));

stmt=Connect.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);

rs=stmt.executeQuery(\while(rs.next()) { }

ButtonGroup bgp=new ButtonGroup(); //为单选钮分组 bgp.add(radioSexM); bgp.add(radioSexF); setSize(450,410);

JPanel p[]=new JPanel[7]; for(int i=0;i<7;i++) { }

p[0].add(cno); p[1].add(sno); p[2].add(name); p[3].add(radioSexM); p[3].add(radioSexF); p[4].add(bir);

p[5].add(checkisparty); p[6].add(email);

JPanel p1=new JPanel(new GridLayout(7,1,0,5)); for(int i=0;i<7;i++) p1.add(p[i]);

JPanel p2=new JPanel(new FlowLayout(FlowLayout.LEFT,10,0)); JScrollPane

jp=new

p[i]=new JPanel(new FlowLayout(FlowLayout.LEFT,10,0)); p[i].add(new JLabel(title[i])); //将班级信息添入到下拉列表中 cno.addItem(rs.getString(1));

cno.addItem(rs.getString(1));

JScrollPane(resume,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,

{

e.printStackTrace(); }

setVisible(true);

JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

jp.setPreferredSize(new Dimension(370,80)); p2.add(new JLabel(title[7]));p2.add(jp); JPanel p3=new JPanel(); p3.add(ok);p3.add(cancel); con.add(p1,\con.add(p2,\con.add(p3,\ok.addActionListener(this); cancel.addActionListener(this); if(No!=-1) {

rs=stmt.executeQuery(\

\

from

xuesheng

where

SNo=\

rs.first(); loadData();

sno.setEditable(false);

} rs.close();

}catch(Exception e)

}

boolean loadData() { //将数据填到组件 try {

cno.setSelectedItem(rs.getString(1)); sno.setText(rs.getString(2)); name.setText(rs.getString(3)); if(rs.getString(4).equals(\男\ radioSexM.setSelected(true); else

radioSexF.setSelected(true); bir.setText(rs.getString(5));

if(rs.getString(6).toUpperCase().equals(\ checkisparty.setSelected(true); else

checkisparty.setSelected(false); email.setText(rs.getString(7)); resume.setText(rs.getString(8));

}catch(SQLException e) {

e.printStackTrace(); return false;

} return true; }

public void actionPerformed(ActionEvent e) {

try {

if(e.getSource()==ok) {

String sex,isMember; int classID; Statement

ResultSet.CONCUR_UPDATABLE);

stmt=Connect.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet rs=stmt.executeQuery(\CLno from xuesheng

+cno.getSelectedItem()+\

where CLno= '\

rs.first();

classID=rs.getInt(1);

if(radioSexM.isSelected()) sex=\男\else sex=\女\if(checkisparty.isSelected()) isMember=\else isMember=\String sql;

{

if(No==-1) { } else {

//修改记录

sql=\sql=sql+\

sql=sql+\sql=sql+\//添加记录 sql=sql+\

sql=sql+\sql=sql+email.getText()+\

sql=\values(\

sql=sql+\

sql=sql+\}

stmt.executeUpdate(sql); //执行SQL语句

}

else if(e.getSource()==cancel) dispose();

}catch(Exception ee)

ee.printStackTrace();

}

}

public static void main(String args[]) {

JFrame.setDefaultLookAndFeelDecorated(true); Font font = new Font(\

Enumeration keys = UIManager.getLookAndFeelDefaults().keys(); while (keys.hasMoreElements()) {

Object key = keys.nextElement();

if(UIManager.get(key) instanceof Font)UIManager.put(key, font);

}

if(!Connect.conn(\ }

{ }

new Student2(-1); //添加新记录的调用方法 //new Student2(2); //修改学号为2的记录

JOptionPane.showMessageDialog(null,\数据库连接不成功!\System.exit(0);

sa\

} import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import java.sql.*;

class StudentDataUpdate extends JFrame implements ActionListener {

String title[]={\班级\学号\姓名\性别\出生日期\团员否\家庭地JComboBox combClassID=new JComboBox(); JTextField txtNo=new JTextField(2); JTextField txtName=new JTextField(10); JTextField txtBirthDate=new JTextField(10); JTextField txtAddress=new JTextField(30); JTextArea txtResume=new JTextArea();

JRadioButton radioSexM=new JRadioButton(\男\JRadioButton radioSexF=new JRadioButton(\女\JCheckBox checkIsMember=new JCheckBox(\JButton ok=new JButton(\保存\JButton cancel=new JButton(\取消\Statement stmt; ResultSet rs; int No;

StudentDataUpdate(int No) 址\简历\

{

stmt=ConnectServer.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE

rs=stmt.executeQuery(\name from classclass order by ID while(rs.next()) { }

ButtonGroup bgp=new ButtonGroup(); //为单选钮分组 bgp.add(radioSexM); bgp.add(radioSexF); setSize(450,410);

JPanel p[]=new JPanel[7]; for(int i=0;i<7;i++) { }

p[0].add(combClassID); p[1].add(txtNo); p[2].add(txtName); p[3].add(radioSexM); p[3].add(radioSexF); p[4].add(txtBirthDate); p[5].add(checkIsMember); p[6].add(txtAddress);

p[i]=new JPanel(new FlowLayout(FlowLayout.LEFT,10,0)); p[i].add(new JLabel(title[i])); //将班级信息添入到下拉列表中

combClassID.addItem(rs.getString(1));

this.No=No; if(No==-1)

setTitle(\添加学生档案窗口\else setTitle(\修改学生档案窗口\try {

Container con=getContentPane();

con.setLayout(new BorderLayout(0,5)); //设置边界布局

,ResultSet.CONCUR_UPDATABLE); //建立可滚动并且可更新的结果集 asc\

JPanel p1=new JPanel(new GridLayout(7,1,0,5)); for(int i=0;i<7;i++) p1.add(p[i]);

JPanel p2=new JPanel(new FlowLayout(FlowLayout.LEFT,10,0)); JScrollPane

jp=new

JScrollPane(txtResume,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

jp.setPreferredSize(new Dimension(370,80)); p2.add(new JLabel(title[7]));p2.add(jp); JPanel p3=new JPanel(); p3.add(ok);p3.add(cancel); con.add(p1,\con.add(p2,\con.add(p3,\ok.addActionListener(this); cancel.addActionListener(this); if(No!=-1) {

rs=stmt.executeQuery(\

from

class.ID

and

classclass.name,xsda.no,xsda.name,xsda.sex,xsda.birthDate,xsda.isMember,speciality.specialityName,xsda.ddress,xsda.resume xsda,speciality,classclass

{

e.printStackTrace(); }

setVisible(true);

where

xsda.classID=class

xsda.speciality=speciality.specialityID and xsda.No=\

rs.first(); loadData();

txtNo.setEditable(false);

} rs.close();

}catch(Exception e)

}

boolean loadData() { //将数据填到组件 try

{

combClassID.setSelectedItem(rs.getString(1)); txtNo.setText(rs.getString(2)); txtName.setText(rs.getString(3)); if(rs.getString(4).equals(\男\ radioSexM.setSelected(true); else

radioSexF.setSelected(true); txtBirthDate.setText(rs.getString(5));

if(rs.getString(6).toUpperCase().equals(\ checkIsMember.setSelected(true); else

checkIsMember.setSelected(false); txtAddress.setText(rs.getString(8)); txtResume.setText(rs.getString(9));

}catch(SQLException e) {

e.printStackTrace(); return false;

} return true; }

public void actionPerformed(ActionEvent e) {

try {

if(e.getSource()==ok) {

String sex,isMember; int classID; Statement

stmt=ConnectServer.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

ResultSet rs=stmt.executeQuery(\id from classclass rs.first();

classID=rs.getInt(1);

where name= '\

{

if(radioSexM.isSelected()) sex=\男\else sex=\女\

if(checkIsMember.isSelected()) isMember=\else isMember=\String sql; if(No==-1) {

//添加记录 sql=sql+\

sql=\into xsda(classID,name,sex,birthDate,isMember,address,resume)\values(\

sql=sql+\sql=sql+txtAddress.getText()+\

} else {

//修改记录

sql=\sql=sql+\

sql=sql+\

sql=sql+\

sql=sql+\}

stmt.executeUpdate(sql); //执行SQL语句

sql=sql+\

}

else if(e.getSource()==cancel) dispose();

}catch(Exception ee)

ee.printStackTrace();

}

}

} try

public static void main(String args[]) {

JFrame.setDefaultLookAndFeelDecorated(true); Font font = new Font(\

Enumeration keys = UIManager.getLookAndFeelDefaults().keys(); while (keys.hasMoreElements()) {

Object key = keys.nextElement();

if(UIManager.get(key) instanceof Font)UIManager.put(key, font);

}

if(!ConnectServer.conn(\ }

{ }

//new StudentDataUpdate(-1); //添加新记录的调用方法 new StudentDataUpdate(2); //修改学号为2的记录

JOptionPane.showMessageDialog(null,\数据库连接不成功!\System.exit(0);

baseName=xsgl\

{

rs.updateRow(); }catch(Exception e){}}

使用PreparedStatement对象删除数据表记录

与使用Statement类似,只是创建SQL语句时,可以带参数(以“?”表示)。 String sql= \

PreparedStatment pstmt= ConnectServer.con.prepareStatement(sql); pstmt.setString(1, '黄小华'); int rowCount=pstmt.executeUpdate();

if(rowCount>0)System.out.println(\成功删除记录\

【应用扩展】

案例中对数据的操作均使用SQL完成。在构造SQL语句时十分麻烦,实际上对数据的更新还有其他方法。例如,使用预处理(PreparedStatement)对象不仅可以提高操作的速度,而且书写也会简单。在后面的内容中将介绍几种更新数据的方法。 【相关知识】

1.数据表记录增加操作

(1)数据表记录增加的SQL语法insert into 表名(字段名1,字段名2?) values(字段值

1,

2,

?

)

insert

into

xsda(classID,name,sex,birthDate,isMember,address,resume) values(12,'张磊','男',' 1988-9-8',1, '北京', ' ')

(2)使用Statement对象增加数据表记录 首先创建一个SQL语句。然后调用Statement对象的executeUpdate()方法。 stmt.executeUpdate(sql); 上述方法可以返回一个整数,表明成功插入的记录数。

(3)使用moveToInsertRow 和insertRow方法增加数据表记录 String sql=\from xsda\

ResultSet rs=stmt.executeQuery(sql); //获取数据表的全部结果集 rs.moveToInsertRow(); //将数据表指针移到插入记录位置 rs.updateInt(2, 13); //向classID字段输入数据 rs.updateString(3, '黄红'); //向name字段输入数据 rs.updateString(4, '女'); //向sex字段输入数据

rs.updateString(5, '1997-9-12'); //向birthDate字段输入数据 rs.updateString(6, '大连'); //向address字段输入数据 rs.updateInt(7, 1); //向isMember字段输入数据 rs.updateString(8, ' 无'); //向resume字段输入数据 try {

rs.insertRow(); }catch(Exception e){}

(4)使用PrepareStatement对象增加数据表记录 与使用Statement类似,只是创建SQL语句时,可以带参数(以“?”表示)。插入时通过更改参数实现记录的更新。 String sql= \into xsda(classID,name,sex,birthDate,isMember,addre

ss,resume) values(?,?,?,?,?, ?, ' ')\

PrepareStatment pstmt= ConnectServer.con.prepareStatement(sql); pstmt.setInt(1, 14);

pstmt.setString(2, '黄少军'); pstmt.setString(3, '男'); pstmt.setString(4, '1987-4-10'); pstmt.setString(5, '上海'); pstmt.setInt(6, 0);

int rowCount=pstmt.executeUpdate();

if(rowCount>0)System.out.println(\成功插入记录\

2.数据表记录修改操作

(1)数据表记录修改的SQL语法 update 表名 set 字段1=字段值1,字段2=字段值2? where 特定条件 例如: update xsda name='黄小华' where name='黄少华' (2)使用Statement对象修改数据表记录 首先创建一个SQL语句。然后调用Statement对象的executeUpdate()方法。

stmt.executeUpdate(sql); 上述方法可以返回一个整数,表明成功修改的记录数。 (3)使用ResultSet对象修改数据表记录

String sql=\黄少华'\ResultSet rs=stmt.executeQuery(sql); //获取数据表的结果集

if(rs.next()){ rs.updateString(3, '黄小华'); //修改name字段的数据 try{

rs.updateRow(); }catch(Exception e){} }

(4)使用PrepareStatement对象修改数据表记录 与使用Statement类似,只是创建SQL语句时,可以带参数(以“?”表示)。修改时通过更改参数实现记录的更新。 String sql= \黄少华'\PrepareStatment pstmt= ConnectServer.con.prepareStatement(sql); pstmt.setString(1, '黄小华'); int rowCount=pstmt.executeUpdate();

if(rowCount>0)System.out.println(\成功修改记录\

3.数据表记录删除操作

(1)数据表记录删除的SQL语法 delete form 表名 where 特定条件 例如: delete from xsda where name='黄小华'

(2)使用Statement对象删除数据表记录 首先创建一个SQL语句。然后调用Statement对象的executeUpdate()方法。 stmt.executeUpdate(sql); 上述方法可以返回一个整数,表明成功删除的记录数。

(3)使用ResultSet对象删除数据表记录

String sql=\黄少华'\

ResultSet rs=stmt.executeQuery(sql); //获取数据表的结果集 if(rs.next()){ rs.deleteRow(); //删除该行

利用Connection对象的getMetaData()方法创建DatabaseMetaData对象,从该对象中获取数据库的基本信息。 4_3_1.jpg

本案例运行后能够获取数据库的存放位置、使用的驱动程序、所包含的表的信息,及其中一个的表的列信息。

4.3.1 案例4-5 获取数据库基本信息 学习获取数据基本信息的方法。

使用数据库元数据对象还可以获得数据库对SQL支持的信息。 例如:

getNumericsFunctions():获取数据库支持的数学函数。 getStringFunctions():获取数据库支持的系统字符串函数。 getSystemFunction():获取数据库支持的系统函数。

SupportsANSI92FullSQL():获取数据库是否支持ANSI92全集SQL语法的布尔值。

import java.awt.*; import java.sql.*; import java.awt.event.*; import javax.swing.*; import java.util.*;

import javax.swing.table.*;

public class QueryDataBase extends JFrame {

JTable table1,table2,table3; JScrollPane sp1,sp2,sp3; JPanel p1=new JPanel(); public QueryDataBase() {

Vector vc1=new Vector(); Vector header1=new Vector(); Vector vc2=new Vector(); Vector header2=new Vector(); Vector vc3=new Vector(); Vector header3=new Vector(); Vector v1; try {

DatabaseMetaData dbmd=ConnectServer.con.getMetaData(); //元数据String url=dbmd.getURL(); //获得数据库的位置

String driverName=dbmd.getDriverName(); //获得数据库的驱动v1=new Vector(); v1.addElement(url); v1.addElement(driverName); vc1.addElement(v1);

ResultSet rs=dbmd.getTables(null,null,\获取表的信息 while(rs.next()) { }

rs=dbmd.getColumns(null,null,\获取列的信息 while(rs.next()) {

v1=new Vector(); v1=new Vector();

v1.addElement(rs.getString(\表名 v1.addElement(rs.getString(\类型 vc2.addElement(v1);

对象

程序

}

}

v1.addElement(rs.getString(\列名 v1.addElement(rs.getString(\类型名 v1.addElement(rs.getString(\大小 vc3.addElement(v1);

}catch(SQLException e){} header1.addElement(\位置\header1.addElement(\驱动程序\table1=new JTable(vc1,header1); header2.addElement(\表名称\header2.addElement(\表类型\table2=new JTable(vc2,header2); header3.addElement(\字段名\header3.addElement(\字段类型\header3.addElement(\字段大小\table3=new JTable(vc3,header3); sp1=new JScrollPane(table1); sp2=new JScrollPane(table2); sp3=new JScrollPane(table3); p1.setLayout(new GridLayout(2,1)); setSize(300,300);

sp1.setPreferredSize(new Dimension(200,40)); p1.add(sp2);p1.add(sp3);

this.getContentPane().add(sp1,\this.getContentPane().add(p1,\setTitle(\数据库基本信息查询\setVisible(true);

public static void main(String args[]) {

JFrame.setDefaultLookAndFeelDecorated(true); Font font = new Font(\

Enumeration keys = UIManager.getLookAndFeelDefaults().keys(); while (keys.hasMoreElements()) {

Object key = keys.nextElement(); if (UIManager.get(key) instanceof Font)

}

}

UIManager.put(key, font);

if(!ConnectServer.conn(\ }

{

JOptionPane.showMessageDialog(null,\数据库连接不成功!\System.exit(0);

baseName=xsgl\

} new QueryDataBase();

数据库的基本信息可以通过DatabaseMetaData对象获得。DatabaseMetaData对象要使用Connection对象的getMetaData()方法创建。DatabaseMetaData对象的主要方法有: String getURL():返回数据库系统的URL。

String getDatabaseProductName():获得数据库产品名。 String getDriverName():获得驱动程序名称。

ResultSet

getTables(String

catalog,

String

schemaPattern,String

tableNamePattern,String[] types):获得表的信息 。其中catalog为目录名,null表示忽略目录;schemaPattern为大纲的匹配模式,null表示忽略;schemaPattern表示 名称匹配模式;type为需要检索的表类型列表。该方法返回一个结果集,主要的字段有TABLE_NAME、TABLE_TYPE 等。类型可以是\, \, \TABLE\, \,\, \,\。

ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern,String columnNamePattern): 获得表的列信息,其中columnNamePattern为列名的匹配模式。该方法获得的结果集每一行都是一个列的描述,主要 的字段COLUMN_NAME, COLUMN_SIZE,TYPE_NAME等。

ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern):获得存储过程的 信息,其中procedureNamePattern为存储过程名的匹配模式。该方法获得的结果集每一行都是一个存储过程的描述, 主要的字段有PROCEDURE_NAME,PROCEDURE_NAME等。

ResultSet getProcedureColumns(String catalog, String schemaPattern,String procedureNamePattern, String columnNam ePattern):获得存储过程结果集中的列信息。columnNamePatter为列名的匹配模式。

对于记录集对象,也可以使用ResultSet的getMetaData()获得表的元数据。该方法返回ResultSetMetaData对象。 ResultSetMetaData对象主要有如下方法: int getColumnCount():返回记录集的列数。

String getColumnName(int column):返回指定列名称。 int getColumnType(int column):返回指定列类型号。

boolean isAutoIncrement(int index):判断指定字段是都为自动增值字段。

java.swing.table包中的JTable类可用来建立表格。利用默认的表格数据模型(DefaultTableModel)建立表格,对维护表格数据十分方便。 4_4_1.jpg

本案例通过表格显示学生档案信息,并提供了分页功能。 4.4.1 案例4-6 使用表格浏览数据 学习利用表格显示数据库数据的方法。

利用数据模型建立表格,对表格的维护也比较方便。例如: 1.增加行或列

dtm.addRow(new Vector()); //添加一空行 dtm.addColumn(\新列名\添加一列

2. 删除行

int rowcount = defaultModel.getRowCount()-1;//返回行数 if(rowcount >= 0) {

dtm.removeRow(rowcount); //删除尾行

dtm.setRowCount(rowcount); //删除行后必须重新设置行数。 }

3.删除列

int columncount = defaultModel.getColumnCount()-1; if(columncount >= 0)

{ //若columncount<0代表已经没有任何列了。

TableColumnModel columnModel = table.getColumnModel(); TableColumn tableColumn = columnModel.getColumn(columncount); columnModel.removeColumn(tableColumn); //删除列

dtm.setColumnCount(columncount); //重新设置列数 }

import java.awt.*; import java.sql.*; import java.awt.event.*; import javax.swing.*; import java.util.*;

import javax.swing.table.*;

public class Student3 extends JFrame implements ActionListener {

JTable table; //定义表格 DefaultTableModel dtm; //定义数据模型 Vector title=new Vector(); //表头向量 JScrollPane p1;

JPanel p2=new JPanel();

JButton b1=new JButton(\首页\); JButton b2=new JButton(\上页\); JButton b3=new JButton(\下页\); JButton b4=new JButton(\尾页\); JLabel bb=new JLabel(\); int count=0; //记录数 int pagesize=2; //页大小 int pagecount=0; //页数 int page=1; //当前页 Statement stmt;

ResultSet rs; public Student3() {

String sql=\SNo as 学号, SName as 姓名,SSex as 性别,SBir as 出try{

生日期 from xuesheng\;

stmt=Connect.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

rs=stmt.executeQuery(sql); count=getcount();

pagecount=(int)count/pagesize+(count%pagesize==0?0:1); ResultSetMetaData dbmd=rs.getMetaData(); //获得表的元数据 for(int i=1;i<=dbmd.getColumnCount();i++)

title.addElement(dbmd.getColumnName(i)); //将列名填入表 dtm=new DefaultTableModel(null,title); //建立默认的表格数 table=new JTable(dtm); //由数据模型建立表格 initTable(); //向表格中添如数据 table.setRowHeight(25); //设置表格行高 p1=new JScrollPane(table); //附加滚动条 if(pagecount!=0)

bb.setText(\第\+page+\页 b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); b4.addActionListener(this); p2.add(b1); p2.add(b2); p2.add(b3); p2.add(b4); p2.add(bb);

this.getContentPane().add(p1,\); this.getContentPane().add(p2,\);

头向量 据模型

\);

}catch(Exception e)

{ }

void initTable() {

dtm.setRowCount(0); //清空模型中的数据 try {

rs.beforeFirst(); //记录指针移到首记录之前

for(int i=1;i<1+pagesize*(page-1);i++) //将指针移到本页的第rs.next(); int j=0;

while(j

//循环,直到读完本页的记录或记录已经读完 j++;

}

this.addWindowListener(new WindowAdapter() { });

setTitle(\学生信息分页浏览\); setSize(600,400); setVisible(true);

public void windowClosing(WindowEvent e) { }

try { { }

System.exit(0);

ee.printStackTrace(); rs.close(); stmt.close(); Connect.con.close();

System.out.println(e);dispose();

}catch(SQLException ee)

一个记录

}

{ }

}

Vector v1=new Vector(); //建立行向量

for(int i=1;i<=title.size();i++) //将当前记录的各列添v1.addElement(rs.getString(i));

dtm.addRow(v1); //将行向量添加到数据模型

加到行向量

}catch(SQLException e)

e.printStackTrace();

dtm.fireTableStructureChanged(); //通知所有的listener,表格的

结构已经改变

public int getcount() { }

public void actionPerformed(ActionEvent e) {

if(e.getSource()==b1) {

page=1; //计算记录数 int n=0; try { { }

return 0; if(rs.last()) { } else

return 0;

n=rs.getRow(); rs.beforeFirst(); return n;

}catch(SQLException e)

}

}

else if(e.getSource()==b2) { }

else if(e.getSource()==b3) { }

else if(e.getSource()==b4) { }

initTable();

bb.setText(\第\+page+\页

page=pagecount; if(page1) page=page-1;

\);

public static void main(String args[]) {

JFrame.setDefaultLookAndFeelDecorated(true); Font font = new Font(\, Font.PLAIN, 14);

Enumeration keys = UIManager.getLookAndFeelDefaults().keys(); while (keys.hasMoreElements()) { }

Object key = keys.nextElement();

if(UIManager.get(key) instanceof Font) UIManager.put(key,

font);

if(!Connect.conn(\,\

{ }

JOptionPane.showMessageDialog(null,\数据库连接不成功!\); System.exit(0);

a\,\))

}

}

new Student3();

利用数据模型建立表格,对表格可以有更好地控制,数据变化的灵活性更大。TableModel是一个接口,在这个接口里面定义了若干个方法:包括了存取表格字段(cell)的内容、计算表格的列数等的基本存取操作。Java中提供了两个类实现了这个接口,一个是AbstractTableModel抽象类,一个是DefaultTableModel实体类。前者实现了TableModel的大部分方法,让用户可以很有弹性地构造自己的表格数据模型。后者继承抽象类AbstractTableModel而来,并且实现了getColumnCount()、getRowCount()与getValueAt()3个方法。因此在实际的使用上,DefaultTableModel比AbstractTableModel要简单许多。 DefaultTableModel的构造方法:

DefaultTableModel():建立一个DefaultTableModel,里面没有任何数据。 DefaultTableModel(int numRows,int numColumns):建立一个指定行列数的DefaultTableModel。

DefaultTableModel(Object[][] data,Object[] columnNames):建立一个DefaultTableModel,输入数据格式为数组。 DefaultTableModel(Object[] DefaultTableModel(Vector DefaultTableModel(Vector 法来设置数据。

DefaultTableModel的主要方法:

int getColumnCount():返回字段(列)数。

String getColumnName(int column):返回字段名称。 int getRowCount():返回数据行数。

Object getValueAt(int row,int column):返回数据某个cell中的值。 void setValueAt(Object value,int row,int column):设置某个Cell的值。 void addColumn(Object columnName):添加一空列。

void addColumn(Object columnName, Object[] columnData):添加一列,包含数据。 void addColumn(Object columnName, Vector columnData):添加一列,包含数据。

columnNames,int columnNames,int data,Vector

numRows):numRows)

::

建立建建

立立

一一一

个个个

DefaultTableModel,并具有列名称与行数信息。 DefaultTableModel,并具有列名称与行数信息。

columnNames)

DefaultTableModel,输入数据格式为Vector。系 统会自动调用setDataVector()方

void addRow(Object[] rowData):添加一行,包含数据。 void addRow(Vector rowData):添加一行,包含数据。 void removeRow(int row):删除一行。 void setRowCount(int rowCount):设置行数。

窗口上利用分割面板,将空间分成左右两部分,各放一个滚动面板。左边的滚动面板放置一个树型组件,右边的滚动面板放一个表格组件。树中的数据是从数据库中提取的。利用DefaultTreeModel建立树,通过递归函数把数据库数据自动取出添加到树中。当选择树中的结点时,右边的表格显示相应的数据。 4_4_2.jpg

树(JTree)易于表示层次结构。本案例利用树显示班级的层次结构。在树中选择某专业,表格中将显示该专业所有学生的数据;选择某年级在表格中将显示该年级所有学生的数据;选择某班级在表格中将显示该班级所有学生的数据。 案例4-7 用树浏览数据

学习利用树显示数据库数据的方法。

利用数据模型,也可以对数的结点进行维护。例如,插入结点: TreePath parentPath=tree.getSelectionPath(); if(parentPath!=null) {

DefaultMutableTreeNode newNode=new DefaultMutableTreeNode(\新结点\newNode.setAllowsChildren(true); DefaultMutableTreeNode

parentNode=(DefaultMutableTreeNode)(parentPath.getLastPathComponent());

//取得新结点的父节点

treeModel.insertNodeInto(newNode,parentNode,parentNode.getChildCount

());//插入结点

tree.scrollPathToVisible(new TreePath(newNode.getPath()));//自动展开文件夹以便显示所加入的新节点 }

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.util.*; import java.sql.*;

import javax.swing.table.*; import javax.swing.tree.*;

class ClassBrowse extends JFrame implements TreeSelectionListener { 学

Statement stmt; ResultSet rs,rs1;

DefaultTableModel dtm; //定义数据模型 String[] title ; //表头数组 JTree tree; //树 JTable table;

DefaultTreeModel treeModel=null; //定义一个默认的树模型,用于建立树 JScrollPane scroll1,scroll2; //定义两个滚动面板 JSplitPane splitPane; //定义一个分割面板 public ClassBrowse() {

stmt=ConnectServer.con.createStatement(ResultSet.TYPE_SCROLL_SENSITIV 号

DefaultMutableTreeNode root = new DefaultMutableTreeNode(\专业treeModel = new DefaultTreeModel(root); //建立树模型 initTree(root,0); //调用递归函数建立树模型 tree = new JTree(treeModel); //利用树模型建立树 scroll1=new JScrollPane(tree); tree.addTreeSelectionListener(this);

rs=stmt.executeQuery(\班级,xsda.no as ,xsda.name

as

from

xsda,classclass

where

try {

E,ResultSet.CONCUR_UPDATABLE); \根

xsda.classId=classclass.id\

ResultSetMetaData dbmd=rs.getMetaData();//得当记录集的元数据,

建立表头数组

}

void initTree(DefaultMutableTreeNode root,int id) {

//这是递归函数

DefaultMutableTreeNode node=null; //定义结点 try {

Statement }

catch(SQLException e) { }

setTitle(\分类查询学生信息\setSize(500,400); setVisible(true);

System.out.println(e);

title=new String[dbmd.getColumnCount()]; for(int i=1;i<=dbmd.getColumnCount();i++) title[i-1]=dbmd.getColumnName(i);

dtm=new DefaultTableModel(null,title); //建立表格数据模型 table=new JTable(dtm); //利用数据模型建立表格 scroll2=new JScrollPane(table); initTable(); //建立表 splitPane=new

splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(200);

this.getContentPane().add(splitPane,null);

JSplitPane(JSplitPane.HORIZONTAL_SPLIT,scroll1,scroll2);

stmt=ConnectServer.con.createStatement(ResultSet.TYPE_SCRO LL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

ResultSet rs=stmt.executeQuery(\while(rs.next()) {

int nno=rs.getInt(\取得分类ID

String nname=rs.getString(\取得分类名称

parent=\查询班级类表

}

}

node = new DefaultMutableTreeNode(nname); //建立树的结点 treeModel.insertNodeInto(node, initTree(node,nno); //递归建立子树

root,

root.getChildCount());//插入结点

}catch(Exception e){} finally { }

try { }

catch(Exception e){}

rs.close();

public void valueChanged(TreeSelectionEvent e) {

JTree tree = (JTree) e.getSource(); //利用DefaultMutableTreeNode

String name=((String)selectionNode.getUserObject());

String sql=\classclass.name as 班级,xsda.no as 学号,xsda.name if(!name.equals(\专业\

sql=sql+\and classId in (select id from classclass where rtrim(ltri

JTree

getLastSelectedPathComponent()方法取得目前选取的节点.

selectionNode=(DefaultMutableTreeNode)tree.get LastSelectedPathComponent();

as 姓名 from xsda,classclass where xsda.classId=classclass.id\

m(str(id))) like (select ltrim(rtrim(str(id)))+'%' from classclass where rt rim(ltrim(name)) ='\

}

void initTable() {

//将数据显示到表格 try {

rs=stmt.executeQuery(sql); //利用嵌套查询查出所有数据 initTable();

}catch(Exception ee){}

}

}

dtm.setRowCount(0); try { { }

dtm.fireTableStructureChanged();

e.printStackTrace(); rs.beforeFirst(); while(rs.next()) { }

Vector v1=new Vector();

for(int i=1;i<=title.length;i++) v1.addElement(rs.getString(i)); dtm.addRow(v1);

}catch(SQLException e)

public static void main(String args[]) { }

JFrame.setDefaultLookAndFeelDecorated(true); Font font = new Font(\

Enumeration keys = UIManager.getLookAndFeelDefaults().keys(); while(keys.hasMoreElements()) { }

if(!ConnectServer.conn(\{ }

new ClassBrowse();

JOptionPane.showMessageDialog(null,\数据库连接不成功!\System.exit(0);

Object key = keys.nextElement();

if (UIManager.get(key) instanceof Font) UIManager.put(key, font);

DatabaseName=xsgl\

【相关知识】

1.TreeNode

JTree上的每一个结点代表一个TreeNode对象,TreeNode本身是一个接口,定义了7个有关结点的方法,例如判断是否为树叶结点、有几个子结点(getChildCount())、父结点为何(getParent())等等。在实际的应用上,一般我们不会直接实现此接口,而是采用Java所提供的DefaultMutableTreeMode类,此类实现了MutableTreeNode接口,并提供了其他许多实用的方法。MutableTreeNode接口继承了TreeNode接口,定义一些结点的处理方方法,例如,新增结点(insert())、删除结点(remove())、设置结点(setUserObject())等。DefaultMutableTreeNode构造方法:

DefaultMutableTreeNode():建立空的DefaultMutableTreeNode对象。

DefaultMutableTreeNode(Object userObject):建立DefaultMutableTre eNode对象,结点为userObject对象。

DefaultMutableTreeNode(Object userObject,Boolean allowsChildren):建立DefaultMutableTreeNode对象,结点 为userObject对象并决定此结点是否允许具有子结点。

可以利用DefaultMutableTreeNode建立JTree。如:

DefaultMutableTreeNode root=new DefaultMutableTreeNode(\资源管理器\DefaultMutableTreeNode node1=new DefaultMutableTreeNode(\我的公文包\DefaultMutableTreeNode node2=new DefaultMutableTreeNode(\我的电脑\root.add(node1); root.add(node2);

DefaultMutableTreeNode leafnode=new DefaultMutableTreeNode(\公司文件\node1.add(leafnode);

leafnode=new DefaultMutableTreeNode(\私人文件\node1.add(leafnode);

leafnode=new DefaultMutableTreeNode(\个人信件\node1.add(leafnode);

leafnode=new DefaultMutableTreeNode(\本机磁盘(C:)\

node2.add(leafnode);

leafnode=new DefaultMutableTreeNode(\本机磁盘(D:)\node2.add(leafnode);

leafnode=new DefaultMutableTreeNode(\本机磁盘(E:)\node2.add(leafnode); JTree tree=new JTree(root);

2.DefaultTreeModel

除了以结点 (TreeNode) 的方式建立树之外,还可以用数据模型建立树。树的数据模型称为TreeModel,用此模型的 好处是可以触发相关的树事件,来处理树可能产生的一些变动。TreeModel是一个接口,里面定义了8种方法;如果 显示的数据格式很复杂,可以考虑直接实现TreeModel接口。 TreeModel接口的方法有:

void addTreeModelListener(TreeModelListener l):增加一个TreeModelListener来监控TreeModelEvent事件。 Object getChild(Object parent,int index):返回子结点。

int getChildCount(Object parent):返回子结点数量.

int getIndexOfChild(Object parent,Object child):返回子结点的索引值。 Object getRoot():返回根结点。

boolean isLeaf(Object node):判断是否为树叶结点。

void removeTreeModelListener(TreeModelListener l):删除TreeModelListener。 void valueForPathChanged(TreePath path,Object newValue):当用户改变Tree上的值时如何应对。

Java提供了一个默认的数据模型,称为DefaultTreeModel。这个类实现了TreeModel接口,并提供了许多实用的方法。 利用这个默认的数据模型,可以很方便的构造出JTree。

DefaultTreeModel构造方法:

DefaultTreeModel(TreeNode root):建立DefaultTreeModel对象,并确定根结点。 DefaultTreeModel(TreeNode root,Boolean asksAllowsChildren):建立具有根结点的DefaultTreeModel对象,并决定 此结点是否允许具有子结点。

DefaultTreeModel的主要方法:

Object getChild(Object parent, int index):由父结点和索引返回孩子。 int getChildCount(Object parent):取得孩子数。

int getIndexOfChild(Object parent, Object child) :返回孩子索引。

Object getRoot():返回根。

void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index):插入结点。

boolean isLeaf(Object node):判断是否为叶子。

void removeNodeFromParent(MutableTreeNode node) :删除结点。

4.5 预处理域存储过程

预处理是先将SQL语句预编译,这样在每次执行时,驱动程序只向数据库发送执行语 句编号和要用到的具体参数,速度比Statement快得多。

存储过程允许用任意的商业逻辑扩展SQL。存储过程在数据库中执行,所以具有很高的效率。合理地使用存储过程是优化数据库操作的关键。

案例4-8 使用语句预处理 【案例说明】

本案例演示使用语句预处理对学生档案进行数据查询,运行界面如图4—6所示。可以

按性别和地址查询学生信息。

图4—6 使用预处理查询学生信息界面 [技术要点]

以带参SQL语言为参数,创建预处理(PreparedStatement)对象,再利用预处理对象的方法设置查询条件。执行查询,查询结果显示在表格中。 [代码与注释]

以带参的SQL语言为参数,创建预处理(PreparedStatement)对象,再利用预处理对象的方法设置查询条件。执行查询,查询结果显示在表格中。 4_5_1.jpg

本案例演示使用语句预处理对学生档案进行数据查询。可以按性别和地址查询学生信息。

案例4-8 使用语句预处理

学习使用预处理进行数据操作的方法。

使用预处理不仅可以查询数据,也可以实现删除和修改数据。

//案例4-8 使用语句预处理

import java.awt.*; import java.sql.*; import java.awt.event.*; import javax.swing.*; import java.util.*;

import javax.swing.table.*;

class ParameterQuery extends JFrame implements ActionListener {

JTable table; //定义表格

DefaultTableModel dtm; //定义数据模型 Vector title=new Vector(); JPanel p1=new JPanel(); JScrollPane p2;

JButton ok=new JButton(\查询\JLabel L1=new JLabel(\性别:\JLabel L2=new JLabel(\地址:\JComboBox combSex=new JComboBox(); JTextField txtAddr=new JTextField(20); PreparedStatement pstmt; //定义预处理对象 ResultSet rs;

public ParameterQuery() {

pstmt=ConnectServer.con.prepareStatement(sql,ResultSet.TYPE_SCROLL_SEN

String sql=\no as 学号, name as 姓名,sex as 性别,address as 地try {

址 from xsda where sex like ? and address like ?\

SITIVE,ResultSet.CONCUR_READ_ONLY);//利用连接对象创建预处理对象

{ }

pstmt.setString(1,\设置查询条件 pstmt.setString(2,\设置查询条件 rs=pstmt.executeQuery();

ResultSetMetaData dbmd=rs.getMetaData(); //获得表的元数据 for(int i=1;i<=dbmd.getColumnCount();i++)

title.addElement(dbmd.getColumnName(i)); //将列名填入表头dtm=new DefaultTableModel(null,title); table=new JTable(dtm); initTable();

table.setRowHeight(20); p2=new JScrollPane(table); combSex.addItem(\所有\combSex.addItem(\男\combSex.addItem(\女\p1.add(L1); p1.add(combSex); p1.add(L2); p1.add(txtAddr); p1.add(ok);

ok.addActionListener(this);

this.getContentPane().add(p1,\this.getContentPane().add(p2,\

向量

}catch(Exception e)

e.printStackTrace(); dispose();

this.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

try {

rs.close(); pstmt.close();

}catch(SQLException ee)

}

});

}

{ }

ee.printStackTrace();

setTitle(\按性别和地址查询学生信息\setSize(600,400); setVisible(true);

void initTable() { }

public void actionPerformed(ActionEvent e) {

if(e.getSource()==ok) {

String sex=(String)combSex.getSelectedItem(); String addr=txtAddr.getText(); try {

if(sex.equals(\所有\

dtm.setRowCount(0); try { { }

dtm.fireTableStructureChanged();

e.printStackTrace(); rs.beforeFirst(); while(rs.next()) { }

Vector v1=new Vector();

for(int i=1;i<=title.size();i++) v1.addElement(rs.getString(i)); dtm.addRow(v1);

}catch(SQLException e)

}

}

}

pstmt.setString(1,\else

pstmt.setString(1,sex); if(addr.equals(\ pstmt.setString(2,\else

pstmt.setString(2,addr+\rs=pstmt.executeQuery();//执行查询

}catch(SQLException ee){}

initTable();

public static void main(String args[]) {

JFrame.setDefaultLookAndFeelDecorated(true); Font font = new Font(\

Enumeration keys = UIManager.getLookAndFeelDefaults().keys(); while (keys.hasMoreElements()) { }

Object key = keys.nextElement();

if(UIManager.get(key) instanceof Font)UIManager.put(key, font);

if(!ConnectServer.conn(\ }

{ }

ParameterQuery mainFrame = new ParameterQuery();

JOptionPane.showMessageDialog(null,\数据库连接不成功!\System.exit(0);

baseName=xsgl\

【相关知识】

PreparedStatement是SQL预处理类,使用这个类来处理SQL能大大提高系统的执行效

率。PreparedStatement对象可以将SQL语句预编译,这样在每次执行时,驱动程序只向数据库发送执行语句编号和要用到的具体参数,速度比Statement快得多。如果向网络数据发出SQL请求,它传输的数据量比Statement小很多。特别是,它可以实现参数查询。创建PreparedStatement对象,要使用Connection对象的PrepareStatement()方法。如:

PreparedStatement pstmt=con.PreparedStatement(“select * from student where no=? and name=? ”);

其中,?标出了参数。使用时,使用格式如setXXX()的方法进行设置。XXX是与参数相对应的类型。这类方法的参 数有两个,第一个是SQL中参数的索引(第一个为1),第二个是所要赋的值。如: pstmt.setInt(1,2);

pstmt.setString(2,”王军”); pstmt.executeQuery();

与Statement类似,PreparedStatement也可以使用delete,update,insert类型的SQL。在建立PreparedStatement 时,也指定游标类型和记录集的并发特性。如: pstmt=con.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);

案例4-9 调用存储过程 【案例说明】

存储过程是在数据库中定义的对象。存储过程在数据库中执行,具有很高的效率。 Java提供了调用存储过程的机制。本案例调用存储过程查询学生成绩,运行界面如图4—7 所示。

图4-7 使用存储过程查询学生成绩界面

在SQL Server中建立如下两个存储过程: create procedure getCourseName as select

distinct

course.courseName

create

from procedure

grade,course stat

where

grade.courseID=course.courseID declare @count int

select @count=count(*),@avgGrade=avg(grade) from xsda,grade,course where xsda.no=grade.no and grade.courseID=course.courseID and course.cour seName like @courseName

@courseName

nchar(20),@avgGrade float output as begin

select xsda.no as 学号,xsda.name as 姓名,grade.grade as 成绩 from xsda,g rade,course where xsda.no=grade.no and grade.courseID=course.courseID and course.courseName like @courseName return @count end

利用Connection对象的prePareCall()方法创建CallableStatement对象。创建后,再利用该对象的形如setXXX()的方法 设置输入参数,利用registerOutputParameter()方法注册返回参数和输入参数。然后,调用executeQuery()执行查询, 并将查询结果显示在表格中。

4_5_2.jpg

存储过程是在数据库中定义的对象。存储过程是在数据库中执行,所以具有很高的效率。Java提供了调用存储过程的机制。本案例调用存储过程查询学生成绩。 学习使用存储过程的方法。

使用存储过程可以提高数据库操作的速度和效率。合理设计存储过程需要学习数据库的知识。下面是SQL Server 存储过程的一般格式:

CREATE PROC [ EDURE ] procedure_name [ ; number ] [ { @parameter data_type } [ VARYING ] [ = default ] [ OUTPUT ]] [ ,...n ] [ WITH { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] [ FOR REPLICATION ] AS sql_statement [ ...n ]

import java.awt.*; import java.sql.*; import java.awt.event.*; import javax.swing.*; import java.lang.*; import java.util.*;

import javax.swing.table.*;

class StoredProcedure extends JFrame implements ItemListener {

JTable table;//定义表格

DefaultTableModel dtm;//定义数据模型 DefaultComboBoxModel dcm; Vector title=new Vector(); JPanel p1=new JPanel(); JScrollPane p2; JComboBox comb;

JLabel L1=new JLabel(\请选择课程名称\JLabel L2=new JLabel(\考试人数: \

JLabel L3=new JLabel(\平均分: \CallableStatement cstmt1;//用于查询课程名 CallableStatement cstmt2;//用于查询成绩 ResultSet rs1; ResultSet rs2;

public StoredProcedure() {

cstmt2=ConnectServer.con.prepareCall(\

cstmt2.registerOutParameter(1,java.sql.Types.INTEGER); //登记cstmt2.setString(2,(String)comb.getSelectedItem()+\设置cstmt2.registerOutParameter(3,java.sql.Types.FLOAT); //登rs2=cstmt2.executeQuery(); //执行该存储过ResultSetMetaData dbmd=rs2.getMetaData(); //获得表的元数据 for(int i=1;i<=dbmd.getColumnCount();i++)

title.addElement(dbmd.getColumnName(i)); //将列名填入表头dtm=new DefaultTableModel(null,title); table=new JTable(dtm); initTable();

int count= cstmt2.getInt(1); //获取返回值

float avgGrade=Math.round(cstmt2.getFloat(3)*100f)/100.0f;//获table.setRowHeight(20); L2.setText(\考试人数:\try {

cstmt1=ConnectServer.con.prepareCall(\getCourseName()}\rs1=cstmt1.executeQuery(); dcm=new DefaultComboBoxModel(); comb=new JComboBox(dcm); initComboBox();

E_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); 返回参数 输入参数 记输出参数

向量

取输出参数的值

本文来源:https://www.bwwdw.com/article/ln9w.html

Top