电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

如何重构出DAO模式


发布日期:2023/3/12
 

前言

本文的目的是将一个获取数据库连接的普通类重构成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 );

上一篇:JNDI Connection 池化

下一篇:Groovy轻松入门——Grails实战之GORM