1JDBC
JDBC(Java DataBase Connection)是Java运行平台的核心类库中的一部分,提供了访问数据库的API,它由一些Java类和接口组成。在JSP中可以使用JDBC实现对数据库中表记录的查询、修改和删除等操作。使用JDBC的应用程序一旦和数据库建立连接,就可以使用JDBC提供的API操作数据库。
经常使用JDBC进行如下操作:
与一个数据库建立连接。
向已连接的数据库发送SQL语句。
处理SQL语句返回的结果。
连接数据库的常用方式:
应用程序为了能和数据库交互信息,必须首先和数据库建立连接。建立JDBC-ODBC桥接器和加载纯Java数据库,这两种方式都有各自优势。
*********JDBC-ODBC桥接器************
使用JDBC-ODBC桥接器方式的机制是,应用程序只需建立JDBC和ODBC之间的连接,即所谓的建立JDBC-ODBC桥接器,而和数据库的连接有ODBC去完成。
JDBC-ODBC桥接器的优点是:ODBC(Open DataBase Connectivity)是Microsoft引进的数据库连接技术,提供了数据库访问的通用平台,而且ODBC驱动程序被广泛的使用。建立这种桥接器后,使得JDBC有能力访问几乎所有类型的数据库。缺点是:使得应用程序依赖于ODBC,移植性较差,应用程序所驻留的计算机必须提供ODBC。
应用程序负责使用JDBC提供的API建立JDBC-ODBC桥接器,然后应用程序可以请求和数据库建立连接,连接工作由ODBC完成。ODBC使用数据源来管理数据库,所以必须事先将某个数据库设置称ODBC所管理的一个数据源,应用程序只能请求和ODBC管理的数据源建立连接。
使用JDBC-ODBC桥接器访问数据库的3个步骤:
建立JDBC-ODBC桥接器
创建ODBC数据源
和ODBC数据源建立连接
建立JDBC-ODBC桥接器
JDBC使用java.lang包中的Class类建立JDBC-ODBC桥接器。Class类通过条用它的静态方法forName加载sun.jdbc.odbc包中JdbcOdbcDriver类建立JDBC-ODBC桥接器。建立桥接器可能发生异常,必须捕获这个异常,建立桥接器的代码:
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}catch(ClassNotFoundException e){
System.out.println(e);
}
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//load the JDBC driver
Connection con=DriverManager.getConnection("jdbc:odbc:oracletest","MILS","mil3068");
创建ODBC数据源
必须保证应用程序所在计算机有ODBC系统。“控制面板”->“管理工具”->"ODBC数据源",选择"用户DSN",单击"添加"按钮添加数据源。
和ODBC数据源指定的数据库建立连接
编写连接数据库代码不会出现数据库的名称,只会出现数据源的名字。首先使用java.sql包中的Connection类声明一个对象,然后在使用DriverManager调用它的静态方法getConnection创建这个连接对象。
try{
Connection con=DriverManager.getConnection("jdbc:odbc:数据源名字","login name","password");
}catch(SQLException e){}
假如没有为数据源设置login name和password,那么连接形式是:
try{
Connection con=DriverManager.getConnection("jdbc:odbc:数据源名字","","");
}catch(SQLException e){}
例:
import java.sql.*;
public class testdata{
public static void main(String args[]){
String name;
String query="SELECT to_char(sum(m_act)/1000,‘9,999,999,999‘)t_m_act FROM m_fulltable where lot_type=‘P‘ "+
"and time_of_run=to_date(‘20081009‘,‘yymmdd‘) and substr(m_fulltable.mils_code,1,1)=‘A‘";
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//load the JDBC driver
Connection con=DriverManager.getConnection("jdbc:odbc:oracletest","MILS","mil3068");
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(query);//execute SQL查询
while(rs.next()){//get data from ResultSet
name=rs.getString("t_m_act");
System.out.println(name);
}
con.close();
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}}}
2使用纯Java数据库驱动程序方式和数据库建立,连接需要两个步骤:
加载纯Java驱动程序
和指定的数据库建立连接
加载纯Java数据库驱动程序:
与JDBC-ODBC桥接器方式不同的是,使用纯Java数据库驱动程序访问数据库不需要设置数据源,使用纯Java数据库驱动程序访问数据库时,必须要保证连接数据库的应用程序所驻留的计算机上安装有相应DBMS提供的纯Java数据驱动程序。
************************************
JDBC连接Microsoft SQL Server
(1)将sqljdb.jar该软件包复制到Tomcat服务器所使用的JDK的\jre\lib\ext文件夹中或Tomcat服务器安装目录的\common\lib文件夹中
(2)在安装sql server2000的数据库服务器上将它升级到sp3。sql server 2000 sp3升级包是sql2ksp3.exe。 你可以在这里下载http://www.bossed.com.cn/download/detailcp.asp?id=74
安装好以后执行安装目录下的setup.bat进行升级。
(3)在web服务器上安装sql server 2000 jdbc 驱动.
下载SQLSERVER2000的jdbc驱动程序
http://download.microsoft.com/download/3/0/f/30ff65d3-a84b-4b8a-a570-27366b2271d8/setup.exe
安装好以后将安装目录C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib下的三个包msbase.jar,mssqlserver.jar,msutil.jar复制到web项目的lib目录下。
应用程序加载SQL Server驱动程序代码如下:
try{ Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
}catch(Exception e){}
和指定的数据库建立连接
try{
Connection conn=DriverManager.getConnection("jdbc:sqlserver://SQLserver主机IP:端口号;DatabaseName=要连接的数据库名称","用户名","密码");
}catch(SQLException e){}
如果SQL server主机的IP地址给错,则会报出以下错误:
SQLSever2000 Driver for JDBCError establishing socket
例如:
<%@ page contentType="text/html;Charset=UTF-8"%>
<%@ page import="java.sql.*"%>
<html>
<head>
</head>
<body>
<%
response.setCharacterEncoding("UTF-8");
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String uri="jdbc:sqlserver://10.93.13.155:1433;DatabaseName=UserRegistration";
String user="sa";
String password="happy0000";
Connection con=DriverManager.getConnection(uri,user,password);
try{
Statement statement=con.createStatement();
ResultSet rs=statement.executeQuery("select * from bbs_T");
while(rs.next()){
out.println(rs.getString("bbsTitle"));
}
}catch(SQLException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
con.close();
}
%>
</body>
</html>
如果sql server2000没有升级到sql server2000sp3则会出现以下错误:
java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket.
******************************
JDBC连接oracle
对于连接Oracle,安装Oracle后,找到目录C:\oracle\ora81\jdbc\lib中的文件classes12.zip,将该文件复制到Tomcat所使用的JDK的子目录/jre/lib/ext中和Web项目的lib目录下,并将classes12.zip重新命名为classes.jar。
应用程序加载Oracle驱动程序:
Class.forName("oracle.jdbc.driver.OracleDriver");
可以查看本机要连接的各个oracle服务器的名称,端口,sid
C:\oracle\ora81\network\ADMIN\tnsnames.ora
和指定的数据库建立连接
try{
Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@主机host:端口号:sid","用户名","密码");
}catch(SQLException e){}
例如:
Class.forName("oracle.jdbc.driver.OracleDriver");//load the JDBC driver
Connection con=DriverManager.getConnection("jdbc:oracle:thin:@138.198.197.130:1521:fwhdb","MILS","mil3068");
//get a connection
解释:
138.198.197.130是数据库服务器fwhdb.szs.st.com的IP地址。
1521是端口
fwhdb是SID,SID就是Oracle的Session ID,用来标识数据库实例的。相当于orcale的实例名。JDBC连数据库用的是ORACLE的实例名,也就是真实数据库的名字而PL/SQL登录数据库用的是数据库的net别名
注意:
在将SQL语句时,orcale的语句结尾时不带分号的“;”。如
rs=stmt.executeQuery("select * from yhb");
如果不小心带上分号会出现以下错误提示:
Java.sql.sQLException: ORA-00911:invalid character
3查询操作
对一个数据库中表进行查询操作的具体步骤如下:
向数据库发送SQL查询语句
首先使用Statement声明一个SQL语句对象,然后让已创建的连接对象con调用方法createStatement()创建这个SQL语句对象,代码如下:
try{
Statement sql=con.createStatement();
}catch(SQLException e){}
处理查询结果
有了SQL语句对象后,这个对象就可以调用相应的方法实现对数据库中表的查询和修改,并将查询结果存放在一个ResultSet类声明的对象中。ResultSet对象那是以统一形式的列组织的数据行组成。
ResultSet rs=sql.executeQuery("SELECT * FROM employee");
ResultSet 对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。next()方法将指针移动到下一行;该方法在 ResultSet 对象中没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。next()获得一行数据后,ResultSet对象可以使用getXxx方法获得字段值,getXXX方法的参数可以使用列的索引编号或列的名称检索值。一般情况下,使用列索引较为高效。列从 1 开始编号
无论字段是何种属性,总可以使用getString(int columnIndex)或getString(String columnName)方法返回字段值的串表示。
*********************
ResultSet对象的方法:
boolean absolute(int row),将指针移动到此 ResultSet 对象的给定行编号。
void afterLast(),将指针移动到此 ResultSet 对象的末尾,正好位于最后一行之后。
void beforeFirst(),将指针移动到此 ResultSet 对象的开头,正好位于第一行之前。
void close(),立即释放此 ResultSet 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。
void deleteRow(),从此 ResultSet 对象和底层数据库中删除当前行。
int findColumn(String columnName)将给定的 ResultSet 列名称映射到其 ResultSet 列索引。
boolean first(),将指针移动到此 ResultSet 对象的第一行。
int getRow(),检索当前行编号。
int getType(),检索此 ResultSet 对象的类型。
boolean isAfterLast(),检索指针是否位于此 ResultSet 对象的最后一行之后。
boolean isBeforeFirst(),检索指针是否位于此 ResultSet 对象的第一行之前。
boolean isFirst(),检索指针是否位于此 ResultSet 对象的第一行。
boolean isLast(),检索指针是否位于此 ResultSet 对象的最后一行。
boolean last()将指针移动到此 ResultSet 对象的最后一行。
boolean next(),将指针从当前位置下移一行。
boolean previous(),将指针移动到此ResultSet对象的上一行。
如果要执行的数据库语句没有任何结果返回,我们不能用if(rs==null)来判断是否没有结果返回,应该使用if(rs.last())来判断,如果没有结果返回的或,那么rs.last()将会返回false。
********************
4顺序查询
查询数据库中一个表的记录时,若希望知道表中字段的个数以及各个字段的名字。使用如下方法:
当和数据库建立连接对象con之后,那么该连接对象调用getMetaData()方法可以返回一个DatabaseMetaData对象。
DatabaseMetaDta metadata=con.getMetaData();
metadata对象再调用getColumns可以将表的字段信息以行列的形式存储在一个ResulSet对象中,如:
ResultSet tableMessage=metaData.getColumn(null,null,"表名(employee)",null);
如果employee表有n个字段,tableMessage就刚好有n行,每行4列。这四列分别是“数据库名”、“数据库扩展名”,“表名”,“字段名”。其中最重要的信息是第4列,该列上的信息为字段的名字。我们让tableMessage调用next方法是游标向下移动,然后再调用getString(4)方法依次获取每个字段的名字。
while(tableMessage.next()){
字段个数++;
String clumnName=tableMessage.getString(4);
}
5随机查询
有时候需要在结果集中前后移动、显示结果集指定的一条记录或随机显示若干条记录。这时,必须返回一个可滚动的结果集。为了得到一个可滚动的结果集,需使用下述方法获得一个Statement对象:
Statement stmt=con.createStatement(int type,int concurrency);
type的取值决定滚动方式,可以取以下值:
ResultSet.TYPE_FORWORD_ONLY,结果集的游标只能向下滚动。
ResultSet.TYPE_SCROLL_INSENSITIVE,结果集的游标可以上下移动,当数据库变化时,当前结果集不变。
ResultSet.TYPE_SCROLL_SENSITIVE,返回可滚动的结果集,当数据库变化时,当前结果集同步改变。
Concurrency的取值决定是否可以用结果集更新数据库,可以取以下值:
ResultSet.CONCUR_READ_ONLY,不能用结果集更新数据库中的表。
ResultSet.CONCUR_UPDATABLE,能用结果集更新数据库中的表。
滚动查询经常用到ResultSet的下述方法:
public boolean previous(),将游标向上移动,该方法返回boolean型数据,当移动到第一行之前返回false。
public void beforeFirst(),将游标移动到结果集的初始位置,即在第一行之前。
public void afterLast(),将游标移动到结果集最后一行之后。
public void first(),将游标移到结果集的第一行。
public void last(),将游标移到结果集的最后一行。
public boolean isAfterLast(),判断游标是否在最后一行之后。
public boolean isBeforeFirst(),判断游标是否在第一行之前。
public boolean isFirst(),判断游标是否指向结果集的第一行。
public boolean ifLast(),判断游标是否指向结果集的最后一行。
public int getRow(),得到当前游标所指行的行号,行号从1开始。如果结果集中没有行,则返回0。
public boolean absolute(int row),将游标移到参数row指定的行号。row去取负值表示倒数的行数。absolute(-1)表示倒数第一行。
***********************
如果要使用上述随机查询的方法,而没有为type选择滚动方式,而只是简单的Statement stmt=con.createStatement();就会报出以下错误:
SQLServer2000 Dvriver for JDBC Unsupported method:Resulset.last
***********************
6更新、添加与删除操作
Statement对象调用方法:
public int executeUpdate(String sqlStatement);
通过参数sqlStatement指定的方式实现对数据库表中记录的更新、添加和删除操作。更新、添加和删除记录的SQL语法分别是:
UPDATE <表名> SET <字段名> = 新值 WHERE <条件子句>
INSERT INTO 表(字段列表) VALUES (对应的具体记录) 或 INSERT INTO 表 VALUES (对应的具体记录)
DELETE FROM <表名> WHERE <条件子句>
7分页显示记录
JDBC使用ResultSet对象处理SQL语句从数据库表中查询的记录。ResultSet对象和数据库连接对象和数据库连接实现了紧密的绑定,一旦连接对象被关闭,ResultSet对象中的数据立刻消失。com.sun.rowset包提供了CachedRowSetImpl类,该类实现了CachedRowSet接口。CachedRowSetImpl对象可以保存ResultSet对象中的数据。CachedRowSetImpl继承了ResultSet的所有方法,将ResultSet对象result中的数据保存到CachedRowSetImpl对象rowSet中的代码如下:
CachedRowSetImpl rowSet=new CachedRowSetImpl();
rowSet.populate(result);
假设CachedRowSetImpl对象中有m行记录,每页显示n行。那么总页数的计算公式为:(m%n)==0?(m/n):(m+n+1)
如果准备显示第p页的内容,应当把CachedRowSetImpl对象中的游标移动到第(p-1)*n+1行记录处。
************************************
8使用预处理语句PreparedStatement
使用预处理语句可以防止SQL注入。
public interface PreparedStatement extends Statement
对于JDBC,如果使用Connection和某个数据库建立了连接对象con,那么con就可以调用prepareStatement(String sql)方法对参数指定的SQL语句进行预编译处理,生成该数据库底层的内部命令,并将该命令封装在PreparedStatement对象中,那么该对象调用下列方法都可以使得该底层的内部命令被数据库执行。
ResultSet executeQuery()
boolean execute()
int executeUpdate()
只要编译好PrepareStatement对象,那么该对象可以随时执行上述方法。
例:
PreparedStatement sql=con.prepareStatement("SELECT * FROM "+tableName);
使用Connection的prepareStatement()方法创建PreparedStatement对象:
PreparedStatement prepareStatement(String sql)
创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。该对象将生成顺序的ResultSet对象
PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
创建一个 PreparedStatement 对象,该对象将生成具有给定类型和并发性的ResultSet对象(可以得到随机的ResultSet对象)。
预处理语句中使用通配符
在对SQL进行预处理时可以使用通配符(?)来代替字段的值,只要的预处理语句执行之前设置通配符所表示的具体值即可。如:
sql=con.prepareStatement("SELECT * FROM employee WHERE salary<?");
那么在sql对象执行之前,必须调用相应的方法设置通配符?代表具体值。如:sql.setFloat(1,4389);
通配符按照它们在预处理SQL语句中从左到右一次出现的顺序分别称为第1个、第2个...第m个通配符。
void setFloat(int parameterIndex,int x);
parameterIndex用来表示SQL语句中从左到右的第parameterIndex个通配符,x是该通配符所代表的具体值。
PreparedStatement对象的方法:
void clearParameters(),立即清除当前参数值
void setArray(int i, Array x),将指定参数设置为给定 Array 对象
void setAsciiStream(int parameterIndex, InputStream x, int length),将指定参数设置为给定输入流,该输入流将拥有给定字节数。
void setBigDecimal(int parameterIndex, BigDecimal x),将指定参数设置为给定 java.math.BigDecimal 值。
void setBinaryStream(int parameterIndex, InputStream x, int length),将指定参数设置为给定输入流,该输入流将拥有给定字节数。
void setShort(int parameterIndex, short x)
将指定参数设置为给定 Java short 值。
void setString(int parameterIndex, String x)
将指定参数设置为给定 Java String 值。
void setTime(int parameterIndex, Time x)
将指定参数设置为给定 java.sql.Time 值。
void setTime(int parameterIndex, Time x, Calendar cal)
使用给定的 Calendar 对象将指定参数设置为给定 java.sql.Time 值。
void setTimestamp(int parameterIndex, Timestamp x)
将指定参数设置为给定 java.sql.Timestamp 值。
void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
使用给定的 Calendar 对象将指定参数设置为给定 java.sql.Timestamp 值。
void setDate(int parameterIndex, Date x)
将指定参数设置为给定 java.sql.Date 值。
void setDate(int parameterIndex, Date x, Calendar cal)
使用给定的 Calendar 对象将指定参数设置为给定 java.sql.Date 值。
void setDouble(int parameterIndex, double x)
将指定参数设置为给定 Java double 值。
void setFloat(int parameterIndex, float x)
将指定参数设置为给定 Java float 值。
void setInt(int parameterIndex, int x)
将指定参数设置为给定 Java int 值。
void setLong(int parameterIndex, long x)
将指定参数设置为给定 Java long 值。
void setBlob(int i, Blob x)
将指定参数设置为给定 Blob 对象。
void setBoolean(int parameterIndex, boolean x)
将指定参数设置为给定 Java boolean 值。
void setByte(int parameterIndex, byte x)
将指定参数设置为给定 Java byte 值。
void setBytes(int parameterIndex, byte[] x)
将指定参数设置为给定 Java 字节数组。
void setCharacterStream(int parameterIndex, Reader reader, int length)
将给定参数设置为给定 Reader 对象,后者是给定的字符数长度。
void setClob(int i, Clob x)
将指定参数设置为给定 Clob 对象。
void setNull(int parameterIndex, int sqlType)
将指定参数设置为 SQL NULL。
void setNull(int paramIndex, int sqlType, String typeName)
将指定参数设置为 SQL NULL。
void setObject(int parameterIndex, Object x)
使用给定对象设置指定参数的值。
void setObject(int parameterIndex, Object x, int targetSqlType)
使用给定对象设置指定参数的值。
void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
使用给定对象设置指定参数的值。
void setRef(int i, Ref x)
将指定参数设置为给定 REF(<structured-type>) 值。
void setUnicodeStream(int parameterIndex, InputStream x, int length)
已过时。
void setURL(int parameterIndex, URL x)
将指定参数设置为给定 java.net.URL 值
void addBatch(String sql),将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。
*******************
9Statement
public interface Statement,用于执行静态 SQL 语句并返回它所生成结果的对象。
Statement的方法
void cancel(),如果 DBMS 和驱动程序都支持中止 SQL 语句,则取消此 Statement 对象
void close(),立即释放此 Statement 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。
boolean execute(String sql),执行给定的 SQL 语句,该语句可能返回多个结果。
ResultSet executeQuery(String sql),执行给定的 SQL 语句,该语句返回单个ResultSet对象。如果执行出错会返回一个null的ResultSet对象。
void addBatch(String sql),将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。
void clearBatch(),清空此 Statement 对象的当前 SQL 命令列表。
int[] executeBatch(),将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
int executeUpdate(String sql),执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句.executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零.如果执行失败则返回值小于0(-1)。
**********************************
10查询Excel电子
有时需要查询、更新和删除Excel电子表格的内容,可以通过JDBC-ODBC桥接器访问Excel电子表格。访问Excel电子表格和访问Excel电子表格和访问其他的数据库有所不同。连接Excel电子表格的步骤:
设置表
必须在电子表格中选出一个工作区作为连接时使用的表。在Excel电子表格中拖动鼠标选出范围,然后Excel菜单中选择"插入"->"名称"->"定义",给选中的工作区命名。例如我们命名为message。
设置数据源
设置表之后,就可以设置数据源了。为数据源选择的驱动程序必须是Microsoft Excel Driver。例如我们将数据源设置为star。如果准备修改Excel电子表格,在设置数据源时,单击其中的"选项",将"只读"属性设置为未选中状态。
例:
<@ page contentType="text/html;Charset=GB2312" %>
<@ page import="java.sql.*"%>
<html>
<body>
<%
Connection con;
Statement sql;
ResultSet rs;
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}catch(ClassNotFoundException e){}
try{
con=DriverManager.getConnection("jdbc:odbc:star","","");
sql=con.createStatement();
sql=executeUpdate("UPDATE message SET 品名=‘电缆线’WHERE 货号=‘ED56G‘");
rs=sql.executeQuery("SELECT * FROM message");
out.print("<Table Border>");
out.print("<TR>");
out.print("<TH width=100>"+"货号");
out.print("<TH width=100>"+"品名");
out.print("<TH width=50>"+"单位");
out.print("<TH width=50>"+"单位");
out.print("<TH width=50>"+"库存");
out.print("</TR>");
while(rs.next())
{
out.print("<TR>")
out.print("<TD>"+rs.getString(1)+"</TD>");
out.print("<TD>"+rs.getString(2)+"</TD>");
out.print("<TD>"+rs.getString(3)+"</TD>");
out.print("<TD>"+rs.getString(4)+"</TD>");
out.print("<TD>"+rs.getString(5)+"</TD>");
out.print("</TR>");
}
out.print("</Table>");
con.close;
}
%>
</body>
</html>
11Tomcat配置使用连接池
数据库都有最大连接数目的限制,如果很多用户连接的是同一数据库,所进行的都是同样的操作。那么每个用户都建立连接是不合理的。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而再不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能
连接池的思想是:Tomcat服务器可以事先预备好若干个连接对象,将这些连接对象存放在一个称为连接池的容器中(通常由链表担当),当某个用户需要操作数据库时,只要从连接池中取出一个连接对象即可。当用户使用完该连接对象后,将该连接对象放回到连接池中。如果某个用户需要操作数据库时,连接池中已没有连接对象可用,那么该用户就必须等待,直到连接池中有了连接对象。
Datasource中事先建立了多个数据库连接,这些数据库连接保持在数据库连接池中,当程序访问数据库时,只需要从连接池从取出空闲的连接,访问数据库结束,在将这些连接归还给连接池
(1)将使用数据库连接池需要的包放入lib下
无论连接哪种数据库都需要以下包:
commons-pool-1.4.jar,commons-dbcp-1.2.2.jar,naming-resources.jar,naming-factory-5.5.12.jar,naming-common-5.0.28.jar,commons-collections-2.1.1.jar,jndi.jar
必须将以上包放入tomcat的lib目录下。这些包可以到http://www.jar114.com下载。
commons-pool.jar, commons-dbcp.jar:
DBCP数据库连接池,Apache的Jakarta组织开发的,Tomcat4的连接池也是DBCP。
jndi.jar随JDK1.4一起提供,不需下载。
******使用数据库连接池连接Microsoft SQL server*******
既然是连接SQL server那么SQL的jdbc包msbase.jar,mssqlserver.jar,msutil.jar同上面连接SQL一样也是需要的
(2)修改server.xml配置文件
在apache-tomcat-6.0.18\conf目录下的server.xml文件中的<host>标签内增加以下内容
<Context path="/bbs" docBase="D:\apache-tomcat-6.0.18\webapps\bbs">
<Resource name="jdbc/SqlServerDB" auth="Container" type="javax.sql.DataSource" factory="org.apache.commons.dbcp.BasicDataSourceFactory"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://10.93.13.155:1433;databaseName=UserRegistration"
username="sa"
password="happy0000"
maxActive="10"
maxIdle="20"
maxWait="-1"
removeAbandoned="true"
removeAbandonedTimeOut="10"
logAbandoned="true"/>
</Context>
path,指定访问web应用项目bbs的URL入口,注意/bbs,必须有/。
docBase,表示项目的具体路径。
<Resource>元素为JNDI,在lookup方法是要查找的资源。
name,表示JNDI在lookup是输入的资源名。
auth,是连接池管理权属性,Container表示容器管理。
name,表示你的连接池的名称也就是你要访问连接池的地址。
type,是对象的类型。
factory 指定生成的DataResource的factory类名。
driverClassName是数据库驱动的名称。注意这里是:
com.microsoft.sqlserver.jdbc.SQLServerDriver
如果写成下面的驱动名称将会出错。
com.microsoft.jdbc.sqlserver.SQLServerDriver
url,是数据库的地址。注意这里是:
jdbc:sqlserver://10.93.13.155:1433;databaseName=UserRegistration
如果写成下面的地址将会出错。
jdbc:microsoft:sqlserver://10.93.13.155:1433;databaseName=UserRegistration
maxActive,连接池的最大数据库连接数,设为0表示无限制
maxIdle,最大空闲数,数据库连接的最大空闲时间,数据库连接被标记为不可用,然后被释放。设为0表示无限制。
maxWait,最大建立连接等待时间单位ms,如果超过此时间将接到异常,设为-1表示无限制。
removeAbandoned,是否自我中断,默认为false。
removeAbandonedTimeout,几秒后数据连接会自动断开,在removeAbandoned为true,提供该值。
logAbandoned,是否记录中断事件,默认为false。
(3)jsp页面(在web项目bbs中)测试连接池
需要添加<%@ page import="javax.naming.*"%>,不然找不到Context类
我们是通过在server.xml中配置具有jndi名称的数据源,然后通过该jndi名称得到这个数据源,再与数据库进行交互。
<%@ page contentType="text/html;Charset=UTF-8"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.naming.*"%>
<html>
<head>
</head>
<body>
<%
Context initCtx = new InitialContext();
Context ctx = (Context) initCtx.lookup("java:comp/env");
//获取连接池对象,jdbc/SqlServerDB与Resource的name属性值对应
Object obj = (Object) ctx.lookup("jdbc/SqlServerDB");
//类型转换
javax.sql.DataSource ds = (javax.sql.DataSource)obj;
Connection con=ds.getConnection();
try{
Statement statement=con.createStatement();
ResultSet rs=statement.executeQuery("select * from bbs_T");
while(rs.next()){
out.println(rs.getString("bbsTitle"));
}
}catch(SQLException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
con.close();
}
%>
</body>
</html>
DataSource对象的方法:
Connection getConnection(),尝试建立与此 DataSource 对象表示的数据源的连接。
Connection getConnection(String username, String password),尝试建立与此 DataSource 对象表示的数据源的连接。
******使用数据库连接池连接Oracle*******
注意在server.xml中Context元素代表一个web应用,Host元素中嵌套任意多的Context元素。每个Context的路径必须是惟一的,由path属性定义。注意如果两个Context的path相同,则tomcat启动会出错。一个Context下可以有多个Resource元素,通过Resource的name属性来区别不同的Resource。
首先数据库连接池所需要的包和前面一样是必须的。
然后连接Oracle那么Oracle8的jdbc驱动包classes.jar也是必须的。
再配置server.xml在其中加入以下内容。其参数意义同上。
<Context path="/bbs" docBase="D:\apache-tomcat-6.0.18\webapps\bbs">
<Resource name="jdbc/OracleServerDB" auth="Container" type="javax.sql.DataSource" factory="org.apache.commons.dbcp.BasicDataSourceFactory"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@138.198.197.130:1521:fwhdb"
username="MILS"
password="mil3068"
maxActive="10"
maxIdle="20"
maxWait="-1"
removeAbandoned="true"
removeAbandonedTimeOut="10"
logAbandoned="true"/>
</Context>
最后jsp页面(在web项目bbs中)测试连接池
<%@ page contentType="text/html;Charset=UTF-8"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.naming.*"%>
<html>
<head>
</head>
<body>
<%
response.setCharacterEncoding("UTF-8");
Context initCtx = new InitialContext();
Context ctx = (Context) initCtx.lookup("java:comp/env");
//获取连接池对象,jdbc/OracleServerDB与Resource的name属性值对应
Object obj = (Object) ctx.lookup("jdbc/OracleServerDB");
//类型转换
javax.sql.DataSource ds = (javax.sql.DataSource)obj;
Connection con=ds.getConnection();
try{
Statement statement=con.createStatement();
ResultSet rs=statement.executeQuery("SELECT * FROM m_fulltable");
while(rs.next()){
out.println("Ok");
}
}catch(SQLException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
con.close();
}
%>
</body>
</html>
*****************************
常用数据库JDBC连接写法
1. MySQL(http://www.mysql.com)mm.mysql-2.0.2-bin.jar
Class.forName( "org.gjt.mm.mysql.Driver" );
cn = DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName", sUsr, sPwd );
2. PostgreSQL(http://www.de.postgresql.org)pgjdbc2.jar
Class.forName( "org.postgresql.Driver" );
cn = DriverManager.getConnection( "jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName", sUsr, sPwd );
3. Oracle(http://www.oracle.com/ip/deploy/database/oracle9i/)classes12.zip ;10.2版本建议使用ojdbc4.jar
Class.forName( "oracle.jdbc.driver.OracleDriver" );
cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:SID", sUsr, sPwd );
4. Sybase(http://jtds.sourceforge.net)jconn2.jar
Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" );
cn = DriverManager.getConnection( "jdbc:sybase:Tds:MyDbComputerNameOrIP:2638", sUsr, sPwd );
//(Default-Username/Password: "dba"/"sql")
5. Microsoft SQLServer(http://jtds.sourceforge.net)
Class.forName( "net.sourceforge.jtds.jdbc.Driver" );
cn = DriverManager.getConnection( "jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master", sUsr, sPwd );
6. Microsoft SQLServer(http://www.microsoft.com)
Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
cn = DriverManager.getConnection( "jdbc:microsoft:sqlserver://MyDbComputerNameOrIP:1433;databaseName=master", sUsr, sPwd );
7. ODBC
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
Connection cn = DriverManager.getConnection( "jdbc:odbc:" + sDsn, sUsr, sPwd );
8.DB2
Class.forName("Com.ibm.db2.jdbc.net.DB2Driver");
String url="jdbc:db2://192.9.200.108:6789/SAMPLE"
cn = DriverManager.getConnection( url, sUsr, sPwd );
***********************
注意当我们从数据库中获取int类型的数据时,返回的将是字符串型,如果赋给整型变量需要进行转换。如:
int Tid=Integer.parseInt(rs.getString("intID"));
当从数据库中获取数据时,Tomcat窗口出现如下错误:
:[Microsoft][ODBC SQL Server Driver]无效的描述符索引
问题的解决:
在对sqlserver数据库进行数据读取的时候,
必须按照表中列名的顺序读取,不然就会出现这个错误错误.
如果数据库定义顺序:
name
password
power
取值时一定要按下面顺序来取:
rs.getString("name")
rs.getString("password")
rs.getString("power")
这是因为rs默认为顺序查询,如果将rs改为随机查询就可以不按顺序取值了。
*****************
使用textarea向数据库存入数据
首先是数据库使用哪种类型(char,varchar,nchar,nvarchar),来对应textarea类型?
char类型:对英文(ASCII)字符占用1个字节,对一个汉字占用2个字节,CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义 char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间。因为是固定长度,所以速度效率高。
Varchar类型:Varchar 的类型不以空格填满,比如varchar(100),但它的值只是"qian",则它的值就是"qian"
而char 不一样,比如char(100),它的值是"qian",而实际上它在数据库中是"qian "(qian后共有96个空格,就是把它填满为100个字节)。
由于char是以固定长度的,所以它的速度会比varchar快得多!但程序处理起来要麻烦一点,要用trim之类的函数把两边的空格去掉!
VARCHAR 存储变长数据,但存储效率没有CHAR高。如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢?这一个字节用于保存实际使用了多大的长度。
Nchar类型和Nvarchar类型是怎么一回事呢?采用unicode,为了与其他多种字符的转换,如中文,音标等,对每个英文(ASCII)字符都占用2个字节,对一个汉字也占用两个字节,所有的字符都占用2个字节。
varchar一般适用于英文和数字,Nvarchar适用中文和其他字符,其中N表示Unicode常量,可以解决多语言字符集之间的转换问题
另外textarea元素中的空格,回车等特殊数符存入数据库为" ","\r\n"等,所以当我们从数据库中再次取出数据库是\r\n这样的字符不被html所识别,为了保持原有的格式。我们在取出数据后,需要进行转换。例如将\r\n转换为原有的格式<br>
guZh=rs.getString("miaoshu");
guZh=guZh.replaceAll(" "," ");
guZh=guZh.replaceAll("\r\n","<br>");
注意上面的替换在什么时候使用?,如果从数据库取出的数据仍然放在一个textarea中,那么不需要进行替换(在textarea中可以正确显示原有的格式)如:<td><textarea rows="3" cols="17" name="miaoshu"> <%=guZh%> </textarea></td>
但是如果不是放在一个textarea中而是就放在其他html元素中,如<td>中,那么就需要替换:
<%
String msh=rs.getString("miaoshu");
msh=msh.replaceAll(" "," ");
msh=msh.replaceAll("\r\n","<br>");
out.println("<td>"+msh+"</td>");
%>
************************
jdbc连接mySQL
首先下载jdbc连接mySQL需要的驱动包mysql-connector-java-5.1.13-bin.jar,下载地址:
http://dev.mysql.com/downloads/connector/j/
采用如下格式进行连接:
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://host:port/database","user","password");
连接端口默认为3306,例如:
Class.forName("com.mysql.jdbc.Driver");
String uri="jdbc:mysql://localhost:3306/DGZZBIN";
String user="root";
String password="dgzzbin";
Connection con=DriverManager.getConnection(uri,user,password)
*******************
ResultSet的其它方法:
Array getArray(int i),以 Java 编程语言中 Array 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Array getArray(String colName,以 Java 编程语言中 Array 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
BigDecimal getBigDecimal(int columnIndex),以具有全精度的 java.math.BigDecimal 的形式检索此 ResultSet 对象的当前行中指定列的值。
BigDecimal getBigDecimal(String columnName)m以具有全精度的 java.math.BigDecimal 的形式检索此 ResultSet 对象的当前行中指定列的值。
InputStream getBinaryStream(int columnIndex)
以未解释字节的二进制流的形式检索此 ResultSet 对象的当前行中指定列的值。
InputStream getBinaryStream(String columnName)
以未解释的 byte 流的形式检索此 ResultSet 对象的当前行中指定列的值。
Blob getBlob(int i)
以 Java 编程语言中 Blob 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Blob getBlob(String colName)
以 Java 编程语言中 Blob 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
boolean getBoolean(int columnIndex)
以 Java 编程语言中 boolean 的形式检索此 ResultSet 对象的当前行中指定列的值。
如果数据库中对应的字段的值为0,则使用getBoolean获得的值为false,当大于0时,使用getBoolean获得的值是true。
boolean getBoolean(String columnName)
以 Java 编程语言中 boolean 的形式检索此 ResultSet 对象的当前行中指定列的值。
byte getByte(int columnIndex)
以 Java 编程语言中 byte 的形式检索此 ResultSet 对象的当前行中指定列的值。
byte getByte(String columnName)
以 Java 编程语言中 byte 的形式检索此 ResultSet 对象的当前行中指定列的值。
byte[] getBytes(int columnIndex)
以 Java 编程语言中 byte 数组的形式检索此 ResultSet 对象的当前行中指定列的值。
byte[] getBytes(String columnName)
以 Java 编程语言中 byte 数组的形式检索此 ResultSet 对象的当前行中指定列的值。
Reader getCharacterStream(int columnIndex)
以 java.io.Reader 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Reader getCharacterStream(String columnName)
以 java.io.Reader 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Clob getClob(int i)
以 Java 编程语言中 Clob 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Clob getClob(String colName)
以 Java 编程语言中 Clob 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
int getConcurrency()
检索此 ResultSet 对象的并发模式。
String getCursorName()
检索此 ResultSet 对象使用的 SQL 指针的名称。
Date getDate(int columnIndex)
以 Java 编程语言中 java.sql.Date 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Date getDate(int columnIndex, Calendar cal)
以 Java 编程语言中 java.sql.Date 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Date getDate(String columnName)
以 Java 编程语言中的 java.sql.Date 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Date getDate(String columnName, Calendar cal)
以 Java 编程语言中 java.sql.Date 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
double getDouble(int columnIndex)
以 Java 编程语言中 double 的形式检索此 ResultSet 对象的当前行中指定列的值。
double getDouble(String columnName)
以 Java 编程语言中 double 的形式检索此 ResultSet 对象的当前行中指定列的值。
int getFetchDirection()
检索此 ResultSet 对象的获取方向。
int getFetchSize()
检索此 ResultSet 对象的获取大小。
float getFloat(int columnIndex)
以 Java 编程语言中 float 的形式检索此 ResultSet 对象的当前行中指定列的值。
float getFloat(String columnName)
以 Java 编程语言中 float 的形式检索此 ResultSet 对象的当前行中指定列的值。
int getInt(int columnIndex)
以 Java 编程语言中 int 的形式检索此 ResultSet 对象的当前行中指定列的值。
int getInt(String columnName)
以 Java 编程语言中 int 的形式检索此 ResultSet 对象的当前行中指定列的值。
long getLong(int columnIndex)
以 Java 编程语言中 long 的形式检索此 ResultSet 对象的当前行中指定列的值。
long getLong(String columnName)
以 Java 编程语言中 long 的形式检索此 ResultSet 对象的当前行中指定列的值。
ResultSetMetaData getMetaData()
检索此 ResultSet 对象的列的编号、类型和属性。
Object getObject(int columnIndex)
以 Java 编程语言中 Object 的形式获取此 ResultSet 对象的当前行中指定列的值。
Object getObject(int i, Map<String,Class<?>> map)
以 Java 编程语言中 Object 的形式检索此 ResultSet 对象的当前行中指定列的值。
Object getObject(String columnName)
以 Java 编程语言中 Object 的形式获取此 ResultSet 对象的当前行中指定列的值。
Object getObject(String colName, Map<String,Class<?>> map)
以 Java 编程语言中 Object 的形式检索此 ResultSet 对象的当前行中指定列的值。
Ref getRef(int i)
以 Java 编程语言中 Ref 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Ref getRef(String colName)
以 Java 编程语言中 Ref 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
short getShort(int columnIndex)
以 Java 编程语言中 short 的形式检索此 ResultSet 对象的当前行中指定列的值。
short getShort(String columnName)
以 Java 编程语言中 short 的形式检索此 ResultSet 对象的当前行中指定列的值。
Statement getStatement()
检索生成此 ResultSet 对象的 Statement 对象。
String getString(int columnIndex)
以 Java 编程语言中 String 的形式检索此 ResultSet 对象的当前行中指定列的值。
String getString(String columnName)
以 Java 编程语言中 String 的形式检索此 ResultSet 对象的当前行中指定列的值。
Time getTime(int columnIndex)
以 Java 编程语言中 java.sql.Time 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Time getTime(int columnIndex, Calendar cal)
以 Java 编程语言中 java.sql.Time 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Time getTime(String columnName)
以 Java 编程语言中 java.sql.Time 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Time getTime(String columnName, Calendar cal)
以 Java 编程语言中 java.sql.Time 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Timestamp getTimestamp(int columnIndex)
以 Java 编程语言中 java.sql.Timestamp 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Timestamp getTimestamp(int columnIndex, Calendar cal)
以 Java 编程语言中 java.sql.Timestamp 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Timestamp getTimestamp(String columnName)
以 java.sql.Timestamp 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
Timestamp getTimestamp(String columnName, Calendar cal)
以 Java 编程语言中 java.sql.Timestamp 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
InputStream getUnicodeStream(int columnIndex)
已过时。 使用 getCharacterStream 取代 getUnicodeStream
InputStream getUnicodeStream(String columnName)
已过时。 使用 getCharacterStream 代替
URL getURL(int columnIndex)
以 Java 编程语言中 java.net.URL 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
URL getURL(String columnName)
以 Java 编程语言中 java.net.URL 对象的形式检索此 ResultSet 对象的当前行中指定列的值。
SQLWarning getWarnings()
检索此 ResultSet 对象上的调用报告的第一个警告。
void insertRow()
将插入行的内容插入到此 ResultSet 对象和数据库中。
void moveToCurrentRow()
将指针移动到记住的指针位置,通常为当前行。
void moveToInsertRow()
将指针移动到插入行。
void refreshRow()
用数据库中的最近值刷新当前行。
boolean relative(int rows)
按相对行数(或正或负)移动指针。
boolean rowDeleted()
检索是否已删除某行。
boolean rowInserted()
检索当前行是否已有插入。
boolean rowUpdated()
检索是否已更新当前行。
void setFetchDirection(int direction)
设置此 ResultSet 对象中行的处理方向。
void setFetchSize(int rows)
为 JDBC 驱动程序设置此 ResultSet 对象需要更多行时应该从数据库获取的行数。
void updateArray(int columnIndex, Array x)
用 java.sql.Array 值更新指定列。
void updateArray(String columnName, Array x)
用 java.sql.Array 值更新指定列。
void updateAsciiStream(int columnIndex, InputStream x, int length)
用 ascii 流值更新指定列。
void updateAsciiStream(String columnName, InputStream x, int length)
用 ascii 流值更新指定列。
void updateBigDecimal(int columnIndex, BigDecimal x)
用 java.math.BigDecimal 值更新指定列。
void updateBigDecimal(String columnName, BigDecimal x)
用 java.sql.BigDecimal 值更新指定列。
void updateBinaryStream(int columnIndex, InputStream x, int length)
用二进制流值更新指定列。
void updateBinaryStream(String columnName, InputStream x, int length)
用二进制流值更新指定列。
void updateBlob(int columnIndex, Blob x)
用 java.sql.Blob 值更新指定列。
void updateBlob(String columnName, Blob x)
用 java.sql.Blob 值更新指定列。
void updateBoolean(int columnIndex, boolean x)
用 boolean 值更新指定列。
void updateBoolean(String columnName, boolean x)
用 boolean 值更新指定列。
void updateByte(int columnIndex, byte x)
用 byte 值更新指定列。
void updateByte(String columnName, byte x)
用 byte 值更新指定列。
void updateBytes(int columnIndex, byte[] x)
用 byte 数组值更新指定列。
void updateBytes(String columnName, byte[] x)
用字节数组值更新指定列。
void updateCharacterStream(int columnIndex, Reader x, int length)
用字符流值更新指定列。
void updateCharacterStream(String columnName, Reader reader, int length)
用字符流值更新指定列。
void updateClob(int columnIndex, Clob x)
用 java.sql.Clob 值更新指定列。
void updateClob(String columnName, Clob x)
用 java.sql.Clob 值更新指定列。
void updateDate(int columnIndex, Date x)
用 java.sql.Date 值更新指定列。
void updateDate(String columnName, Date x)
用 java.sql.Date 值更新指定列。
void updateDouble(int columnIndex, double x)
用 double 值更新指定列。
void updateDouble(String columnName, double x)
用 double 值更新指定列。
void updateFloat(int columnIndex, float x)
用 float 值更新指定列。
void updateFloat(String columnName, float x)
用 float 值更新指定列。
void updateInt(int columnIndex, int x)
用 int 值更新指定列。
void updateInt(String columnName, int x)
用 int 值更新指定列。
void updateLong(int columnIndex, long x)
用 long 值更新指定列。
void updateLong(String columnName, long x)
用 long 值更新指定列。
void updateNull(int columnIndex)
为可以为 null 的列提供 null 值。
void updateNull(String columnName)
用 null 值更新指定列。
void updateObject(int columnIndex, Object x)
用 Object 值更新指定列。
void updateObject(int columnIndex, Object x, int scale)
用 Object 值更新指定列。
void updateObject(String columnName, Object x)
用 Object 值更新指定列。
void updateObject(String columnName, Object x, int scale)
用 Object 值更新指定列。
void updateRef(int columnIndex, Ref x)
用 java.sql.Ref 值更新指定列。
void updateRef(String columnName, Ref x)
用 java.sql.Ref 值更新指定列。
void updateRow()
用此 ResultSet 对象的当前行的新内容更新底层数据库。
void updateShort(int columnIndex, short x)
用 short 值更新指定列。
void updateShort(String columnName, short x)
用 short 值更新指定列。
void updateString(int columnIndex, String x)
用 String 值更新指定列。
void updateString(String columnName, String x)
用 String 值更新指定列。
void updateTime(int columnIndex, Time x)
用 java.sql.Time 值更新指定列。
void updateTime(String columnName, Time x)
用 java.sql.Time 值更新指定列。
void updateTimestamp(int columnIndex, Timestamp x)
用 java.sql.Timestamp 值更新指定列。
void updateTimestamp(String columnName, Timestamp x)
用 java.sql.Timestamp 值更新指定列。
boolean wasNull()
报告最后一个读取的列是否具有值 SQL NULL。
***************
c3p0
C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的 Connection 和Statement 池的DataSources 对象。
c3p0默认配置
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement">3</property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts">30</property>
<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay">1000</property>
<!--连接关闭时默认将所有未提交的操作回滚。Default: false -->
<property name="autoCommitOnClose">false</property>
<!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么
属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试
使用。Default: null-->
<property name="automaticTestTable">Test</property>
<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为 true,那么在尝试
获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->
<property name="breakAfterAcquireFailure">false</property>
<!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出
SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->
<property name="checkoutTimeout">100</property>
<!--通过实现ConnectionTester或 QueryConnectionTester的类来测试连接。类名需制定全路径。
Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->
<property name="connectionTesterClassName"></property>
<!--指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可
Default: null-->
<property name="factoryClassLocation">null</property>
<!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs.
(文档原文)作者强烈建议不使用的一个属性-->
<property name="forceIgnoreUnresolvedTransactions">false</property>
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod">60</property>
<!--初始化时获取三个连接,取值应在minPoolSize与 maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize">3</property>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。 Default: 0 -->
<property name="maxIdleTime">60</property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">15</property>
<!--JDBC的标准参数,用以控制数据源内加载的 PreparedStatements数量。但由于预缓存的statements
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为 0,则缓存被关闭。Default: 0-->
<property name="maxStatements">100</property>
<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection"></property>
<!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能
通过多线程实现多个操作同时被执行。Default: 3-->
<property name="numHelperThreads">3</property>
<!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0
的数据源时。Default: null-->
<property name="overrideDefaultUser">root</property>
<!--与overrideDefaultUser参数对应使用的一个参数。 Default: null-->
<property name="overrideDefaultPassword">password</property>
<!--密码。Default: null-->
<property name="password"></property>
<!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:
测试的表必须在初始数据源的时候就存在。Default: null-->
<property name="preferredTestQuery">select id from test where id=1</property>
<!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->
<property name="propertyCycle">300</property>
<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个 connection提交的
时候都将校验其有效性。建议使用idleConnectionTestPeriod或 automaticTestTable
等方法来提升连接测试的性能。Default: false -->
<property name="testConnectionOnCheckout">false</property>
<!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->
<property name="testConnectionOnCheckin">true</property>
<!--用户名。Default: null-->
<property name="user">root</property>
在Hibernate(spring管理)中的配置:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="jdbcUrl"><value>jdbc:oracle:thin:@localhost:1521:Test</value></property>
<property name="user"><value>Kay</value></property>
<property name="password"><value>root</value></property>
<!--连接池中保留的最小连接数。-->
<property name="minPoolSize" value="10" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="100" />
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。 Default: 0 -->
<property name="maxIdleTime" value="1800" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3" />
<property name="maxStatements" value="1000" />
<property name="initialPoolSize" value="10" />
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" />
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="30" />
<property name="breakAfterAcquireFailure" value="true" />
<property name="testConnectionOnCheckout" value="false" />
</bean>
使用c3p0只需要导入c3p0需要的jar文件:c3p0-0.9.1.2.jar,上面的是在spring中使用c3p0,下面是在程序中使用c3p0
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public final class ConnectionManager {
private static ConnectionManager instance;
private static ComboPooledDataSource dataSource;
private ConnectionManager() throws SQLException, PropertyVetoException {
dataSource = new ComboPooledDataSource();
dataSource.setUser("loux");
dataSource.setPassword("loux");
dataSource.setJdbcUrl("jdbc:oracle:thin:@192.168.100.70:1521:orcl");
dataSource.setDriverClass("oracle.jdbc.driver.OracleDriver");
dataSource.setInitialPoolSize(5);
dataSource.setMinPoolSize(1);
dataSource.setMaxPoolSize(10);
dataSource.setMaxStatements(50);
dataSource.setMaxIdleTime(60);
}
public static final ConnectionManager getInstance() {
if (instance == null) {
try {
instance = new ConnectionManager();
} catch (Exception e) {
e.printStackTrace();
}
}
return instance;
}
public synchronized final Connection getConnection() {
Connection conn = null;
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
*************************
tomcat数据源配置
配置tomcat数据源
Tomcat 在 7.0 以前的版本都是使用commons-dbcp做为连接池的实现,但是 dbcp存在一些问题:
dbcp 是单线程的,为了保证线程安全会锁整个连接池
dbcp 性能不佳
dbcp 太复杂,超过 60 个类,发展滞后。
因此,通常J2EE中还会使用其它的高性能连接池,如C3P0,还有阿里系的druid 等。为此,Tomcat 从 7.0 开始引入一个新的模块:Tomcat jdbc pool,tomcat jdbc pool 近乎兼容 dbcp ,性能更高。
异步方式获取连接
tomcat jdbc pool 是 tomcat 的一个模块,基于 tomcat JULI,使用 Tomcat 的日志框架
使用 javax.sql.PooledConnection 接口获取连接
支持高并发应用环境
超简单,核心文件只有8个,比 c3p0 还少
更好的空闲连接处理机制
支持 JMX
支持 XA Connection。
tomcat jdbc pool 可在 Tomcat 中直接使用,也可以在独立的应用中使用。
Tomcat7中配置JNDI数据源连接池:
将下面的代码添加到Tomcat服务器上conf/context.xml中的<Context></Context>标签中,或者在web项目的META-INF/context.xml中:
<Resource name="jdbc/ens"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors=
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="root"
password="123"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/ens"/>
修改web.xml
打开%TOMCAT_HOME%\conf\web.xml,在</web-app>的前面添加以下内容:
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/shopping</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>