JDBC对数据库的基本操作

第N章 使用数据库


N.1 连接数据库

N.2 执行SELECT语句

N.3 执行DML语句

N.4 参数化SQL

N.5 使用存储过程

N.6 使用事务

N.7 操作大数据字段


N.1 连接数据库

连接数据库时,需要数据库厂商提供的JAVA引擎,这实在是一个比较无奈的事情。

连接数据库的语法如下所示:

import  java.sql.Connection;
import  java.sql.DriverManager;
...
Class.forName(
" 类名 " ).newInstance();
Connection con 
=  DriverManager.getConnection( " 连接字符串 " " 用户名 " " 口令 " );

 

下表提供了常用数据库的JAVA引擎及连接字符串

数据库驱动提供者驱动类连接字符串
SQL Server Microsoftcom.microsoft.jdbc.sqlserver.SQLServerDriverjdbc:microsoft:sqlserver://服务器名或IP:端口号(默认为1433);
DatabaseName=pubs;
SelectMethod=cursor
jTDSnet.sourceforge.jtds.jdbc.Driverjdbc:jtds:sqlserver://服务器名或IP:端口号(默认为1433)/数据库名
ORACLEOracleoracle.jdbc.driver.OracleDriverjdbc:oracle:thin:@服务器名或IP:端口号(默认为1521):数据库SID
ODBCSunsun.jdbc.odbc.JdbcOdbcDriverjdbc:odbc:数据源名称

下面是一个连接本地SQL SERVER的pubs库的程序:

import  java.sql.Connection;
import  java.sql.DriverManager;
...
Class.forName(
" com.microsoft.jdbc.sqlserver.SQLServerDriver " ).newInstance();
Connection con 
=  DriverManager.getConnection(
    
" jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=pubs;SelectMethod=cursor "
    
" sa "
    
" sa " );

 

N.1.1 SQL Server


如果要使用Windows 身份验证方式连接SQL Server,使用微软的开发包我还没找出来,使用jTDS的话,连接字符串可以这样写:

Connection connection  =  
    DriverManager.getConnection(
        
" jdbc:jtds:sqlserver://localhost:1433/pubs;domain=a "
        
" administrator "
        
" liulindong " );

 

 

因为我的电脑不在域中,所在domain我是随便写的,但不能为空,后面两个参数是windows的用户名和口令,呵呵。

N.2 执行SELECT语句

下面是一个简单的例子,它连接本机的SQL SERVER pubs库,输出authors表的全部内容。

package  example;

import  java.sql.Connection;
import  java.sql.DriverManager;
import  java.sql.ResultSetMetaData;
import  java.sql.ResultSet;
import  java.sql.Statement;

public   class  Test  {
    
    
public static void main(String[] args) throws Exception
    
{
        Class.forName(
"com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
        Connection con 
= DriverManager.getConnection(
            
"jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=pubs;SelectMethod=cursor"
            
"sa"
            
"sa");
        Statement st 
= con.createStatement();
        String sql 
= "select * from authors";
        ResultSet rs 
= st.executeQuery(sql);
        ResultSetMetaData meta_data 
= rs.getMetaData();
        
        
for(int i_col = 1; i_col <= meta_data.getColumnCount(); i_col++)
        
{
            System.out.print(meta_data.getColumnLabel(i_col) 
+ " ");
        }

        System.out.println();
        
        
while(rs.next())
        
{
            
for(int i_col = 1; i_col <= meta_data.getColumnCount(); i_col++)
            
{
                System.out.print(rs.getString(i_col) 
+ " ");
            }

            System.out.println();
        }

        rs.close();
        st.close();
    }


}

 

从上例中,我们可获知如下几点内容:

  1. 使用java.sql.Statement.executeQuery来执行SELECT语句
  2. 它返回一个ResultSet类型,使用next()方法遍历
  3. 使用ResultSetMetaData来获取结果集的一些统计信息,如列名、列数、列类型等
  4. 使用ResultSetMetaData和ResultSet的get*()类的成员函数时,如果以整数值作为索引,则索引值从1开始。

注意:ResultSet没有提供方法可以获取结果集的记录条数,所以,如果想要获取记录条数,需要使用count()函数自己去查。网上有些人提出的所谓解决方法并不好用,说明如下:

  1. 使用ResltSet.last()和ResultSet.getRow()以获取记录条数,但很可惜,有些JDBC的驱动并不实现last()函数,例如JDBC-ODBC、SQL Server,其实这些JDBC驱动不实现除next()外的所有的定位操作,包括:first()、last()、previous()、absolute()等
  2. 使用对next()方法进行计数,方法可行,但且不说效率如何,只说我们获取了结果集,并不是只是为了得到一个结果集记录条数的。循环完了,我们怎么回去呢,因为对某些JDBC驱动,可并不提供first()方法哦。

N.3 执行DML语句

使用Statement.executeUpdate()方法或Statement.execute()方法

N.4 参数化SQL

使用PreparedStatement对象

PreparedStatement pstmt  =  con.prepareStatement( " UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ? " );
pstmt.setBigDecimal(
1 153833.00 )
pstmt.setInt(
2 110592 )

 

N.5 使用存储过程

N.5.1 带返回参数的存储过程

针对如下的表:

create   table  test_table(a  int , b  int

 

有如下存储过程

create   procedure   [ sp_test ]
    
@a   int @b   int @count   int  output
with  recompile
as
    
set  nocount  on
    
insert   into  test_table(a, b)  values ( @a @b )
    
select   @count   =   count ( * from  test_table
go

 

Java的示例代码如下所示:

import  java.sql. * ;
...
Connection conn 
=  ...;     // 获取Connection
String sql  =   " exec sp_test ?, ?, ? " ;
CallableStatement st 
=  conn.prepareCall(sql);
st.setInt(
1 10 );     // 设置输入参数
st.setInt( 2 10 );
st.registerOutParameter(
3 , Types.INTEGER);     // 设置输出参数
st.execute();
System.out.println(st.getInt(
3 ));         // 获取输出参数的值

 

N.5.2 返回结果集的存储过程

这个简单,直接使用executeQuery()即可。也不一定用CallableStatement对象,Statement(如果没参数)和PrepareStatement均可。

N.6 使用事务

一般使用的步骤如下所示:

Connection conn  =  ...;      // 获取Connection对象
conn.setAutoCommit( false );     // 取消自动提交
try
{
    ...(数据库操作)
    conn.commit();    
//提交更改
}

catch (Exception ex)
{
    conn.rollback();    
//回滚事务
    ex.printStackTrace();
}

conn.setAutoCommit(
true );     // 恢复自动提交

 

N.7 操作大数据字段

大数据字段是指ORACLE下的BLOB、CLOB,SQL Server下的image、text等类型的字段。

N.7.1 示例表

假设有如下的SQL SERVER表

create   table  test_table(id  int , content  image )

 

N.7.2 引用的类

import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.InputStream;
import  java.sql.Connection;
import  java.sql.DriverManager;
import  java.sql.PreparedStatement;
import  java.sql.ResultSet;
import  java.sql.Statement;

N.7.2 插入

Connection connection  =  ...     // 获取连接
String sql;
sql 
=   " insert into test_table(id, content) values(?, ?) " ;
PreparedStatement st 
=  connection.prepareStatement(sql);
st.setInt(
1 20 );
String file_path 
=   " c:/1.xls " ;     // 要读取的文件

// 获取文件长度并分配空间
File f  =   new  File(file_path);
byte [] data  =   new   byte [( int )f.length()];

// 读取文件内容并插入
FileInputStream fs  =   new  FileInputStream( " c:/1.xls " );
fs.read(data);
st.setObject(
2 , data);
st.executeUpdate();
fs.close();

N.7.3 读取

Connection connection  =  ...     // 获取连接
String sql  =   " select content from test_table where id = 10 " ;
Statement st2 
=  connection.createStatement();
ResultSet rs 
=  st2.executeQuery(sql);
rs.next();
InputStream outStream 
=  rs.getBinaryStream( 1 );
FileOutputStream fw 
=   new  FileOutputStream( " c:/2.xls " false );     // 输出到c:.xls
int  buf_len  =   1024 ;
byte [] out_buf  =   new   byte [buf_len];
int  read_len  =  outStream.read(out_buf);
while (read_len  >   0 )
{
    fw.write(out_buf, 
0, read_len);            
    read_len 
= outStream.read(out_buf);
}

fw.flush();
fw.close();
outStream.close();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值