分享
 
 
 

用Java实现数据库应用系统

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

我们在做信息系统的时候,都要访问数据库,我最近接手一个项目,项目组决定使用Java编写,我负责数据层的设计和编码,为了提高代码的重用性和提高项目的开发效率。我们开发了一个通用的数据库连接和完成基本操作的类库,个人认为这个类在做MIS系统时还是有一定的价值,所以总结出来,介绍给大家。

连接工厂,实现了DataSource接口

package skydev.modules.data;

import java.sql.*;

import javax.sql.DataSource;

import java.io.PrintWriter;

public class ConnectionFactory implements DataSource {

private String userName;

private String password;

private String driverName;

private String url;

private java.sql.Connection connection;

/**

* 根据设置的连接参数创建一个新的连接实例

* @return

*/

private Connection getNewConnection() {

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.password);

}

catch (SQLException e) {

throw e;

}

}

finally {

return this.connection; //返回新建立的连接

}

}

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public String getDriverName() {

return driverName;

}

public void setDriverName(String driverName) {

this.driverName = driverName;

}

public String getUrl() {

return url;

}

public void setUrl(String url) {

this.url = url;

}

public java.sql.Connection getConnection() {

if (connection != null) {

try {

if (connection.isClosed()) {

connection = null;

getNewConnection();

}

}

catch (SQLException ex) {

}

}

if (connection == null) { //没有设置连接则创建一个连接

getNewConnection();

}

return connection;

}

public Connection getConnection(String userName, String password) throws

SQLException {

this.setUserName(userName);

this.setPassword(password);

return getConnection();

}

public PrintWriter getLogWriter() {

return null;

}

public void setLogWriter(PrintWriter printWriter) {

}

public void setLoginTimeout(int int0) {

}

public int getLoginTimeout() {

return 0;

}

}

实现连接SQLServer的连接工厂,这里因为我们的项目使用SQLServer2000所以只实现了SqlServerConnectionFactory。

package skydev.modules.data;

public final class SqlServerConnectionFactory extends ConnectionFactory {

private final String dbDriver ="com.microsoft.jdbc.sqlserver.SQLServerDriver";

private String host;//主机

private int port;//端口

private String databaseName;//Sql数据库名称

public SqlServerConnectionFactory() {

super.setDriverName(dbDriver);

}

/**

*

* @param host 数据库所在的主机名:如"localhost"

* @param port SQL服务器运行的端口号,如果使用缺省值 1433,传入一个负数即可

* @param databaseName 数据库名称

* @param userName 用户名

* @param password 口令

*/

public SqlServerConnectionFactory(String host,

int port,

String databaseName,

String userName,

String password) {

this.setHost(host);

this.setPort(port);

this.setDatabaseName(databaseName);

this.setUserName(userName);

this.setPassword(password);

init();

}

private void init() {

super.setDriverName(dbDriver);

super.setUrl("jdbc:microsoft:sqlserver://" + host.trim() + ":" +

new Integer(port).toString() + ";DatabaseName=" +

databaseName.trim());

//super.setUrl("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=demo");

}

public void setHost(String host) {

//处理主机名称

if ( (host == null) || (host.equals("")) || (host.equals(".")) ||

(host.equals("local"))) {

host = "localhost";

}

int index = host.indexOf("//", 0);

if (index == 0) {

host = host.substring(2); //去掉前面的"//"

}

index = host.indexOf("//", 0);

if (index >= 0) {

try {

throw new Exception("SQL Server主机名参数错误!");

}

catch (Exception ex) {

}

}

this.host = host;

}

public void setPort(int port) {

/**

* 缺省端口1433

*/

if (port < 0) {

port = 1433;

}

this.port = port;

}

public void setDatabaseName(String databaseName) {

this.databaseName = databaseName;

}

}

使用"sun.jdbc.odbc.JdbcOdbcDriver"连接数据库的连接工厂

package skydev.modules.data;

public class JdbcOdbcConnectionFactory extends ConnectionFactory {

private final static String driveName = "sun.jdbc.odbc.JdbcOdbcDriver";

private String odbcName;

public JdbcOdbcConnectionFactory() {

super.setDriverName(driveName);

}

/**

*使用指定的Odbc数据源连接数据库服务器

* @param odbcName

*/

public JdbcOdbcConnectionFactory(String odbcName) {

super.setDriverName(driveName);

setOdbcName(odbcName);

}

public void setOdbcName(String odbcName) {

this.odbcName = odbcName;

this.setUrl("jdbc:odbc:" + odbcName);

}

}

package skydev.modules.data;

import java.sql.*;

import java.sql.PreparedStatement;

import javax.sql.DataSource;

public abstract class DatabaseObject {

protected Connection connection = null;

protected ResultSet resultSet = null;

protected ResultSetMetaData resultSetMetaData = null;

private ConnectionFactory connectionFactory = null;

private java.sql.Statement statement=null;

private javax.sql.DataSource dataSource;//=new Statement();

public DatabaseObject(){

dataSource=null;

connection=null;

}

public DatabaseObject(ConnectionFactory connectionFactory) {

this.setConnectionFactory(connectionFactory);

this.dataSource=connectionFactory;//ConnectionFactory实现了DataSource接口

}

/**

* 执行查询

* @param sql 要执行的Sql语句

* @return返回查询的结果集 ,查询失败返回null

*/

public ResultSet getResultSet(String sql) {

try {

this.resultSet = statement.executeQuery(sql); //保留内部指针

}

catch (SQLException e) {

e.printStackTrace();

this.resultSet = null;

}

finally {

return this.resultSet;

}

}

/**

* 获取外部指定ResltSet的ResultSetMetaData数据

* @param resultSet 要获取的ResultSet

* @return 失败返回null

*/

public ResultSetMetaData getResultSetMetaData(ResultSet resultSet) {

ResultSetMetaData resultSetMetaData = null;

try {

resultSetMetaData = resultSet.getMetaData();

}

catch (SQLException e) {

e.printStackTrace();

resultSetMetaData = null;

}

finally {

return resultSetMetaData;

}

}

/**

* 获取最近一次设置或者返回的ResultSet的ResultMetaData数据,

* 比方说调用了:getResultSet(sql)方法,然后调用getResultSetMetaData方法

* 可以获得相应的ResultSetMetaData数据。

* @return

*/

public ResultSetMetaData getResultSetMetaData() {

return this.getResultSetMetaData(this.resultSet);

}

/**

* 执行存储过程

* @param spName 存储过程名称

* @return

*/

public ResultSet Execute(String spName) {

//对此数据库执行一个 SQL 查询

ResultSet resultSet = null;

try {

// PreparedStatement stmt = (PreparedStatement) connection.createStatement();

resultSet = statement.executeQuery(spName);

}

catch (Exception e) {

System.out.println("execute error" + e.getMessage());

}

return resultSet;

}

/**

* 设置数据库连接工厂,对此类的所有操作之前,必须调用该方法,

* 设置数据库连接工厂。

* @param connectionFactory 数据库连接工厂ConnectionFactory 类对象以及

* 派生类对象。

*/

public void setConnectionFactory(ConnectionFactory connectionFactory) {

this.connectionFactory = connectionFactory;

connection = connectionFactory.getConnection();

try {

statement = connection.createStatement();

}

catch (SQLException ex) {

System.err.println(ex);

}

}

public Connection getConnection() {

return connection;

}

public java.sql.Statement getStatement() {

return statement;

}

public javax.sql.DataSource getDataSource() {

return dataSource;

}

}

具体项目的数据库访问基类

package skydev.modules.data;

public class DbObject extends DatabaseObject {

// private final static String driveName = "sun.jdbc.obdc.JdbcOdbcDriver";

public DbObject() {

super(new SqlServerConnectionFactory("localhost", 1433, "TheSchool", "sa",""));

}

public DbObject(ConnectionFactory connectionFactory) {

super(connectionFactory);

}

}

在项目中的数据库层中的数据库访问类都从DatabaseObject类派生,这样只需要在一个地方设置数据连接,其他地方都不需要涉及数据库访问的具体连接代码。

如:User类专门负责Users组的权限控制等,只需要简单的代码就可以连接并访问数据库了。这里具体实 现与此文章无关,只举一两个模块做例子。

public class User extends DbObject {

public User() {

//子类也可以覆盖基类的访问方式,在单机调式时有用。

// super(new SqlServerConnectionFactory("localhost", 1433, "TheSchool", "sa",""));

super();//调用基类的数据库访问代码。

}

/*

在做信息系统时为了提高客维护性,我们一般使用存储过程返回和修改数据,在数据库层代码不使用

Select语句直接检索数据,做到数据库层代码的最大的灵活性和可维护性。一旦发现需要修改数据库中的

代码,只需要修改村年初过程即可以。

下面介绍Java使用SqlServer StoreProcedure的方法。

存储过程的参数使用“?”代替,下面的代码有一定的代表性,存储过程有输入参数,输出参数。

存储过程的基本功能为:检测userID和encPassword是否和数据库存储的一致,返回UserID,如果不一

致返回-1。

*/

//测试数据库中存储的已经加密的密码和用户传入的加密的密码是否一致。

public boolean testPassword(int userID, byte[] encPassword) {

Connection con = this.getConnection();

CallableStatement cs = null;

try {

cs = con.prepareCall("{?=call sp_Accounts_TestPassword(?,?)}");

cs.setInt(2, userID);

cs.setBytes(3, encPassword);

cs.registerOutParameter(1, Types.INTEGER); //@UserID

cs.execute();

if (cs.getInt(1) == 1) { //密码合格

return true;

}

else {

return false;

}

}

catch (SQLException ex) {

return false;

}

catch (Exception e) {

return false;

}

}

}

以上只是我在学习和工作中的一点体会,写出来的目的使为了和大家交流,错误之处希望大家提出宝贵的意见,以便把该模块的功能做得更完善一点。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有