name="jdbc/webdb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.gjt.mm.mysql.Driver"
url="jdbc:
mysql:
//localhost:
3306/LibraryOA"
username="root"
password="root"
maxActive="50"
maxIdle="20"
maxWait="10000"/>
以上代码配置了数据库驱动,数据库地址,数据库用户名、密码,默认提供的连接数,最大提供的连接数,最长等待时间等参数。
2、Java中从连接池获取连接的类,使用了单例模式(来自GoF提出的设计模式):
//DataBaseConnectionPond.java
packagelibrary.util;
importjava.sql.Connection;
importjavax.sql.DataSource;
//作者:
赵伯涛
publicclassDataBaseConnectionPond{
privatestaticDataBaseConnectionPonddbcp=null;
privateDataSourceds=null;
privateDataBaseConnectionPond()throwsException{
javax.naming.Contextctx=newjavax.naming.InitialContext();
ds=(DataSource)ctx.lookup("java:
/comp/env/jdbc/webdb");
}
publicConnectionGetConnettion()throwsException{
returnds.getConnection();
}
publicstaticConnectiongetConnection()throwsException{
Connectionconn=null;
if(dbcp==null){
Thread.sleep((long)(Math.random()*200));
synchronized(DataBaseConnectionPond.class){
if(dbcp==null){
dbcp=newDataBaseConnectionPond();
}
}
}
try{
conn=dbcp.GetConnettion();
}catch(Exceptione){
}
returnconn;
}
}
该类在整个项目部署的过程中只实例化了一个对象,故称单例。
可以通过该类的static函数getConnection()获取连接。
3、Dao(DataAccessObject)的模板化实现,使用了模板方法模式(来自GoF提出的设计模式):
//SqlExecute.java
packagelibrary.execute;
importjava.sql.Connection;
importlibrary.util.*;
//作者:
赵伯涛
publicabstractclassSqlExecute{
publicConnectionconn;
publicObjectresult;
publicabstractvoidsetExecute()throwsException;
publicObjectexecute(){
try{
conn=DataBaseConnectionPond.getConnection();
conn.setAutoCommit(false);
setExecute();
mit();
}catch(Exceptione){
try{
conn.rollback();
}catch(Exceptionee){
}
e.printStackTrace();
}finally{
try{
conn.close();
}catch(Exceptione){
}
}
returnresult;
}
}
该类是一个抽象类,必须通过继承该类来实现具体的功能,其中的execute()函数是一个模板方法,将try-catch-finaly、获取connection及connection的事务处理提取出来,具体Dao的功能应该写在setExecute()函数中,在具体实现Dao的功能的时候可以不用重复这些代码,方便程序员编码,也方便程序员维护程序。
下面举例使用这个模板类:
//ReaderChangePasswordDao.java
packagelibrary.dao;
importjava.sql.PreparedStatement;
importlibrary.execute.SqlExecute;
importlibrary.model.ReaderModel;
//作者:
赵伯涛
publicclassReaderChangePasswordDaoextendsSqlExecute{
privateReaderModelrm;
//传入readerID,password,password2(旧密码)
//返回影响行数
publicReaderChangePasswordDao(ReaderModelrm){
this.rm=rm;
}
@Override
publicvoidsetExecute()throwsException{
Stringsql="updateReaderssetpassword=?
wherereaderID=?
andpassword=?
";
PreparedStatementps=conn.prepareStatement(sql);
ps.setString(1,rm.getPassword());
ps.setInt(2,rm.getReaderID());
ps.setString(3,rm.getPassword2());
this.result=ps.executeUpdate();
}
}
上面的类继承了SqlExecute类,重写了它的setExecute()函数,通过构造函数传入操作时需要的参数,在写代码的时候可以更加专注于数据库的操作,因为其它操作由模板类做好了。
这对写一个数据库操作或许没什么大不了的,但是一个项目里边数据库操作肯定是几十个,几百个,甚至几千个,使用模板类减少的编码量是非常客观的。
下面举例使用ReaderChangePasswordDao类:
//来自UserCommonService.java的部分代码
//读者修改密码
publicbooleanreaderChangePassword(intreaderID,StringnewPassword,
StringoldPassword){
ReaderModelrm=newReaderModel();
rm.setReaderID(readerID);
rm.setPassword(newPassword);
rm.setPassword2(oldPassword);
ReaderChangePasswordDaorcpd=newReaderChangePasswordDao(rm);
intcount=(Integer)rcpd.execute();
if(count>0){
returntrue;
}else{
returnfalse;
}
}
注意:
使用Dao的时候调用的应该是它的execute()方法(在抽象类中)。
4、时间显示
varcTime=newDate();//初始化日期
varmyYear=cTime.getFullYear();//年
varmyMonth=cTime.getMonth()+1;//月
varmyDate=cTime.getDate();//日
//获得时分秒
varmyHour=cTime.getHours();//时
varmyMinute=cTime.getMinutes();//分
varmySecond=cTime.getSeconds();//秒
if(myHour<10){//判断如果时钟小于10就显示两位,前一位用0代替
myHour='0'+myHour;
}
if(myMinute<10){//判断如果分钟小于10就显示两位,前一位用0代替
myMinute='0'+myMinute;
}
if(mySecond<10){//判断如果分秒钟小于10就显示两位,前一位用0代替
mySecond='0'+mySecond;
}
vartime=time=myYear+'/'+myMonth+'/'+myDate+''+myHour+':
'+myMinute+':
'+mySecond;//格式化时间
vartimer=setInterval(function(){//定义一个时钟,周期为1秒
varcTime=newDate();
varmyYear=cTime.getFullYear();//支持火狐
varmyMonth=cTime.getMonth()+1;//外国都是以0开头为一月
varmyDate=cTime.getDate();
//获得时分秒
varmyHour=cTime.getHours();
varmyMinute=cTime.getMinutes();
varmySecond=cTime.getSeconds();
if(myHour<10){
myHour='0'+myHour;
}
if(myMinute<10){
myMinute='0'+myMinute;
}
if(mySecond<10){
mySecond='0'+mySecond;
}
varcmp=Ext.getCmp("timer");
time=myYear+'/'+myMonth+'/'+myDate+''+myHour+':
'+myMinute+':
'+mySecond;
cmp.setValue(time);
},1000);
5、登录控制
//登录界面
Ext.onReady(function(){
Ext.QuickTips.init();
varform=newExt.Panel({//登录验证的form
autoTabs:
true,
activeTab:
0,
deferredRender:
false,
border:
false,
bodyStyle:
"background-color:
RGB(193,223,232);padding:
0px0px0px0px;",
items:
[{
xtype:
'box',
width:
385,
height:
80,
autoEl:
{
tag:
'img',
src:
'icons/borrowbooks.jpg'
}
},{
xtype:
'panel',
bodyStyle:
'background-color:
RGB(193,223,232);',
layout:
'hbox',
items:
[{
xtype:
'panel',
bodyStyle:
'background-color:
RGB(193,223,232);',
border:
false,
width:
120,
height:
150,
items:
[{
xtype:
'panel',
layout:
'hbox',
border:
false,
bodyStyle:
'background-color:
RGB(193,223,232);padding:
10px0px0px10px',
items:
[{
xtype:
'box',
width:
'30',
height:
'30',
autoEl:
{
tag:
'img',
src:
'icons/0.png'
}
},{
xtype:
'panel',
border:
false,
bodyStyle:
'background-color:
RGB(193,223,232);padding:
5px0px0px0px',
items:
[{
xtype:
'displayfield',
value:
";'onclick=viewWindow('"+l.names[0]+"')>查阅书目"
}]
}]
},{
xtype:
'panel',
layout:
'hbox',
border:
false,
bodyStyle:
'background-color:
RGB(193,223,232);padding:
10px0px0px10px',
items:
[{
xtype:
'box',
width:
'30',
height:
'30',
autoEl:
{
tag:
'img',
src:
'icons/6.png'
}
},{
xtype:
'panel',
border:
false,
bodyStyle:
'background-color:
RGB(193,223,232);padding:
5px0px0px0px',
items:
[{
xtype:
'displayfield',
value:
";'onclick=viewWindow('"+"找回密码"+"')>找回密码"
}]
}]
}]
},{
xtype:
'panel',
border:
false,
width:
320,
height:
150,
bodyStyle:
'background-color:
RGB(193,223,232);',
items:
[{
xtype:
'panel',
layout:
'form',
border:
false,
items:
[{
xtype:
'form',
layout:
'form',
id:
'loginno',
labelWidth:
30,
bodyStyle:
'background-color:
RGB(193,223,232);padding:
15px0px0px0px',
border:
false,
defaults:
{
width:
200
},
items:
[{
xtype:
'textfield',
fieldLabel:
'编号',
allowBlank:
false
}]
},{
xtype:
'form',
layout:
'form',
id:
'loginpassword',
labelWidth:
30,
bodyStyle:
'background-color:
RGB(193,223,232);padding:
10px0px0px0px',
border:
false,
defaults:
{
width:
200
},
items:
[{
xtype:
'textfield',
fieldLabel:
'密码',
inputType:
'password',
allowBlank:
false
}]
}]
}]
}]
}]
});
functionlogin(){//登录验证函数
varformNo=Ext.getCmp("loginno");
varformPassword=Ext.getCmp("loginpassword");
varusername=formNo.items.items[0];
varpassword=formPassword.items.items[0];
if(username.getValue().trim()!
=""&&password.getValue().trim()!
=""){
Ext.Ajax.request({
url:
'servlet/LoginServlet',
success:
function(response){
varresult=Ext.decode(response.responseText);
if(result.success){
location.href="index.html";
loginWindow.close();
}else{
Ext.Msg.alert('提示',result.msg,function(){
formPassword.getForm().reset();
});
};
},
params:
{
cmd:
'login',
username:
username.getValue().trim(),
password:
password.getValue().trim()
},
scope:
this
});
}else{
Ext.Msg.alert('提示','编号和密码都不能为空!
');
}
}
varloginWindow=newExt.Window({//登录窗口
title:
'用户登录',
layout:
'fit',
width:
400,
height:
240,
shadow:
true,