数据库与JDBC技术
2007-06-13
JDBC技术工作原理:
JDBC是JAVA数据库连接(Java DataBase Connectivity)技术的简称,是为各种常用数据库提供无缝连接的技术。它由一些Java语言编写的类和界面组成。JDBC为数据库应用开发人员、数据库前台工具开发人员提供了一种标准的应用程序设计接口,使开发人员可以用纯 Java语言编写完整的数据库应用程序。JDBC是一种低级的API
JDBC的两个程序包:
Java.sql(核心API)
Javax.sql (扩展API)
JDBC和ODBC及其他API的比较
1.) ODBC不适合在Java中直接使用,因为它是一个C语言实现的API,从Java程序调用本地的C程序会在安全性、完整性、健壮性方面都有许多缺点。
2.)不能完全精确地实现从ODBC,C,API到Java API的翻译。
3.)ODBC很难学,它把简单和高级功能混杂在一起,甚至对非常简单的查询,其选项也非常复杂。而JDBC恰好相反,其尽量保证简单功能的简便性,而同时在必要时允许使用高级功能。
4.)启用纯Java需要象JDBC这样的Java API.
JDBC中常用的类和接口:
Class类:
java.sql DriverManager: 类.驱动管理
java.sql Connection:接口获得连接
java.sql Statement接口(PreparedStatement):得到语句对象
java.sql RelultSet接口(结果集).表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
通过JDBC访问数据库步骤:
1.加载驱动程序:Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”)
2.获得连接: Connection con=DriverManger.getConnection(“jdbc:odbc:qq“,” 用户名”,“密码”)
3.得到语句对象://作用向数据库发送语句对象
Statement stmt=con.createStatement();
4. 得到结果: RelustSet rs=stmt. ExecuteQuery (“ select * from student ”)//执行查询
ResultSet 对象的常用方法
返回类型 | 方法名称 |
boolean | next() |
byte | getByte(int columnIndex) |
Date | getDate(int columnIndex) |
double | getDouble(int columnIndex) |
float | getFloat(int columnIndex) |
int | getInt(int columnIndex) |
long | getLong(int columnIndex) |
String | getString(int columnIndex) |
byte | getByte(String columnName) |
Date | getDate(String columnName) |
double | getDouble(String columnName) |
float | getFloat(String columnName) |
int | getInt(String columnName) |
long | getLong(String columnName) |
String | getString(String columnName) |
例:
|
//加载驱动:
import java.sql.*;
class mysql
{
public static void main(String args[])
{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加载桥连驱动
con=DriverManager.getConnection("jdbc:odbc:qq","sa","");// /url,建立数据库的连接
stmt=con.createStatement();//得到语句对象
rs=stmt.executeQuery("select * from student");//获得结果
while(rs.next())//显示结果
{
int id=rs.getInt(1);
String name=rs.getString(2);
String pwd=rs.getString(3);
System.out.println (id+" "+name+" "+pwd);
}
}
catch (Exception e)
{
System.out.println (e.getMessage());//返回此 throwable 的详细消息字符串。
}
finally//这样不管try模块中是否发生异常,都能保证对象的关闭
{
try{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch (Exception e)
{
e.getStackTrace();
}
}
}
}//结果如下
配置数据源
点。点石。。。 |
1111111111111111111111111111
import java.sql.*;
class mysql
{
public static void main(String args[])
{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加载桥连驱动
con=DriverManager.getConnection("jdbc:odbc:qq","sa","");// /url,建立数据库的连接
//qq为数据源名称
stmt=con.createStatement();//得到语句对象
// int flag=stmt.executeUpdate("delete student where id in(7)");//获得结果
//int flag=stmt.executeUpdate("INSERT student values(2,'cc','987')");//获得结果
int flag1=stmt.executeUpdate("insert student(id,name,pass) values(1,'rff','7839')");
int flag2=stmt.executeUpdate("insert student(id,name,pass) values(2,'bff','4536')");
int flag3=stmt.executeUpdate("insert student(id,name,pass) values(3,'cff','1233')");
//int flag4=stmt.executeUpdate("insert student(name,pass) values('dd','678')");
// System.out.println (flag1);
// System.out.println (flag2);
// System.out.println (flag3);
// System.out.println (flag4);
}
catch (Exception e)
{
System.out.println (e.getMessage());//返回此 throwable 的详细消息字符串。
}
finally//这样不管try模块中是否发生异常,都能保证对象的关闭
{
try{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch (Exception e)
{
e.getStackTrace();
}
}
}
}
---------------
例:向数据库中更新数据 stmt.executeUpdate("insert student(name,pass) values('dd','678')");
--create database text
--use text
create table student--
(
id int primary key,
name char (20),
pass char(20)
)
select * from student
insert student (id,name,pass) values(4,'aa','456')
import java.sql.*;
class mysql
{
public static void main(String args[])
{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
try
{
//直连
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
con=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=text","sa","");// /url,建立数据库的连接
stmt=con.createStatement();//得到语句对象
//int flag=stmt.executeUpdate("insert into student where id=4");//获得结果
//int flag=stmt.executeUpdate("INSERT student values(2,'cc','987')");//获得结果
//int flag1=stmt.executeUpdate("insert into student(id,name,pass) values(6,'bb','111')");
//int flag2=stmt.executeUpdate("insert student(id,name,pass) values(2,'bff','4536')");
//int flag3=stmt.executeUpdate("insert student(id,name,pass) values(3,'cff','1233')");
//int flag4=stmt.executeUpdate("insert student(name,pass) values('dd','678')");
//System.out.println (flag1);
// System.out.println (flag2);
// System.out.println (flag3);
// System.out.println (flag4);
}
catch (Exception e)
{
System.out.println (e.getMessage());//返回此 throwable 的详细消息字符串。
}
finally//这样不管try模块中是否发生异常,都能保证对象的关闭
{
try{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch (Exception e)
{
e.getStackTrace();
}
}
}
}
例:实现在窗口中添加数据并由数据库接收数据
|
Java代码:
import javax.swing.*;
import java.awt.*;
import java.sql.*;
import java.awt.event.*;
class Registration implements ActionListener
{
static JFrame frame;
static JPanel panel;
JLabel labelFName;
JLabel labelLName;
JLabel labelAddress;
JLabel labelAccType;
JLabel labelPhone;
JLabel labelAnnualIncome;
JTextField textFName;
JTextField textLName;
JTextField textAddress;
JComboBox comboAccType;
JTextField textPhone;
JTextField textAnnualIncome;
JButton buttonAccept;
String[]AccType={"Current","Savings","Credit"};
public static void main(String args[])
{
new Registration();
}
public Registration()
{
panel =new JPanel();
frame=new JFrame("Customer Registration");
frame.setSize(300,300);
frame.setVisible(true);
frame.getContentPane().add(panel);
labelFName=new JLabel("First Name");
labelLName=new JLabel("Last Name");
labelAddress=new JLabel("Address");
labelAccType=new JLabel("Accont Type");
labelPhone=new JLabel("Phone Number");
labelAnnualIncome=new JLabel("Annual Income");
textFName=new JTextField(15);
textLName=new JTextField(15);
textAddress=new JTextField(30);
comboAccType=new JComboBox(AccType);
textPhone=new JTextField(10);
textAnnualIncome=new JTextField(10);
panel.add(labelFName);
panel.add(textFName);
panel.add(labelLName);
panel.add(textLName);
panel.add(labelAddress);
panel.add(textAddress);
panel.add(labelAccType);
panel.add(comboAccType);
panel.add(labelPhone);
panel.add(textPhone);
panel.add(labelAnnualIncome);
panel.add(textAnnualIncome);
buttonAccept=new JButton("SUBMIT");//提交按键
panel.add(buttonAccept);
buttonAccept.addActionListener(this); //注册监听
}
public void actionPerformed(ActionEvent e)//监听方法
{
Object source=e.getSource();
if(source ==buttonAccept)
{
try
{
//桥连
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con;
con=DriverManager.getConnection("jdbc:odbc:yy","sa","");
//表示预编译的 SQL 语句的对象可以使用此对象高效地多次执行该语句
PreparedStatement stat2=con.prepareStatement("insert into Registration(cFirst_name,cLast_name,cAddress,cAccount_type,cPhone_no,mAnnual_income)values(?,?,?,?,?,?)");
stat2.setString(1,textFName.getText());
stat2.setString(2,textLName.getText());
stat2.setString(3,textAddress.getText());
stat2.setString(4,(String)comboAccType.getSelectedItem());
stat2.setString(5,textPhone.getText());
stat2.setFloat(6,Float.parseFloat(textAnnualIncome.getText()));
stat2.executeUpdate();//执行向数据库更新数据,该语句必须是一个 SQL INSERT、UPDATE 或 DELETE 语句##
JOptionPane.showMessageDialog(frame,new String("已经提交"));
}
catch(Exception exception)
{
JOptionPane.showMessageDialog(frame,new String("Error encountered while entering date in the datebase:")+exception); // JOptionPane要求用户提供值或向其发出通知的标准对话框
}
}
}
}
我的JDBC-ODBC桥接方法:先创建数据源,上面有详细图片##
|
结果集元数据
接口ResultSetMetaData:可根据结果集ResultSet对象得到相应列的类型和属性信息的对象。
例:ResultSetMetaData ##
import java.sql.*;
public class Test{
public static void main(String[] args)
{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
try
{ //桥连
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection("jdbc:odbc:qq","sa","");
stmt = con.createStatement();//语句对象
rs = stmt.executeQuery("SELECT * FROM student");
while(rs.next())
{
int id = rs.getInt(1);
String name= rs.getString(2);
String pwd = rs.getString(3);
System.out.println(id+" "+name+" "+pwd);
}
//以下用于获取关于 ResultSet 对象中列的类型和属性信息的对象##
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns =rsmd.getColumnCount();////获得列数
System.out.println (numberOfColumns);//输出列数
for(int i=1;i<=numberOfColumns;i++)
{
String columnName=rsmd.getColumnName(i);//获得ID列名##
System.out.print("列名:"+columnName);
String columnType=rsmd.getColumnTypeName(i);//获得列类型##
System.out.println(" 列类型:"+columnType);
}
}//end try
catch(Exception e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}
catch(Exception e)
{
e.getStackTrace();
}
}
}
}
JDBC2.0的新特性
新特性:
1. ResultSet 对象中的光标能自由上下移动。
2. 能直接使用JAVA程序语言更新数据库表格的内容,而不需写SQL法。
3. 也可进行数据库的批处理操作。
如何设置可滚动的结果ResustSet?
实际有三个参数 但性能一个比一个差,因为它要将数据取出到内存后再移动指针来读取,所以不建议使用,除非你要操作的数据较少,可以采用;如果数据较大,决对不要使用。
例:
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
//得到语句对象
// 声明结果集可上下移动
stmt =
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY) ;
例:在结果集中 使用游标倒序输出所有记录:
|
//java代码:
import java.sql.*;
class mysql
{
public static void main(String args[])
{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加载桥连驱动##
con=DriverManager.getConnection("jdbc:odbc:qq","sa","");// url,建立数据库的连接##
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);//得到语句对象
rs=stmt.executeQuery("select * from student");//获得查询的结果集##
//rs.absolute(5);//指针的决对位置##
rs.afterLast(); //最后一条记录##
while( rs.previous())//##数据库上一条记录注意不要在此加分号,否则后果。。我都疯了,查了
3个小时rs.next()为下一条##
{
int id=rs.getInt(1);
String name=rs.getString(2);
String pass=rs.getString(3);
System.out.println(id+""+name+""+pass);
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}
catch(Exception e)
{
e.getStackTrace();
}
}
}
}
批处理Batch
6/15/07
批处理Batch:DBC2.0提供批处理的操作,可以让一个Statement同时执行多个SQL语句,以提高性能。
事务处理:要么全部执行,要么全部失败。有效的保证数据的完事性。
流程: 先取消自动提交(conn.setAutoCommit(false))è执行批处理è有无异常,有则回滚,无则提交。
例:批处理解析:此题要注意的是,当你故意写错一个SQL语句时,如少个引号,你会发现所有的数据都没有插入进行了回滚。
|
import java.sql.*;
class mysql
{
public static void main(String args[])
{
Connection con=null;
Statement stmt=null;
ResultSet rs=null;
try
{
// Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
//con=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=text","sa","");// /url,建立数据库的连接
//加载桥连驱动
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//url,建立数据库的连接
con=DriverManager.getConnection("jdbc:odbc:qq","sa","");
//先取消自动提交##
con.setAutoCommit(false);
stmt=con.createStatement();
//书写批处理SQL语句;
stmt.addBatch("insert into student (id,name,pass) values(11, 'ddr','123ff')");
stmt.addBatch("insert into student (id,name,pass) values(12,'dred','15665')");
stmt.addBatch("insert into student (id,name,pass) values(13,'ddr','44443')");
stmt.addBatch("insert into student (id,name,pass) values(14,'dred','15665')");
stmt.executeBatch();//执行批处理语句
// 如果没有异常,则执行此段代码
con.commit(); // 提交事务,真正向数据库中插入数据
System.out.println("成功写入数据" );
}
catch (Exception e)
{
//将数据回流
try{
System.out.println ("操作失败");
con.rollback();
}
catch(Exception e1)
{
System.out.println (e1.getMessage());
}
}
finally//这样不管try模块中是否发生异常,都能保证对象的关闭
{
try{
//if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch (Exception e)
{
System.out.println ("关闭失败");
e.getStackTrace();
}
}
}
}
当有错误时:运行结果如下 注意下面的关闭失败,是因为我们没有用到结果集rs.close();
当没有发生错误时:数据库中有了新增的数据。