用Java实现数据库应用系统.docx
《用Java实现数据库应用系统.docx》由会员分享,可在线阅读,更多相关《用Java实现数据库应用系统.docx(12页珍藏版)》请在冰豆网上搜索。
用Java实现数据库应用系统
我们在做信息系统的时候,都要访问数据库,我最近接手一个项目,项目组决定使用Java编写,我负责数据层的设计和编码,为了提高代码的重用性和提高项目的开发效率。
我们开发了一个通用的数据库连接和完成基本操作的类库,个人认为这个类在做MIS系统时还是有一定的价值,所以总结出来,介绍给大家。
连接工厂,实现了DataSource接口
packageskydev.modules.data;
importjava.sql.*;
importjavax.sql.DataSource;
importjava.io.PrintWriter;
publicclassConnectionFactoryimplementsDataSource{
privateStringuserName;
privateStringpassword;
privateStringdriverName;
privateStringurl;
privatejava.sql.Connectionconnection;
/**
*根据设置的连接参数创建一个新的连接实例
*@return
*/
privateConnectiongetNewConnection(){
try{
this.connection.close();//试图关闭连接
}
finally{
this.connection=null;//释放连接
try{
Class.forName(this.driverName);//加载驱动程序
//DriverManager.registerDriver(driver);
try{
this.connection=DriverManager.getConnection(this.url,this.userName,this.p
assword);
}
catch(SQLExceptione){
throwe;
}
}
finally{
returnthis.connection;//返回新建立的连接
}
}
}
publicStringgetUserName(){
returnuserName;
}
publicvoidsetUserName(StringuserName){
this.userName=userName;
}
publicStringgetPassword(){
returnpassword;
}
publicvoidsetPassword(Stringpassword){
this.password=password;
}
publicStringgetDriverName(){
returndriverName;
}
publicvoidsetDriverName(StringdriverName){
this.driverName=driverName;
}
publicStringgetUrl(){
returnurl;
}
publicvoidsetUrl(Stringurl){
this.url=url;
}
publicjava.sql.ConnectiongetConnection(){
if(connection!
=null){
try{
if(connection.isClosed()){
connection=null;
getNewConnection();
}
}
catch(SQLExceptionex){
}
}
if(connection==null){//没有设置连接则创建一个连接
getNewConnection();
}
returnconnection;
}
publicConnectiongetConnection(StringuserName,Stringpassword)throws
SQLException{
this.setUserName(userName);
this.setPassword(password);
returngetConnection();
}
publicPrintWritergetLogWriter(){
returnnull;
}
publicvoidsetLogWriter(PrintWriterprintWriter){
}
publicvoidsetLoginTimeout(intint0){
}
publicintgetLoginTimeout(){
return0;
}
}
实现连接SQLServer的连接工厂,这里因为我们的项目使用SQLServer2000所以只实现了SqlServerConnectionFactory。
packageskydev.modules.data;
publicfinalclassSqlServerConnectionFactoryextendsConnectionFactory{
privatefinalStringdbDriver="com.microsoft.jdbc.sqlserver.SQLServerDriver";
privateStringhost;//主机
privateintport;//端口
privateStringdatabaseName;//Sql数据库名称
publicSqlServerConnectionFactory(){
super.setDriverName(dbDriver);
}
/**
*
*@paramhost数据库所在的主机名:
如"localhost"
*@paramportSQL服务器运行的端口号,如果使用缺省值1433,传入一个负数即可
*@paramdatabaseName数据库名称
*@paramuserName用户名
*@parampassword口令
*/
publicSqlServerConnectionFactory(Stringhost,
intport,
StringdatabaseName,
StringuserName,
Stringpassword){
this.setHost(host);
this.setPort(port);
this.setDatabaseName(databaseName);
this.setUserName(userName);
this.setPassword(password);
init();
}
privatevoidinit(){
super.setDriverName(dbDriver);
super.setUrl("jdbc:
microsoft:
sqlserver:
//"+host.trim()+":
"+
newInteger(port).toString()+";DatabaseName="+
databaseName.trim());
//super.setUrl("jdbc:
microsoft:
sqlserver:
//localhost:
1433;DatabaseName=demo");
}
publicvoidsetHost(Stringhost){
//处理主机名称
if((host==null)||(host.equals(""))||(host.equals("."))||
(host.equals("local"))){
host="localhost";
}
intindex=host.indexOf("//",0);
if(index==0){
host=host.substring
(2);//去掉前面的"//"
}
index=host.indexOf("//",0);
if(index>=0){
try{
thrownewException("SQLServer主机名参数错误!
");
}
catch(Exceptionex){
}
}
this.host=host;
}
publicvoidsetPort(intport){
/**
*缺省端口1433
*/
if(port<0){
port=1433;
}
this.port=port;
}
publicvoidsetDatabaseName(StringdatabaseName){
this.databaseName=databaseName;
}
}
使用"sun.jdbc.odbc.JdbcOdbcDriver"连接数据库的连接工厂
packageskydev.modules.data;
publicclassJdbcOdbcConnectionFactoryextendsConnectionFactory{
privatefinalstaticStringdriveName="sun.jdbc.odbc.JdbcOdbcDriver";
privateStringodbcName;
publicJdbcOdbcConnectionFactory(){
super.setDriverName(driveName);
}
/**
*使用指定的Odbc数据源连接数据库服务器
*@paramodbcName
*/
publicJdbcOdbcConnectionFactory(StringodbcName){
super.setDriverName(driveName);
setOdbcName(odbcName);
}
publicvoidsetOdbcName(StringodbcName){
this.odbcName=odbcName;
this.setUrl("jdbc:
odbc:
"+odbcName);
}
}
数据基本操作类,使用连接工厂连接数据库。
packageskydev.modules.data;
importjava.sql.*;
importjava.sql.PreparedStatement;
importjavax.sql.DataSource;
publicabstractclassDatabaseObject{
protectedConnectionconnection=null;
protectedResultSetresultSet=null;
protectedResultSetMetaDataresultSetMetaData=null;
privateConnectionFactoryconnectionFactory=null;
privatejava.sql.Statementstatement=null;
privatejavax.sql.DataSourcedataSource;//=newStatement();
publicDatabaseObject(){
dataSource=null;
connection=null;
}
publicDatabaseObject(ConnectionFactoryconnectionFactory){
this.setConnectionFactory(connectionFactory);
this.dataSource=connectionFactory;//ConnectionFactory实现了DataSource接口
}
/**
*执行查询
*@paramsql要执行的Sql语句
*@return 返回查询的结果集,查询失败返回null
*/
publicResultSetgetResultSet(Stringsql){
try{
this.resultSet=statement.executeQuery(sql);//保留内部指针
}
catch(SQLExceptione){
e.printStackTrace();
this.resultSet=null;
}
finally{
returnthis.resultSet;
}
}
/**
*获取外部指定ResltSet的ResultSetMetaData数据
*@paramresultSet要获取的ResultSet
*@return失败返回null
*/
publicResultSetMetaDatagetResultSetMetaData(ResultSetresultSet){
ResultSetMetaDataresultSetMetaData=null;
try{
resultSetMetaData=resultSet.getMetaData();
}
catch(SQLExceptione){
e.printStackTrace();
resultSetMetaData=null;
}
finally{
returnresultSetMetaData;
}
}
/**
*获取最近一次设置或者返回的ResultSet的ResultMetaData数据,
*比方说调用了:
getResultSet(sql)方法,然后调用getResultSetMetaData方法
*可以获得相应的ResultSetMetaData数据。
*@return
*/
publicResultSetMetaDatagetResultSetMetaData(){
returnthis.getResultSetMetaData(this.resultSet);
}
/**
*执行存储过程
*@paramspName存储过程名称
*@return
*/
publicResultSetExecute(StringspName){
//对此数据库执行一个SQL查询
ResultSetresultSet=null;
try{
//PreparedStatementstmt=(PreparedStatement)connection.createStatement();
resultSet=statement.executeQuery(spName);
}
catch(Exceptione){
System.out.println("executeerror"+e.getMessage());
}
returnresultSet;
}
/**
*设置数据库连接工厂,对此类的所有操作之前,必须调用该方法,
*设置数据库连接工厂。
*@paramconnectionFactory数据库连接工厂ConnectionFactory类对象以及
*派生类对象。
*/
publicvoidsetConnectionFactory(ConnectionFactoryconnectionFactory){
this.connectionFactory=connectionFactory;
connection=connectionFactory.getConnection();
try{
statement=connection.createStatement();
}
catch(SQLExceptionex){
System.err.println(ex);
}
}
publicConnectiongetConnection(){
returnconnection;
}
publicjava.sql.StatementgetStatement(){
returnstatement;
}
publicjavax.sql.DataSourcegetDataSource(){
returndataSource;
}
}
具体项目的数据库访问基类
packageskydev.modules.data;
publicclassDbObjectextendsDatabaseObject{
//privatefinalstaticStringdriveName="sun.jdbc.obdc.JdbcOdbcDriver";
publicDbObject(){
super(newSqlServerConnectionFactory("localhost",1433,"TheSchool","sa",""));
}
publicDbObject(ConnectionFactoryconnectionFactory){
super(connectionFactory);
}
}
在项目中的数据库层中的数据库访问类都从DatabaseObject类派生,这样只需要在一个地方设置数据连接,其他地方都不需要涉及数据库访问的具体连接代码。
如:
User类专门负责Users组的权限控制等,只需要简单的代码就可以连接并访问数据库了。
这里具体实现与此文章无关,只举一两个模块做例子。
publicclassUserextendsDbObject{
publicUser(){
//子类也可以覆盖基类的访问方式,在单机调式时有用。
//super(newSqlServerConnectionFactory("localhost",1433,"TheSchool","sa",""));
super();//调用基类的数据库访问代码。
}
/*
在做信息系统时为了提高客维护性,我们一般使用存储过程返回和修改数据,在数据库层代码不使用
Select语句直接检索数据,做到数据库层代码的最大的灵活性和可维护性。
一旦发现需要修改数据库中的
代码,只需要修改村年初过程即可以。
下面介绍Java使用SqlServerStoreProcedure的方法。
存储过程的参数使用“?
”代替,下面的代码有一定的代表性,存储过程有输入参数,输出参数。
存储过程的基本功能为:
检测userID和encPassword是否和数据库存储的一致,返回UserID,如果不一
致返回-1。
*/
//测试数据库中存储的已经加密的密码和用户传入的加密的密码是否一致。
publicbooleantestPassword(intuserID,byte[]encPassword){
Connectioncon=this.getConnection();
CallableStatementcs=null;
try{
cs=con.prepareCall("{?
=callsp_Accounts_TestPassword(?
?
)}");
cs.setInt(2,userID);
cs.setBytes(3,encPassword);
cs.registerOutParameter(1,Types.INTEGER);//@UserID
cs.execute();
if(cs.getInt
(1)==1){//密码合格
returntrue;
}
else{
returnfalse;
}
}
catch(SQLExceptionex){
returnfalse;
}
catch(Exceptione){
returnfalse;
}
}
}
以上只是我在学习和工作中的一点体会,写出来的目的使为了和大家交流,错误之处希望大家提出宝贵的意见,以便把该模块的功能做得更完善一点。