当前位置: 首页 > news >正文

java sql系统_用Java实现数据库应用系统

我们在做信息系统的时候,都要访问数据库,我最近接手一个项目,项目组决定使用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;

}

}

}

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

相关文章:

  • jmeter的java请求参数设置_jmeter之 java请求
  • java如何设置系统属性_java – 设置系统属性
  • java ajax增删改查_使用AJAX实现数据的增删改查
  • java去掉结尾的空格_如何从Java中显示的字符串末尾删除空格?
  • java最大回文字符串长度_Leet Code 5 最长回文子串 - Java
  • java泡沫_Java初认识--函数和数组
  • java虚拟机内存溢出的三个原因_JVM发生内存溢出的原因分析及解决方案
  • mysql更新多个字段php_PHP:如果语句无意中导致多个MySQL列更新?
  • properties java jar_propertiesutil jar包
  • python段落注释的语法格式是_Python 基础语法
  • python读取xml配置_python解析xml配置文件
  • java 接口数据类型_Java中的基本数据类型与引用数据类型
  • java 红包接口开发_java调用微信现金红包接口的心得与体会总结
  • java项目中学到了什么_我们能从Java的HelloWorld中学到什么?
  • js java md5加密_MD5加密 (java、js)
  • bootstrap创建登录注册页面
  • ES学习笔记(12)--Symbol
  • httpie使用详解
  • HTTP中GET与POST的区别 99%的错误认识
  • Java多态
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • LintCode 31. partitionArray 数组划分
  • SpiderData 2019年2月25日 DApp数据排行榜
  • spring security oauth2 password授权模式
  • storm drpc实例
  • 动态规划入门(以爬楼梯为例)
  • 给github项目添加CI badge
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 微信支付JSAPI,实测!终极方案
  • Java总结 - String - 这篇请使劲喷我
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (二)c52学习之旅-简单了解单片机
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • 、写入Shellcode到注册表上线
  • .NET Core 成都线下面基会拉开序幕
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .net wcf memory gates checking failed
  • .net web项目 调用webService
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .Net多线程总结
  • .net开发时的诡异问题,button的onclick事件无效
  • .Net下的签名与混淆
  • .pyc文件是什么?
  • @RequestParam,@RequestBody和@PathVariable 区别
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • @SuppressWarnings(unchecked)代码的作用
  • [ C++ ] STL---string类的使用指南
  • [AIGC] Spring Interceptor 拦截器详解
  • [Android]使用Git将项目提交到GitHub
  • [BUAA软工]第一次博客作业---阅读《构建之法》
  • [BZOJ3223]文艺平衡树
  • [CERC2017]Cumulative Code