一前言 本文的目的是将一个获取数据库连接的普通类重构成DAO+Abstract Factory模式 二设计初衷 使用数据访问对象(DAOData Access Object)模式来抽象和封装所有对数据源的访问DAO管理着与数据源的连接以便检索和存储数据可以降低商业逻辑层和数据访问层的耦合度提高应用的可维护性和可移植性 由于底层数据源实现变化时DAO向客户端提供的接口不会变化所有该模式允许DAO调整到不同的存储模式而不会影响其客户端或者业务组件显然DAO充当了组件和数据源之间的适配器 三重构 首先创建一个获取数据库连接的普通类 DAOClientjava import javasql*; publicclass DAOClient { publicstaticvoid main( String[] args ) { try { //For Oracle ClassforName( oraclejdbcdriverOracleDriver ); Connection conn = DriverManagergetConnection( jdbc:oracle:thin:@localhost::dy scott tiger ); Systemoutprintln( conntoString() ); } catch ( ClassNotFoundException e ) { eprintStackTrace(); } catch ( SQLException e ) { eprintStackTrace(); } } } 再将这段代码封装到一个getConnection()方法中以便其它的地方调用 import javasql*; publicclass DAOClient { publicstaticvoid main( String[] args ) { Connection conn = getConnection(); Systemoutprintln( conntoString() ); } /** *得到一个Connection对象 *@returnjavasqlConnection */ privatestatic Connection getConnection() { Connection conn = null; try { //For Oracle ClassforName( oraclejdbcdriverOracleDriver ); conn = DriverManagergetConnection( jdbc:oracle:thin:@localhost::dy scott tiger ); } catch ( ClassNotFoundException e ) { eprintStackTrace(); } catch ( SQLException e ) { eprintStackTrace(); } return conn; } } 再将此方法定义到针对Oracle的工厂类中 OracleDAOFactoryjava import javasql*; publicclass OracleDAOFactory { private OracleDAOFactory() {} /** *返回一个OracleDAOFactory对象 *@returnOracleDAOFactory类型对象 */ publicstatic OracleDAOFactory newInstance() { returnnew OracleDAOFactory(); } /** *得到一个Connection对象 *@returnjavasqlConnection */ public Connection getConnection() { Connection conn = null; try { //For Oracle ClassforName( oraclejdbcdriverOracleDriver ); conn = DriverManagergetConnection( jdbc:oracle:thin:@localhost::dy scott tiger ); } catch ( ClassNotFoundException e ) { eprintStackTrace(); } catch ( SQLException e ) { eprintStackTrace(); } return conn; } } 此时DAOClientjava这个测试类的代码应修改为 import javasql*; public class DAOClient { publicstaticvoid main( String[] args ) { Connection conn = OracleDAOFactorynewInstance()getConnection(); Systemoutprintln( conntoString() ); } } 考虑通常数据库服务器数据库名数据库用户密码等应该从配置文件中获取因此修改Oracle的工厂类 import javaioIOException; import javasqlConnection; import javasqlDriverManager; import javasqlSQLException; import javautilProperties; publicclass OracleDAOFactory { privatestatic Properties prop = new Properties(); static { try { propload( OracleDAOFactoryclass getResourceAsStream( configproperties ) ); } catch ( IOException e ) { Systemoutprintln( File:configproperties no findPLS check out! ); eprintStackTrace(); } } private String CONNECTION_SERVER_NAME = prop getProperty( oracle_server_name ); private String CONNECTION_DRIVER = propgetProperty( oracle_conn_driver ); private String CONNECTION_DBINSTANCE = prop getProperty( oracle_dbInstance ); private String CONNECTION_USER = propgetProperty( oracle_conn_user ); private String CONNECTION_PWD = propgetProperty( oracle_conn_pwd ); private String CONNECTION_URL = jdbc:oracle:thin:@ + CONNECTION_SERVER_NAME + :: + CONNECTION_DBINSTANCE; private OracleDAOFactory() {} /** *返回一个OracleDAOFactory对象 *@returnOracleDAOFactory类型对象 */ publicstatic OracleDAOFactory newInstance() { returnnew OracleDAOFactory(); } /** *得到一个Connection对象 *@returnjavasqlConnection */ public Connection getConnection() { Connection conn = null; try { ClassforName( CONNECTION_DRIVER ); conn = DriverManagergetConnection( CONNECTION_URL CONNECTION_USER CONNECTION_PWD ); } catch ( ClassNotFoundException e ) { eprintStackTrace(); } catch ( SQLException e ) { eprintStackTrace(); } return conn; } } 添加配置文件configproperties oracle_server_name=localhost oracle_conn_driver=oraclejdbcdriverOracleDriver oracle_dbInstance=dy oracle_conn_user=scott oracle_conn_pwd=tiger 继续考虑客户端在获取数据库连接时使用的是针对Oracle的数据库的工厂但如果数据库变化了那么客户端的代码还是要改变因此可以定义一个DAOFactory类定义了一个抽象方法getConnection()用于获取数据库连接还有一个getDAOFactory()方法根据参数dbType的值返回不同的DAOFactory DAOFactoryjava import javasqlConnection; publicabstractclass DAOFactory { publicstaticfinalintORACLE = ; publicstaticfinalintSQLSERVER = ; publicstaticfinalintMYSQL = ; public abstract Connection getConnection(); publicstatic DAOFactory getDAOFactory( int dbType ) { switch( dbType ) { caseORACLE: return OracleDAOFactorynewInstance(); caseSQLSERVER: return SqlDAOFactorynewInstance(); caseMYSQL: return MySqlDAOFactorynewInstance(); default: returnnull; } } } SqlDAOFactoryjava import javaioIOException; import javasqlConnection; import javasqlDriverManager; import javasqlSQLException; import javautilProperties; publicclass SqlDAOFactory extends DAOFactory { privatestatic Properties prop = new Properties(); static { try { propload( OracleDAOFactoryclass getResourceAsStream( configproperties ) ); } catch ( IOException e ) { Systemoutprintln( File:configproperties no findPLS check out! ); eprintStackTrace(); } } private String CONNECTION_SERVER_NAME = prop getProperty( sqlserver_server_name ); private String CONNECTION_DRIVER = propgetProperty( sqlserver_conn_driver ); private String CONNECTION_DBINSTANCE = prop getProperty( sqlserver_dbInstance ); private String CONNECTION_USER = propgetProperty( sqlserver_conn_user ); private String CONNECTION_PWD = propgetProperty( sqlserver_conn_pwd ); private String CONNECTION_URL = jdbc:microsoft:sqlserver:// + CONNECTION_SERVER_NAME + :;DatabaseName= + CONNECTION_DBINSTANCE; private SqlDAOFactory() {} /** *返回一个SqlDAOFactory对象 *@returnSqlDAOFactory类型对象 */ publicstatic SqlDAOFactory newInstance() { returnnew SqlDAOFactory(); } /** *得到一个Connection对象 *@returnjavasqlConnection */ public Connection getConnection() { Connection conn = null; try { ClassforName( CONNECTION_DRIVER ); conn = DriverManagergetConnection( CONNECTION_URL CONNECTION_USER CONNECTION_PWD ); } catch ( ClassNotFoundException e ) { eprintStackTrace(); } catch ( SQLException e ) { eprintStackTrace(); } return conn; } } MySqlDAPFactoryjava import javaioIOException; import javasqlConnection; import javasqlDriverManager; import javasqlSQLException; import javautilProperties; publicclass MySqlDAOFactory extends DAOFactory { privatestatic Properties prop = new Properties(); static { try { propload( OracleDAOFactoryclass getResourceAsStream( configproperties ) ); } catch ( IOException e ) { Systemoutprintln( File:configproperties no findPLS check out! ); eprintStackTrace(); } } private String CONNECTION_SERVER_NAME = prop getProperty( mysql_server_name ); private String CONNECTION_DRIVER = propgetProperty( mysql_conn_driver ); private String CONNECTION_DBINSTANCE = prop getProperty( mysql_dbInstance ); private String CONNECTION_USER = propgetProperty( mysql_conn_user ); private String CONNECTION_PWD = propgetProperty( mysql_conn_pwd ); private String CONNECTION_URL = jdbc:mysql:// + CONNECTION_SERVER_NAME + :/ + CONNECTION_DBINSTANCE + ?useUnicode=true&characterEncoding=UTF; private MySqlDAOFactory() {} /** *返回一个MySqlDAOFactory对象 *@returnMySqlDAOFactory类型对象 */ publicstatic MySqlDAOFactory newInstance() { returnnew MySqlDAOFactory(); } /** *得到一个Connection对象 *@returnjavasqlConnection */ public Connection getConnection() { Connection conn = null; try { ClassforName( CONNECTION_DRIVER ); conn = DriverManagergetConnection( CONNECTION_URL CONNECTION_USER CONNECTION_PWD ); } catch ( ClassNotFoundException e ) { eprintStackTrace(); } catch ( SQLException e ) { eprintStackTrace(); } return conn; } } 修改configproperties配置文件 #Oracle oracle_server_name=localhost oracle_conn_driver=oraclejdbcdriverOracleDriver oracle_dbInstance=dy oracle_conn_user=scott oracle_conn_pwd=tiger #SqlServer sqlserver_server_name=localhost sqlserver_conn_driver=commicrosoftjdbcsqlserverSQLServerDriver sqlserver_dbInstance=test sqlserver_conn_user=sa sqlserver_conn_pwd=sa #MySql mysql_server_name=localhost mysql_conn_driver=commysqljdbcDriver mysql_dbInstance=test mysql_conn_user=root mysql_conn_pwd=root 最后修改客户端文件DAOClientjava代码 import javasql*; public class DAOClient { public static void main( String[] args ) { DAOFactory dao = DAOFactorygetDAOFactory( DAOFactoryORACLE ); Connection conn = daogetConnection(); Systemoutprintln( conntoString() ); } } 通过这种DAO+(Abstract)Factory方式在将程序迁移到其它数据库中时在客户端程序中几乎不用做修改唯一需要做的就是在获得DAOFactory对象的时候修改相应的参数例如迁移到MySql下的时候 DAOFactory dao = DAOFactorygetDAOFactory( DAOFactoryMYSQL ); |