分享
 
 
 

自行开发了个可重用的数据库连接框架

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在开发有关数据库的应用时,虽然JDBC提供给我们许多便利,但在我们开发不同的应用的时候还是会重复着一些相同的工作,比如说编写数据库连接的程序,工作虽然不算多,但不断地重复实在是浪费时间,也增加了调试的复杂度;还有一点,我们应该尽量使用配置的数据源,笔者用的是Mysql,当用到中文应用上的时候Mysql的数据源没办法解决中文问题,另一方面又不希望每次都手动创建连接。基于以上遇到的两个小障碍,我编写了一个小框架,实现数据库使用方法最简单,能创建数据连接池。这些工作的实现都不需要再编程。

在Web应用中我们只需要在WEB-INF文件夹下面加入一个DBconfig.properties的文件,简单设置几个参数,再在Web.xml文件内加入一个listener元素即可。凡是JDBC支持的数据库类型都可以通过这两个文件来设置得到与数据库的连接。有了这个基础,开发者可以只需要考虑业务上的编程。比如说要实现什么样的查询和数据操作,开发者只需要定义这些业务上的方法即可。这样对开发效率来说大有改善。当然,如果在一些大的应用里面,用到ORM框架的话,这个框架就派不上用场了。这个小框架只适用于中小型的“利用关系数据库本土语言来工作”的应用。

使用的步骤:

一、配置DBconfig.properties

DBconfig.properties的设置例子如下:

url=jdbc:mysql://localhost:3306/article?useUnicode=true&characterEncoding=GB2312

user=dbuser

passWord=227711

DriverName=com.mysql.jdbc.Driver

maxConnections=10

url参数指定所要的数据库连接的URL。

user参数是连接该数据库的用户名

passWord参数是连接用户的密码

DriverName参数是所用数据库类型的驱动类

maxConnections可以设置最大连接数目

二、配置Web.xml:

在Web.xml中这样设置便可:

<web-app>

<listener>

<listener-class>bbmyth.util.dataBase.DataSourceProviderServlet</listener-class>

</listener>

</web-app>

不要去改变<listener>里面的所有东西。

三、用本应用包的API来编写业务程序

确保bbmyth.util.dataBase这个应用包在你的ClassPath(供编译程序用)中,或直接将该包Import入来。

最后定义自已的数据库操作Bean。注意这个Bean要继承bbmyth.util.dataBase.DBManager类,在这个DBManager类里提供了四个数据库操作变量:

Connection con:是连接类,框架已提供现成的连接,开发者可在程序里以下面的语句来获得数据库的连接:con=getConnection();

Statement smt:是查询语句类的变量,可直接使用;

PreparedStatement psmt:是预编译查询语句类的变量,可直接使用;

ResultSet rs:是结果集的变量,可直接使用。

每一次连接使用完之后,不管是用编译语句还是预编译语句和有没有返回结果集都可以直接用closeAll()函数来关闭它们,不推荐用他们自已的close()方法。

四、在Jsp中应用UseBean标签把该业务JavaBean应用进去,然后用SetProperty标签设置其一个参数。如:

<jsp:setProperty name="articledb" property="provider" value="<%=application.getAttribute("CONNECTOR")%>"/>

articledb是你自已的UseBean定义的Id。其他的不要改动。

五、调试运行!这样,就可以按照用户给的参数,自动在应用启动的时候创建所需要的连接池。在应用退出的时候释放连接。用Mysql在配置数据源因为总是加不了中文编码的参数,而在这里,可以直接在URL里加入中文参数。既实现了数据库连接的便利,又解决了中文连接的问题。

工作原理:

工作原理很简单:一个类实现了ServletContextListener的接口,可以实现Web应用的事件监听。我在应用的启动的时候读进配置文件的参数,然后按照参数连接数据库,把完成的连接存放到一个Bean当中,然后把这个Bean作为一个变量存放在ServletContext中即Jsp的Application范围中,整个应用都可以使用的。

接着,编写业务方法是用了该包里面的API,在Jsp页面里使用这个连接池实例的时候要通过UseBaen和SetProperty的标签来把ServletContext中的连接池变量作为参数用到自已的业务Bean来,这样就可以使用现成的连接池工作了。

另外,用户写业务Bean的时候继承DBManager类。该类已经定义好了一些必要的变量和实现了连接。用户可以直接开始写自已的业务逻辑方法。只须要知道要怎样开始,怎样结束就得了。

下面是该应用包的源代码:共有三个类文件,DataSourceProviderServlet .java在应用启动的时候生成连接存放到ConnectionProvider.java的类中。DBManager则是为编程提供便利的。

/*******************************************************************/

一、DataSourceProviderServlet .java

package bbmyth.util.dataBase;

import javax.servlet.http.HttpServlet;

import javax.servlet.ServletContextListener;

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContext;

import java.util.*;

import java.io.*;

import javax.sql.*;

import java.sql.*;

public class DataSourceProviderServlet implements ServletContextListener

{

public void contextDestroyed(ServletContextEvent sce)

{

/*本方法是在应用退出时由系统调用的,在这个时候我们

把所有的连接都关闭!*/

((ConnectionProvider)(sce.getServletContext().getAttribute("CONNECTOR"))).destroy();

sce.getServletContext().removeAttribute("CONNECTOR");

}

public void contextInitialized(ServletContextEvent sce)

{

/*本方法在应用初始时调用,这时我们可以创建连接并且存到

一个容器当中,存储在应用的上下文中,然后交由一个JavaBean

处理。*/

Properties ps=new Properties();

Vector connections=new Vector();

String url=null;

String user=null;

String passWord=null;

int maxConnections;

String DriverName=null;

ServletContext context=sce.getServletContext();

try

{

InputStream input=context

.getResourceAsStream("/WEB-INF/DBconfig.properties");

ps.load(input);

input.close();

url=(String)ps.get("url");

user=(String)ps.get("user");

passWord=(String)ps.get("passWord");

DriverName=(String)ps.get("DriverName");

maxConnections=Integer.parseInt(((String)ps.get("maxConnections")).trim(),10);

for(int i=0;i<maxConnections;i++)

{

connections.add(getConnection(url,user,passWord));

}

}

catch(Exception e)

{

e.printStackTrace();

}

context.setAttribute("CONNECTOR",new ConnectionProvider(connections));

}

public Connection getConnection(String url,String user,

String passWord)throws Exception

{

Class.forName(DriverName);

return DriverManager.getConnection(url,user,passWord);

}

}

二、ConnectionProvider.java

package bbmyth.util.dataBase;

import java.util.*;

import java.sql.*;

import javax.sql.*;

public class ConnectionProvider

{

private int maxConnections;

private Vector freeConnections;

private Vector nowConnections;

public ConnectionProvider(Vector connections)

{

freeConnections=new Vector();

nowConnections=new Vector();

freeConnections=connections;

maxConnections=freeConnections.size();

}

public Connection getConnection()

{

Connection temp=(Connection)freeConnections.firstElement();

freeConnections.remove(temp);

nowConnections.add(temp);

return temp;

}

public void closeConnection(Connection con)

{

/*Don't use the method close() provid by Connection to close the connection!

beacuase if you do that,the connection will not return to the pool!*/

nowConnections.remove(con);

freeConnections.add(con);

}

public void destroy()//can the container call this method?

{

freeConnections.removeAllElements();

nowConnections.removeAllElements();

}

}

三、DBManager.java

package bbmyth.util.dataBase;

import java.sql.*;

import javax.sql.*;

import java.util.*;

public class DBManager

{

protected ConnectionProvider provider=null;

protected Connection con=null;

protected Statement smt=null;

protected PreparedStatement psmt=null;

protected ResultSet rs=null;

public void setProvider(Object provider)

{

this.provider=(ConnectionProvider)provider;

}

public Connection getConnection()throws SQLException //get acess to database

{

if(provider==null)

throw new SQLException("missing the property 'provider'!!");

return provider.getConnection();

}

public void closeAll()

{

try

{

if(rs!=null)rs.close();

if(smt!=null)smt.close();

if(psmt!=null)psmt.close();

if(con!=null)provider.closeConnection(con);

}

catch(Exception e)

{

e.printStackTrace();

}

}

}

/**************************************************************************/

下面是一个应用的例子:该应用是一个文档的添加和查看的应用。在业务逻辑JavaBean里面只有三个方法

而这些方法是根据你自已的业务需要去添加和编写的。另外有一个代表了编文章的JavaBean。

一、ArticleDB.java

package article;

import java.sql.*;

import java.util.*;

import javax.naming.*;

import javax.sql.*;

import bbmyth.util.dataBase.*;

public class ArticleDB extends DBManager

{

public Article getArticleByTitle(String title)throws SQLException

{

Article article=new Article();

try

{

con=getConnection();

String sql="select * "+"from articles where title='"+title+"'";

smt=con.createStatement();

rs=smt.executeQuery(sql);

rs.next();

article.kind=rs.getString(1);

article.author=rs.getString(2);

article.title=rs.getString(3);

article.date=rs.getString(4);

article.body=rs.getString(5);

article.checknum=rs.getInt(6);

closeAll();

}

catch(Exception e)

{

e.printStackTrace();

}

return article;

}

public ArrayList executeQuery(String sql)throws SQLException

{

ArrayList list=new ArrayList();

try

{

con=this.getConnection();

smt=con.createStatement();

rs=smt.executeQuery(sql);

while(rs.next())

{

Article article =new Article();

article.kind=rs.getString(1);

article.author=rs.getString(2);

article.title=rs.getString(3);

article.date=rs.getString(4);

article.body=rs.getString(5);

article.checknum=rs.getInt(6);

list.add(article);

}

closeAll();

}

catch(SQLException e)

{

e.printStackTrace();

}

return list;

}

public void executeUpdate(String sql)throws SQLException

{

try

{

con=this.getConnection();

smt=con.createStatement();

smt.executeUpdate(sql);

closeAll();

}

catch(Exception e)

{

e.printStackTrace();

}

}

}

二、Article.java

package article;

import java.sql.*;

import java.util.*;

import javax.naming.*;

import javax.sql.*;

public class Article

{

String kind;

String author;

String title;

String date;

String body;

int checknum;

public Article()

{

}

public Article(String kind,String author,String title,String date,String body,int checknum)

{

this.kind=kind;

this.author=author;

this.title=title;

this.date=date;

this.body=body;

this.checknum=checknum;

}

/*********读取字段值********/

public int getChecknum()

{

return this.checknum;

}

public String getKind()

{

return this.kind;

}

public String getAuthor()

{

return this.author;

}

public String getTitle()

{

return this.title;

}

public String getDate()

{

return this.date;

}

public String getBody()

{

return this.body;

}

/**********设置字段值*********/

public void setKind(String kind)

{

this.kind=kind;

}

public void setAuthor(String author)

{

this.author=author;

}

public void setTitle(String title)

{

this.title=title;

}

public void setDate(String date)

{

this.date=date;

}

public void setBody(String body)

{

this.body=body;

}

public void setChecknum(int checknum)

{

this.checknum=checknum;

}

}

附:在Jsp中这样设置的:

<jsp:useBean id="articledb" class="article.ArticleDB" scope="application">

<jsp:setProperty name="articledb" property="provider" value="<%=application.getAttribute("CONNECTOR")%>"/>

</jsp:useBean>

这么一来,在Jsp中就可以随处使用你的业务Bean的方法来工作了。

总结:这是个很简单的小应用工具,适用于小型或中小型的应用。可以减少开发者在数据库连接上的花的工夫。专心编写业务程序。当然,也许很多人认为不必要,呵,这是我个人认为了。最好大家都能自已动手写一个,这样的话可以对数据库连接和相关的知识有更进一步的了解,另一方面可以方便自已以后的开发。数据池,最后不要用别人写的,要么自已写!写得不好没关系,再写!直接拿别人的来用就什么都学不到了。呵呵。我是这样认为的。这个工具到目前为止功能不算多,以后还会继续增加。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有