連接池、裝飾設計模式、適配器設計模式、JNDI容器、DBCP、C3P0、Tomcat數據源

概述:

當應用訪問量比較大時,每次請求都需要從數據庫中獲取鏈接,這樣極其消耗資源,創建的時間也比較長。例如一個網站的訪問量每天10W,就得創建10W次連接。

這時就可以用連接池。


連接池需要實現javax.sql.DataSource接口,實現她的兩個方法:

getConnection();

getConnection(String user,String password);


1. 實現DataSource接口

2. 定義一個List類型的成員變量,用來存放Connection。因爲存取的操作頻繁,所以這裏用LinkedList集合。

3. 定義一個成員變量:初始連接數。

4. 在靜態代碼塊中,循環生成 多個連接。

5. 實現getConnection方法,作一個判斷:list>0代表裏面還有連接,否則拋異常“連接不夠”。

6. 在作連接池中,最麻煩的一步就是close關閉。因爲我們並不是要把連接關閉,而是把連接又放回list中。

(當要對一個對象的功能進行增強時,有三種方法:1.寫一個子類繼承被增強的類。2. 用包裝設計模式。3.用動態代理的方式)


private static LinkedList<Connection> list = new LinkedList<Connection>();

	static {
		ResourceBundle rb = ResourceBundle.getBundle("db");
		String url = rb.getString("url");
		String drive = rb.getString("drive");
		String username = rb.getString("username");
		String password = rb.getString("password");

		try {
			Class.forName(drive);

			for (int x = 0; x < 10; x++) {
				Connection conn = DriverManager.getConnection(url, username,
						password);

				list.add(conn);
			}

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static LinkedList<Connection> getList() {
		return list;
	}

	@Override
	public Connection getConnection() throws SQLException {

		if (list.size() > 0) {

			final Connection conn = list.removeFirst();
			
			//用裝飾設計模式實現:重寫他的close方法。其它的方法都調用其自身的方法。			
			// MyConnection myconn = new MyConnection(conn, list);
			// return myconn;
			
			//用動態代理的方式實現
			return (Connection) Proxy.newProxyInstance(conn.getClass()
					.getClassLoader(), conn.getClass().getInterfaces(),
					new InvocationHandler() {

						@Override
						public Object invoke(Object proxy, Method method,
								Object[] args) throws Throwable {

							String methodName = method.getName();

							if (!methodName.equals("close")) {
								return method.invoke(conn, args);
							} else {
								list.add(conn);
								return null;
							}
						}
					});

		} else {
			throw new RuntimeException("對不起!服務器正忙");
		}


裝飾設計模式:

1. 寫一個類實現與被增強類的接口。

2. 在類中定義一個變量,記住被增強的對象。

3. 定義一個構造方法,接收被增強對象。

4. 覆蓋被增強的方法。

5. 對不想被增強的方法,可以直接調用被增強的對象(目標對象)的方法。


適配器設計模式:

理解:當我們自己的多個類或別人寫的類實現一個接口時,而這個接口中定義了N個方法。我們不需要每個實現他的類都去覆蓋他的方法。只需要做一個類去實現他的所有方法。而其它類繼承這個類,覆蓋所需的方法即可。而這個類就是適配器類。這種方法叫適配器設計模式。



開源連接池:DBCP

1. 導入commons-dbcp-*.jar  commons-pool.jar包

2. 修改配置文件


代碼如下:

public class JdbcUtils {

	private static DataSource ds;

	static {

		try {
			
			InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcp.properties");
			Properties props = new Properties();
			props.load(in);
			ds = BasicDataSourceFactory.createDataSource(props);
			
		} catch (Exception e) {
			throw new ExceptionInInitializerError("初始化異常");
		}

	}

	public static Connection getConnection() {

		try {
			return ds.getConnection();
		} catch (SQLException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
}


開源連接池:P3C0

1. 導入c3p0-0.9.1.2.jar,c3p0-0.9.1.2-jdk1.3.jar,c3p0-oracle-thin-extras-0.9.1.2.jar(可選,如果是oracle)

2. 複製配置文件至classPath環境下,或者classes目錄下。


代碼:

public class JdbcUtils {

	private static ComboPooledDataSource cpds;

	static {

		try {

			cpds = new ComboPooledDataSource("mysql");

		} catch (Exception e) {
			throw new ExceptionInInitializerError("初始化異常");
		}

	}

	public static Connection getConnection() {

		try {
			return cpds.getConnection();
		} catch (SQLException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
}


JNDI容器:J2EE開發13種技術之一。用於存放資源,例如:當多個程序之間的數據傳遞時,可以先把數據寫到JNDI容器中,然後哪個程序需要就去JNDI容器裏取出。


Tomcat數據源配置

在Tomcat啓動時建立,將配置信息寫到context.xml文件中,放在META-INF目錄下。

<Context>
  <Resource name="jdbc/EmployeeDB"
            auth="Container"
            type="javax.sql.DataSource"
            username="dbusername"
            password="dbpassword"
            driverClassName="org.hsql.jdbcDriver"
            url="jdbc:HypersonicSQL:database"
            maxActive="8"
            maxIdle="4"/>
</Context
代碼:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
  envCtx.lookup("jdbc/EmployeeDB");

Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();










發佈了67 篇原創文章 · 獲贊 8 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章