首页 > 编程 > JSP > 正文

JSP+JDBC(Thin模式)连接Oracle

2024-09-05 00:19:17
字体:
来源:转载
供稿:网友

 在jsp中连接到oracle一般有2种方式:

  1、oracle jdbc的oci8方式

  2、oracle jdbc的thin方式

  我比较喜欢第2种,因为web发布服务器与数据库服务器一般都不会放在同一台电脑中,而在使用thin方式连接时,web服务器端无须安装oracle的客户端。

  在动手先代码之前,我们先把环境配置妥善。先从安装了oracle的数据库服务器中,找到oracle安装目录,然后将该目录下的jdbc/lib/classes12.jar文件拷贝到web发布服务器的某个目录。假设就直接放在c:/根目录下吧,然后把该路径添加到‘系统--高级--环境变量’中变量名为‘classpath’的值中,如:d:/program files/sqllib/java/db2java.zip;d:/program files/sqllib/java/runtime.zip;c:classes12.jar; 也就是让java能够找到这个包。

  配置好环境后,我们就开始开始动手写代码了。关于数据库连接的代码,应该写个专门的连接类来调用,没必要想网络上有些文章那样,直接写到jsp的代码中。

  关于连接的代码很简单

private connection newconnection(string user,string password) {
connection con = null;
try {
class.forname("oracle.jdbc.driver.oracledriver").newinstance();
con = drivermanager.getconnection (“jdbc:oracle:thin:@192.168.96.1:1521:oracle9i”,user,password);
}
catch (sqlexception e) {
return null;
}
return con;

  如果帐号密码没有错,那这个函数就应该能返回个可用的连接。但如此简单的连接在一个项目中使用,是远远达不到效果的。我们可以在这个数据库连接类中加入更多的功能,如连接池等等。下面我就把该数据库连接类的代码详细的列出来,大家可以参考参考。

/*
* @title 公司网站
* @author: zf
* @version 1.0
* @memo:定义数据库连接及其数据库连接池等
*/
package com.kingson.db;

import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.date;

public class dbconnectionmanager {
static private dbconnectionmanager instance; // 唯一实例
static private int clients;

private vector drivers = new vector();
private printwriter log;
private hashtable pools = new hashtable();

/**
* 返回唯一实例.如果是第一次调用此方法,则创建实例
*
* @return dbconnectionmanager 唯一实例
*/
static synchronized public dbconnectionmanager getinstance() {
if (instance == null) {
instance = new dbconnectionmanager();
}
clients++;
return instance;
}

/**
* 建构函数私有以防止其它对象创建本类实例
*/
private dbconnectionmanager() {
init();
}

/**
* 将连接对象返回给由名字指定的连接池
*
* @param name 在属性文件中定义的连接池名字
* @param con 连接对象
*/
public void freeconnection(string name, connection con) {
dbconnectionpool pool = (dbconnectionpool) pools.get(name);
if (pool != null) {
pool.freeconnection(con);
}
}

/**
* 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
* 限制,则创建并返回新连接
*
* @param name 在属性文件中定义的连接池名字
* @return connection 可用连接或null
*/
public connection getconnection(string name) {
dbconnectionpool pool = (dbconnectionpool) pools.get(name);
if (pool != null) {
return pool.getconnection();
}
return null;
}

/**
* 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
* 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
*
* @param name 连接池名字
* @param time 以毫秒计的等待时间
* @return connection 可用连接或null
*/
public connection getconnection(string name, long time) {
dbconnectionpool pool = (dbconnectionpool) pools.get(name);
if (pool != null) {
return pool.getconnection(time);
}
return null;
}

/**
* 关闭所有连接,撤销驱动程序的注册
*/
public synchronized void release() {
// 等待直到最后一个客户程序调用
if (--clients != 0) {
return;
}

enumeration allpools = pools.elements();
while (allpools.hasmoreelements()) {
dbconnectionpool pool = (dbconnectionpool) allpools.nextelement();
pool.release();
}
enumeration alldrivers = drivers.elements();
while (alldrivers.hasmoreelements()) {
driver driver = (driver) alldrivers.nextelement();
try {
drivermanager.deregisterdriver(driver);
log("撤销jdbc驱动程序 " + driver.getclass().getname()+"的注册");
}
catch (sqlexception e) {
log(e, "无法撤销下列jdbc驱动程序的注册: " + driver.getclass().getname());
}
}
}

/**
* 根据指定属性创建连接池实例.
*
* @param props 连接池属性
*/
private void createpools(properties props) {
enumeration propnames = props.propertynames();
while (propnames.hasmoreelements()) {
string name = (string) propnames.nextelement();
if (name.endswith(".url")) {
string poolname = name.substring(0, name.lastindexof("."));
string url = props.getproperty(poolname + ".url");
if (url == null) {
log("没有为连接池" + poolname + "指定url");
continue;
}
string user = props.getproperty(poolname + ".user");
string password = props.getproperty(poolname + ".password");
string dbip = props.getproperty(poolname + ".db_ip", "192.168.96.1");
string dbport = props.getproperty(poolname + ".db_port", "1521");
string dbuid = props.getproperty(poolname + ".db_uid", "oracle9i");
string maxconn = props.getproperty(poolname + ".maxconn", "0");
//连接信息
string dbinfo = user + "/" + password + "@" + dbip + ":" + dbport + ":" + dbuid;
int max;
try {
max = integer.valueof(maxconn).intvalue();
}
catch (numberformatexception e) {
log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolname);
max = 0;
}
dbconnectionpool pool = new dbconnectionpool(poolname, url,dbinfo, max);
pools.put(poolname, pool);
log("成功创建连接池" + poolname);
}
}
}

/**
* 读取属性完成初始化
*/
private void init() {
inputstream is = getclass().getresourceasstream("db.properties");
properties dbprops = new properties();
try {
dbprops.load(is);
}
catch (exception e) {
system.err.println("不能读取属性文件. " +
"请确保db.properties在classpath指定的路径中");
return;
}
string logfile = dbprops.getproperty("logfile", "newslog.txt");
try {
log = new printwriter(new filewriter(logfile, true), true);
}
catch (ioexception e) {
system.err.println("无法打开日志文件: " + logfile);
log = new printwriter(system.err);
}
loaddrivers(dbprops);
createpools(dbprops);
}

/**
* 装载和注册所有jdbc驱动程序
*
* @param props 属性
*/
private void loaddrivers(properties props) {
string driverclasses = props.getproperty("driver");
stringtokenizer st = new stringtokenizer(driverclasses);
while (st.hasmoreelements()) {
string driverclassname = st.nexttoken().trim();
try {
driver driver = (driver)
class.forname(driverclassname).newinstance();
drivermanager.registerdriver(driver);
drivers.addelement(driver);
log("成功注册jdbc驱动程序" + driverclassname);
}
catch (exception e) {
log("无法注册jdbc驱动程序: " +
driverclassname + ", 错误: " + e);
}
}
}

/**
* 将文本信息写入日志文件
*/
private void log(string msg) {
log.println(new date() + ": " + msg);
}

/**
* 将文本信息与异常写入日志文件
*/
private void log(throwable e, string msg) {
log.println(new date() + ": " + msg);
e.printstacktrace(log);
}

/***************连接池类*************************************************/

/**
* 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
* 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
*/
class dbconnectionpool {
private int checkedout;
private vector freeconnections = new vector();
private int maxconn;
private string name;
private string url;
private string dbinfo;

/**
* 创建新的连接池
*
* @param name 连接池名字
* @param url 数据库的jdbc url
* @param dbinfo 数据库连接信息
* @param maxconn 此连接池允许建立的最大连接数
*/
public dbconnectionpool(string name, string url, string dbinfo, int maxconn) {
this.name = name;
this.url = url;
this.dbinfo = dbinfo;
this.maxconn = maxconn;
}

/**
* 将不再使用的连接返回给连接池
*
* @param con 客户程序释放的连接
*/
public synchronized void freeconnection(connection con) {
// 将指定连接加入到向量末尾
freeconnections.addelement(con);
checkedout--;
notifyall();
}

/**
* 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
* 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
* 然后递归调用自己以尝试新的可用连接.
*/
public synchronized connection getconnection() {
connection con = null;
if (freeconnections.size() > 0) {
// 获取向量中第一个可用连接
con = (connection) freeconnections.firstelement();
freeconnections.removeelementat(0);
try {
if (con.isclosed()) {
log("从连接池" + name+"删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getconnection();
}
}
catch (sqlexception e) {
log("从连接池" + name+"删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getconnection();
}
}
else if (maxconn == 0 || checkedout < maxconn) {
con = newconnection();
}
if (con != null) {
checkedout++;
}
return con;
}

/**
* 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
* 参见前一个getconnection()方法.
*
* @param timeout 以毫秒计的等待时间限制
*/
public synchronized connection getconnection(long timeout) {
long starttime = new date().gettime();
connection con;
while ((con = getconnection()) == null) {
try {
wait(timeout);
}
catch (interruptedexception e) {}
if ((new date().gettime() - starttime) >= timeout) {
// wait()返回的原因是超时
return null;
}
}
return con;
}

/**
* 关闭所有连接
*/
public synchronized void release() {
enumeration allconnections = freeconnections.elements();
while (allconnections.hasmoreelements()) {
connection con = (connection) allconnections.nextelement();
try {
con.close();
log("关闭连接池" + name+"中的一个连接");
}
catch (sqlexception e) {
log(e, "无法关闭连接池" + name+"中的连接");
}
}
freeconnections.removeallelements();
}

/**
* 创建新的连接
*/
private connection newconnection() {
connection con = null;
try {
con = drivermanager.getconnection(url+dbinfo);
log("连接池" + name+"创建一个新的连接");
}
catch (sqlexception e) {
log(e, "无法创建下列url的连接: " + url);
return null;
}
return con;
}


}
}
 


 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表