JDBC 配置文件工厂模式封装

本文介绍了一种使用工厂模式封装JDBC代码的方法,通过配置文件和抽象类实现数据库连接的获取与关闭,支持多种数据库类型的灵活切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在我们写程序的时候,我们想要的代码就是高内聚低耦合,能重用,能按照需求能灵活改变,而在jdbc 这里我们我们变得就只有数据库了,所以在写代码的时候我们要注意些的代码在数据库边的时候是否能灵活的改变,废话少说下面我们就来看看使用工厂模式来封装的jdbc代码。

一、方式一代码如下:

1、数据库信息配置文件:ConnectionConfig.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/music?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
user=root
password=admin

2、配置文件读取代码:ConnectionConfig.java

package jdbc;

import java.io.IOException;
import java.util.Properties;

/**
 * @author WHD data 2016年2月16日
 */
public class ConnectionConfig {
	private static Properties prop = new Properties();
	static {
		try {
			// InputStream input =
			// ClassLoader.getSystemResourceAsStream("ConnectionConfig.properties");
			// InputStream input =
			// ConnectionConfig.class.getClassLoader().getSystemResourceAsStream("ConnectionConfig.properties");
			// prop.load(input);
			prop.load(ConnectionConfig.class.getClassLoader()
					.getResourceAsStream("ConnectionConfig.properties"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static String driver = prop.getProperty("driver");
	public static String url = prop.getProperty("url");
	public static String user = prop.getProperty("user");
	public static String password = prop.getProperty("password");
}

3、获取Connection 接口代码:IDBConnection.java

package jdbc;

import java.sql.Connection;

/**
 * @author WHD data 2016年2月15日
 */
public interface IDBConnection {
	public abstract Connection getConnection();

	public abstract void closeConnection(Connection conn);
}

4、获取Conection接口实现抽象类代码:AbstractConnectionImpl.java

package jdbc;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author WHD data 2016年2月15日
 */
public abstract class AbstractConnectionImpl implements IDBConnection {
	public void closeConnection(Connection conn) {
		try {
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public Connection getConnection() {
		// TODO Auto-generated method stub
		return null;
	}

}

5、获取Connection抽象类继承类代码:ConnectionImpl.java

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @author WHD data 2016年2月16日
 */
public class ConnectionImpl extends AbstractConnectionImpl {
	@Override
	public Connection getConnection() {
		// TODO Auto-generated method stub
		Connection conn = null;
		try {
			Class.forName(ConnectionConfig.driver);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			conn = DriverManager.getConnection(ConnectionConfig.url,
					ConnectionConfig.user, ConnectionConfig.password);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}

	@Override
	public void closeConnection(Connection conn) {
		// TODO Auto-generated method stub
		super.closeConnection(conn);
	}

	public static void main(String[] args) {
		ConnectionImpl imp = new ConnectionImpl();
		imp.getConnection();
	}
}

6、获取IDBConnection实例其实也就是获取Connection实例的工厂类代码:DBConnectionFactory.java

package jdbc;
/**
 *@author WHD
 *data 2016年2月15日
 */
public class DBConnectionFactory {
	  //定义一个接口
    private static IDBConnection instance;
    //同步锁
    private static Object initLock = new Object();
    public static IDBConnection getInstance() {
        if (instance == null) {
            synchronized (initLock) {
                        instance=new ConnectionImpl();
            }
        }
        return instance;
    }

}

7、调用工厂类获取数据库链接代码:DBConnection.java

package jdbc;

import java.sql.Connection;

/**
 * @author WHD data 2016年2月15日
 */
public class DBConnection {
	public static Connection getConnection() {
		/**
		 * 用户无需了解底层是如何实现的,它也不需要关心使用的是哪种数据库
		 */
		IDBConnection service = DBConnectionFactory.getInstance();
		Connection conn = service.getConnection();
		return conn;
	}

	public static void closeConnection(Connection conn) {
		IDBConnection service = DBConnectionFactory.getInstance();
		service.closeConnection(conn);
	}
}

8、测试类代码:Test.java

package jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author WHD data 2016年2月15日
 */
public class Test {
	public Test() {
	}

	public static void main(String[] args) throws SQLException {
		Connection con = DBConnection.getConnection();
		String sql = "select * from musics limit  10";
		PreparedStatement pre = con.prepareStatement(sql);
		ResultSet res = pre.executeQuery();
		try {
			while (res.next()) {
				int id = res.getInt(1);
				String title = res.getString(2);
				System.out.println("id  " + id + "  title  " + title);
			}
		} finally {
			DBConnection.closeConnection(con);
		}
	}
}

9、代码执行结果



   到这里我们的代码展示都结束了,我们来个小小的总结:

  这个过程是 配置文件来配置数据库的相关信息,而ConnectionConfig  这个类就是读取配置文件中数据库的信息。而定义的接口就是一个获取Connection和释放Connection的两个方法,而抽象了实现了这个接口并且实现了释放Connection 方法,而ConnectionImpl 这个类继承了那个抽象了并且实现了获取Connection 的方法,而获取Connection 时数据库相关的信息来自于之前类配置文件中的数据,到这里我们已经能够获取Connection 实例了,而之后的工厂类,工厂类有两个方法,一个是获取Connection 实例的方法而另一个就是释放Connection 资源的方法。而工厂类中的获取Connection 实例的方法就是实例化一个ConnectionImpl 类这样就能调用ConnectionImpl 类的相关方法来获取Connection 实例,ok 到这里我们调用工厂类的响应方法就能获取Connection。在整个过程中和数据库相关的只有一个地方那就是数据库配置文件,这里配置了那个数据库的信息我们就获取那个数据库的链接如果想要MySQL的数据库链接则配置MySQL 相关信息而配置Oracle 则一样配置Oracle 数据库的相关信息而代码一个都不用改,这样就方便多了。


第一种方式中我们使用了一个配置文件,也就是数据库配置文件这种配置方式中我们只需要修改配置文件就能修改获取的数据库链接而还有一种方式就是除了数据库配置文件还有类名配置文件,这样我们可以有多个数据库配置文件,每一个配置一种数据库,而类名配置文件中的类名就是实现接口和抽象类的那个,也就是获取具体数据库链接的类,这个Factory 类什么的都一样了,和上面的相比就是多了一个配置文件,这个配置文件中配置了类名,这样不用修改数据库配置文件而是修改类名配置文件来改变获取的数据库的链接。


二、第二种实现方式代码:

1、数据库配置文件:MySqlConnectionConfig.properties(需要几个数据库就可以配置几个数据库配置文件这里是mysql的配置)

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/music?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
user=root
password=admin
2、获取对应数据库配置文件的类:MySqlConnectionConfig.java

package jdbc;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 *@author WHD
 *data 2016年2月15日
 */
public class MySqlConnectionConfig {
    private static Properties prop = new Properties();
    static {
        try {
        	//InputStream input = ClassLoader.getSystemResourceAsStream("MySqlConnectionConfig.properties");
        	//InputStream input = MySqlConnectionConfig.class.getClassLoader().getSystemResourceAsStream("MySqlConnectionConfig.properties");
        	//prop.load(input);
        	prop.load(MySqlConnectionConfig.class.getClassLoader().getResourceAsStream("MySqlConnectionConfig.properties"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static String driver = prop.getProperty("driver");
    public static String url = prop.getProperty("url");
    public static String user = prop.getProperty("user");
    public static String password = prop.getProperty("password");
    
}

3、获取Connection 连接是Connection资源释放的接口:IDBConnection.java

package jdbc;

import java.sql.Connection;

/**
 * @author WHD data 2016年2月15日
 */
public interface IDBConnection {
	public abstract Connection getConnection();

	public abstract void closeConnection(Connection conn);
}

4、实现Connection连接和Connection 资源释放的抽象类:AbstractConnectionImpl.java

package jdbc;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author WHD data 2016年2月15日
 */
public abstract class AbstractConnectionImpl implements IDBConnection {
	public void closeConnection(Connection conn) {
		try {
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public Connection getConnection() {
		// TODO Auto-generated method stub
		return null;
	}

}


5、具体数据库连接获取的实现了:MySqlConnectionImpl.java   (因为这里使用了mysql为例,但是我们在使用的过程配置几个数据库配置文件,就要有几个具体的连接获取类)

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 *@author WHD
 *data 2016年2月15日
 */
public class MySqlConnectionImpl  extends AbstractConnectionImpl {
	  @Override
      public Connection getConnection() {
          // TODO Auto-generated method stub
          Connection conn = null;
          try {
              Class.forName(MySqlConnectionConfig.driver);
          } catch (ClassNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
          try {
              conn = DriverManager.getConnection(MySqlConnectionConfig.url,
                      MySqlConnectionConfig.user, MySqlConnectionConfig.password);
          } catch (SQLException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
          return conn;
      }
      @Override
      public void closeConnection(Connection conn) {
          // TODO Auto-generated method stub
          super.closeConnection(conn);
      }

	public static void main(String[]args){
		MySqlConnectionImpl  imp= new MySqlConnectionImpl();
		imp.getConnection();
	}
}


6、对象配置文件:DBConfig.properties(这里面配置那个数据库Connection 连接获取类的类名称就获取那个数据库Connection实例)

//这里配置了Mysql 实现类的,当然也可以配置oracle sqlserver 等数据库Connection连接获取类的类名称。

className=jdbc.MySqlConnectionImpl

7、类名称配置文件中值获取的类:DBConnectionConfig.java

package jdbc;

import java.io.IOException;
import java.util.Properties;

/**
 *@author WHD
 *data 2016年2月15日
 */
public class DBConnectionConfig {
	   //对象文件配置
    private static Properties prop = new Properties();
    static {
        try {
            prop.load(DBConnectionConfig.class.getClassLoader()
                    .getResourceAsStream("DBConfig.properties"));
            System.out.println( prop.getProperty("className"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    // 重配置文件中获取的类名称
    public static String className = prop.getProperty("className");

}

8、获取对应数据库连接的工程类:DBConnectionFactory.java

 

package jdbc;
/**
 *@author WHD
 *data 2016年2月15日
 */
public class DBConnectionFactory {
	  //定义一个接口
    private static IDBConnection instance;
    //同步锁
    private static Object initLock = new Object();
    public static IDBConnection getInstance() {
        if (instance == null) {
            synchronized (initLock) {
                          // 这里的名称就是类配置文件中配置的类型名称即 7 中获取的类名称
                    	String className= (DBConnectionConfig.className);
                        try {
			       instance = (IDBConnection) Class.forName(className).newInstance();
						} catch (InstantiationException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (ClassNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
            }
        }
        return instance;
    }

}

9、调用工厂类的方法获取数据库连接和释放:DBConnection.java

package jdbc;

import java.sql.Connection;

/**
 * @author WHD data 2016年2月15日
 */
public class DBConnection {
	public static Connection getConnection() {
		/**
		 * 用户无需了解底层是如何实现的,它也不需要关心使用的是哪种数据库
		 */
		IDBConnection service = DBConnectionFactory.getInstance();
		Connection conn = service.getConnection();
		return conn;
	}

	public static void closeConnection(Connection conn) {
		IDBConnection service = DBConnectionFactory.getInstance();
		service.closeConnection(conn);
	}
}

ok 到这里整个过程已完成,通过和第一种方法的比较我们发现第二种方式写的代码比第一种方式多,因为只要需要什么数据库他就是要写配置文件,配置文件的读取类以及Connection 链接获取类,类名称配置文件以及类名称配置文件数据获取的类,所以我们发现第二种方式写了很多重复的代码,那就问题来了既然第二种方式写了这么多重复的代码来获取对应数据库的连接而第一种方式只是简单的修改了数据库配置文件那为何还要第二种对问题就在这里,第一种方式写的重复代码少,配置文件少,但是Connection连接类类名称是直接写死在了工厂类中,而第二种这种方式是从配置文件中读取那个类名称,可以说完全解耦,所以第二种方式带来的好处就是低耦合。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值