连接池、装饰设计模式、适配器设计模式、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 list = new LinkedList();

	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 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 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();










你可能感兴趣的:(JAVA,EE)