百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

如何应用策略设计模式的思想设计通用的数据库连接类

mhr18 2024-09-18 20:35 25 浏览 0 评论

软件项目实训及课程设计指导——如何应用策略设计模式的思想设计通用的数据库连接类

1、应用属性配置文件分离策略设计模式中的上下文环境类的工作参数

(1)在示例项目中添加一个名称为classNameConfig.properties的属性配置文件

根据Java系统平台中对属性文件(*.properties)解析的基本要求,该属性配置文件应该要存放在软件应用系统的classpath所在的路径中。该路径对于Web方式的应用程序则是在WEB–INFO/classes目录下。

但读者一定要注意属性配置文件(*.properties)的相对路径,否则对属性配置文件进行解析的程序将会由于找不到此属性配置文件而抛出找不到文件的异常错误信息。

因此,读者只需要在MyEclipse开发工具中右击项目的src文件夹,并在弹出的【新建文件】的对话框中输入属性配置文件名 classNameConfig.properties。最后的操作结果的图示请见下图示例图所示。

(2)设计属性配置文件 classNameConfig.properties中的配置项目

由于Java属性配置文件(*.properties)的项目内容是"键/值"对的形式存储,因此根据项目的数据库连接的需要分别提供五个不同的属性项目。

每个项目的内容请见下图所示的内容——它们分别代表MySQL数据库的JDBC驱动程序类、MySQL数据库文件webbank和在该数据库中的账号root和密码root等信息。

2、构建策略设计模式中的上下文环境类的功能实现代码

在本示例中的策略设计模式中的上下文环境类需要从属性配置文件中获得对应的工作参数,因此需要设计一个获得属性配置文件中的各个属性项目的ClassNameConfig程序类。

在java.lang.Class类中的getResourceAsStream方法将直接返回一个InputStream类型的流对象实例,而getResourceAsStream功能方法是查找具有给定名称的资源并返回 InputStream对象。

但要注意的是:getResourceAsStream功能方法在查找和定位属性配置文件时是相对于"/"根路径下的位置——这样的路径是指定绝对路径;如果在标识属性配置文件时不以"/"字符开头,则查找和定位的路径是相对于这个程序类(也就是ClassNameConfig程序类)文件所在包的路径。比如,下面的程序代码示例:

InputStream oneInputStreamObject =
													ClassNameConfig.class.getResourceAsStream("/classNameConfig.properties");

而java.lang.ClassLoader类中的getResource()功能方法则是从系统的classpath的根路径开始查找带有给定名称的资源路径和文件名并返回一个URL类型的对象示例。当然,当指定的程序类名字不能在当前的classpath目录路径中找到时,getResource()功能方法将返回null。

java.lang.Thread类中的contextClassLoader属性则代表线程的上下文 ClassLoader,因为每个运行中的线程都有一个成员contextClassLoader属性对象,用来在运行时动态地载入其它的程序类。并且可以采用下面形式的程序代码获得当前线程的contextClassLoader对象实例。

ClassLoader currentClassLoader= Thread.currentThread().getContextClassLoader();

因此,如果在某个线程中需要应用并加载某个外部的功能类,可以首先利用Thread.currentThread().getContextClassLoader()功能方法获得该线程的对象实例的contextClassLoader;然后再利用所获得的contextClassLoader对象实例请求它的父ClassLoader对象实例来完成外部程序类的载入请求。

完整的ClassNameConfig程序类的功能实现代码请见下面的程序代码示例所示——ClassNameConfig类的功能实现代码示例

package com.px1987.webbank.config;
import java.util.Properties;
import java.io.*;
public class ClassNameConfig {
      public ClassNameConfig() {
      }
      private static Properties onePropertiesObject =null;
      static {
          onePropertiesObject = new Properties();
          try{
                InputStream oneInputStreamObject =
                Thread.currentThread().getContextClassLoader().
                getResource("classNameConfig.properties").openStream();
                onePropertiesObject.load(input);
          }catch(Exception e){
          e.printStackTrace();
          }
      }
      public static String getProperty(String propName){
      		return onePropertiesObject.getProperty(propName);
      }
      public static void setProperty(String propName, String prop Value){
      		onePropertiesObject.setProperty(propName, propValue);
      }
}

请读者注意其中的黑体标识的语句,由于static静态成员属性对象能够达到全局缓存的应用效果,并且static语句块是在该程序类被加载时就执行的、而且也只执行一次。因此,static语句块也能够产生一种"单例"(单一对象实例,也就是单例设计模式)的应用效果,避免重复地对属性配置文件(*.properties)进行加载。另外,下面的语句代码片段:

InputStream oneInputStreamObject =Thread.currentThread().getContextClassLoader().
																						getResource("classNameConfig.properties").openStream();

其实等同于下面的程序代码:

ClassLoader currentClassLoader=Thread.currentThread().getContextClassLoader();
URL oneURL = currentClassLoader.getResource("classNameConfig.properties");
InputStream oneInputStreamObject = oneURL.openStream();

3、设计数据库连接的功能接口——它代表策略设计模式中的"算法"定义

在面向对象OOP的类设计中,一般都倡导面向接口编程功能实现,其基本的目的是为了能够达到分离"类的设计"和"类的功能实现"之间的依赖的基本目的。

因此,对于软件应用系统中的数据库连接的功能实现中,也首先设计一个名称为ConnectDBInterface的接口,然后再对该接口提供对应的功能实现类,实现类的名称为ConnectDBBean。

在MyEclipse开发工具中添加一个名称为ConnectDBInterface的接口,该接口的包名称为com.px1987.webbank.dao.inter。然后再设计和定义该ConnectDBInterface接口中的各个功能方法,最后的操作结果请见下图示例图所示。

4、设计数据库连接接口的具体功能实现类——它代表策略设计模式中的"算法"实现

在策略设计模式中的"算法"实现是可以有多种不同的形式,比如本示例中的数据库连接可以是基于JDBC API实现的数据库连接,也可以根据应用的需要提供基于数据库连接池的数据库连接或者是基于O/R Mapping应用框架的数据库连接等形式。

在本文中,作者只为读者介绍基于JDBC API实现的数据库连接示例。在MyEclipse开发工具中为ConnectDBInterface接口提供一个具体的功能实现类,类名称为ConnectDBBean,该类所在的包名称为com.px1987.webbank.dao.imple。然后再编程该功能实现类的代码。完整的功能实现代码请见下面的程序代码示例所示——ConnectDBInterface接口的功能实现类代码示例。

package com.px1987.webbank.dao.imple;
import java.sql.*;
import java.util.logging.*;
import com.px1987.webbank.config.ClassNameConfig;
import com.px1987.webbank.dao.inter.ConnectDBInterface;
import com.px1987.webbank.exception.WebBankException;
public class ConnectDBBean implements ConnectDBInterface {
      String JDBC_DBDriver_ClassName= null;
      String JDBC_DSN_URL = null;
      String JDBC_dbUserName=null;
      String JDBC_dbUserPassWord=null;
      private java.sql.Connection con = null;
      private Logger logger = Logger.getLogger(this.getClass().getName());
      public ConnectDBBean() throws WebBankException {
          /*利用ClassNameConfig实现从属性文件中获得与数据库相关的连接信息 */
          JDBC_DBDriver_ClassName =
          ClassNameConfig.getProperty("JDBC_DBDriver_ClassName");
          JDBC_DSN_URL = ClassNameConfig.getProperty("JDBC_DSN_URL");
          JDBC_dbUserName = ClassNameConfig.getProperty("JDBC_dbUserName");
          JDBC_dbUserPassWord = ClassNameConfig.getProperty("JDBC_dbUserPassWord");
          try {
          			Class.forName(JDBC_DBDriver_ClassName);
          }
          catch (java.lang.ClassNotFoundException e) {
                logger.log(Level.INFO, e.getMessage());
                throw new WebBankException("不能正确地加载JDBC驱动程序");
          }
          try {
                con = DriverManager.getConnection(JDBC_DSN_URL,
                JDBC_dbUserName, JDBC_dbUserPassWord);
          }
          catch (java.sql.SQLException e) {
                logger.log(Level.INFO, e.getMessage());
                throw new WebBankException("不能正确地连接数据库"+"并且出现SQLException");
          }
          catch (NullPointerException e){
                logger.log(Level.INFO, e.getMessage());
                throw new WebBankException("无法连接数据库"+"并且出现NullPointerException异常");
          }
      }
      public void closeDBCon() throws WebBankException {
          try {
              con.close();
              con = null;
          }
          catch (SQLException e){
              logger.log(Level.INFO, e.getMessage());
              throw new WebBankException("不能正确地关闭数据库连接");
          }
      }
      public Connection getConnection() throws WebBankException {
      		return con;
      }
}

在上面的程序代码中,作者应用JDK系统中所提供的日志处理技术实现错误信息的日志记录——请见其中的黑体部分的代码,但该方法只能将日志信息在控制台中显示输出,而无法保存到文件中。因此,在项目开发的后期将被重构改变为采用Log4J的日志技术实现——在此为了简化代码示例,对日志记录进行了功能实现方面的简化。

由于在数据库连接的功能实现ConnectDBBean类中不再直接以硬编码的方式包含有各种与物理数据库系统相关的连接参数,从而可以使得该ConnectDBBean类适用于连接不同的物理数据库系统,比如MySQL、Oracle或者MS SQLServer等数据库系统。

当软件应用系统最终应用的数据库系统发生变化时,维护人员只需要修改属性配置文件(*.properties)中与数据库连接相关的工作参数,而ConnectDBBean类本身并不需要修改。

因此,ConnectDBBean类可以是一个通用功能的数据库系统连接功能类。据此,读者应该对应用策略设计模式所具有的程序灵活性和通用性有更深刻的理解。

5、应用JUnit单元测试技术对ConnectDBBean组件类进行功能测试

依据体现策略设计模式程序类之间关系的UML类图,读者很容易理解此单元测试用例类TestConnectDBBean(参见如下示例图的代码示例)其实就是模拟策略设计模式中的客户端。在本示例项目中作者应用JUnit4.X版的系统库,因为它提供了许多方便单元测试的各个功能、并使得单元测试用例为一个普通的POJO类型的Java类。

由于在JUnit4.X版的系统库中应用了J2SE5.0新特性之"元数据"(在Java语言中也叫注释或者注解)。比如在单元测试用例中的@Before、@After和@Test等符号。

最后在MyEclipse开发工具中执行该测试用例类TestConnectDBBean的程序代码,该测试用例类的执行结果请见下图示例图所示;然后再将MySQL数据库服务器停止以测试是否出现错误,按照测试的逻辑应该要出现错误状态——为了节省篇幅,在此没有将错误的测试状态图附录出。

从测试用例类的执行结果来看,ConnectDBBean组件类的功能实现是正确的、而且对属性配置文件中的各个属性项目的解析也是正确的。

如何应用策略设计模式分离JDBC数据库连接中的外部环境信息

如何正确地创建和销毁软件应用系统中JDBC数据库连接对象实例

如何应用GOF设计模式中的构建者模式创建复合对象实例

如何应用GOF设计模式中的创建型模式实现松耦合地创建对象实例

如何正确应用Web MVC架构模式分离表示层和模型层耦合关系

相关推荐

甲骨文签署多项大型云协议,其一未来可贡献超300亿美元年收入

IT之家7月1日消息,根据甲骨文Oracle当地时间6月30日向美国证券交易委员会(SEC)递交的FORM8-K文件,该企业在始于2025年6月1日的202...

甲骨文获TEMU巨额合同,后者大部分基础设施将迁移至Oracle云

IT之家6月23日消息,Oracle甲骨文创始人、董事长兼首席技术官LarryEllison(拉里埃里森)在本月早些时候的2025财年第四财季和全财年财报电话会议上表示,Oracle...

Spring Boot 自定义数据源设置,这些坑你踩过吗?

你在使用SpringBoot进行后端开发的过程中,是不是也遇到过这样的问题:项目上线后,数据库连接总是不稳定,偶尔还会出现数据读取缓慢的情况,严重影响了用户体验。经过排查,发现很大一部分原因竟然...

一个开箱即用的代码生成器(一个开箱即用的代码生成器是什么)

今天给大家推荐一个好用的代码生成器,名为renren-generator,该项目附带前端页面,可以很方便的选择我们所需要生成代码的表。首先我们通过git工具克隆下来代码(地址见文末),导入idea。...

低代码建模平台-数据挖掘平台(低代码平台的实现方式)

现在来看一下数据连接。·这里是管理数据连接的空间,点击这里可以新增一个数据连接。·输入连接名称,然后输入url,是通过gdbc的方式去连接的数据库,目前是支持mysql、oracle以及国产数据库达梦...

navicat 17.2.7连接oracle数据库提示加载oracle库失败

系统:macOS15.5navicat版本:navicatpremiumlite17.2.7连接oracle测试报错:加载oracle库失败【解决办法】:放达里面找到程序,显示简介里面勾选“使...

开源“Windows”ReactOS更新:支持全屏应用

IT之家6月17日消息,ReactOS团队昨日(6月16日)在X平台发布系列推文,公布了该系统的最新进展,包括升级Explorer组件,支持全屏应用,从Wine项目引入了...

SSL 推出采用全模拟内置混音技术的模拟调音台Oracle

英国调音台传奇品牌SolidStateLogic宣布推出Oracle——一款采用全模拟内置混音技术的调音台,在紧凑的AWS尺寸机箱内集成了大型调音台的功能。该调音台提供24输入和...

47道网络工程师常见面试题,看看有没有你不会的!

你们好,我的网工朋友。网络工程师面试的时候,都会被问到什么?这个问题其实很泛,一般来说,你肯定要先看明白岗位需求写的是什么。基本上都是围绕公司需要的业务去问的。但不可否认的是,那些最基础的概念,多少也...

汉得信息:发布EBS系统安装启用JWS的高效解决方案

e公司讯,从汉得信息获悉,近日,微软官方宣布InternetExplorer桌面应用程序将于2022年6月15日正式停用。目前大部分客户都是使用IE浏览器打开EBS的Form界面,IE停用后,只能使...

36.9K star ! 推荐一个酷炫低代码开发平台!功能太强!

前言最近在逛github,看看能不能搜罗到一些对自己有帮助的开源软件。不经意间看到一个高star的java开源项目:jeecg-boot。进入在线演示版一看,感叹实在是太牛了!此开源项目不管是给来学习...

Linux新手入门系列:Linux下jdk安装配置

本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...

手把手教你在嵌入式设备中使用SQLite3

摘要:数据库是用来存储和管理数据的专用软件,使得管理数据更加安全,方便和高效。数据库对数据的管理的基本单位是表(table),在嵌入式linux中有时候它也需要用到数据库,听起来好难,其实就是几个函数...

JAVA语言基础(java语言基础知识)

一、计算机的基本概念什么是计算机?计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行、自动高速处理海量数据的现代化智能电子设备。由硬件和软件组成、没有安装过任何软件的计算机称...

再见 Navicat!一款开源的 Web 数据库管理工具!

大家好,我是Java陈序员。在日常的开发工作中,常常需要与各种数据库打交道。而为了提高工作效率,常常会使用一些可视化工具进行操作数据库。今天,给大家介绍一款开源的数据库管理工具,无需下载安装软件,基...

取消回复欢迎 发表评论: