欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java数据库连接池,

来源: javaer 分享于  点击 22377 次 点评:188

java数据库连接池,


第一版:手工模仿连接池

jdbc.properties

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/bank
name=root
password=123456

jdbc工具类:

public class JDBCUtil {
	
	static String driverClass = null;
	static String url = null;
	static String name = null;
	static String password= null;
	
	static{
		try {
			//1. 创建一个属性配置对象
			Properties properties = new Properties();
			InputStream is = new FileInputStream("jdbc.properties");
			
			//使用类加载器,去读取src底下的资源文件。 后面在servlet
//			InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
			//导入输入流。
			properties.load(is);
			
			//读取属性
			driverClass = properties.getProperty("driverClass");
			url = properties.getProperty("url");
			name = properties.getProperty("name");
			password = properties.getProperty("password");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取连接对象
	 * @return
	 */
	public static Connection getConn(){
		Connection conn = null;
		try {
			Class.forName(driverClass);
			//静态代码块 ---> 类加载了,就执行。 java.sql.DriverManager.registerDriver(new Driver());
			//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
			//DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
			//2. 建立连接 参数一: 协议 + 访问的数据库 , 参数二: 用户名 , 参数三: 密码。
			conn = DriverManager.getConnection(url, name, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	/**
	 * 释放资源
	 * @param conn
	 * @param st
	 * @param rs
	 */
	public static void release(Connection conn , Statement st , ResultSet rs){
		closeRs(rs);
		closeSt(st);
		closeConn(conn);
	}
	public static void release(Connection conn , Statement st){
		closeSt(st);
		closeConn(conn);
	}

	
	private static void closeRs(ResultSet rs){
		try {
			if(rs != null){
				rs.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			rs = null;
		}
	}
	
	private static void closeSt(Statement st){
		try {
			if(st != null){
				st.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			st = null;
		}
	}
	
	private static void closeConn(Connection conn){
		try {
			if(conn != null){
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			conn = null;
		}
	}
}

自定义数据连接池类:

/**
 * 这是一个数据库连接池
 * 一开始先往池子里面放10个连接
 * 
 * 	1. 开始创建10个连接。
 * 
 * 	2. 来的程序通过getConnection获取连接
 * 
 * 	3. 用完之后,使用addBack 归还连接。
 * 
 * 	4. 扩容。 
 * 
 * 
 * 问题: 
 * 
 * 		1. sun公司针对数据库连接池定义的一套规范。 
 * 	
 * 	1. 需要额外记住 addBack方法
 * 
 * 	2. 单例。
 * 
 * 	3. 无法面向接口编程。 
 * 
 * 		UserDao dao = new UserDaoImpl();
 * 		dao.insert();
 * 
 * 
 * 		DataSource dataSource = new MyDataSource();
 * 
 * 		因为接口里面没有定义addBack方法。 
 * 
 * 	4. 怎么解决?  
 * 	由于多了一个addBack方法,所以使用这个连接池的地方,需要额外记住这个方法,无法面向接口编程。
 * 打算修改这个close方法,以后在调用close,并不是真的关闭。而是归还连接对象。
 */
public class MyDataSource implements DataSource {
	
	List <Connection> list = new ArrayList<Connection>();
	
	public  MyDataSource() {
		for (int i = 0; i < 10; i++) {
			Connection conn = JDBCUtil.getConn();
			list.add(conn);
		}
	}
	
	
//	该连接池对外公布的获取连接的方法
	@Override
	public Connection getConnection() throws SQLException {
		//来拿连接的时候,先看看,池子里面还有没有。
		if(list.size() == 0 ){
			for (int i = 0; i < 5; i++) {
				Connection conn = JDBCUtil.getConn();
				list.add(conn);
			}
		}
		
		//remove(0) ---> 移除第一个。 移除的是集合中的第一个。  移除的是开始的那个元素
		Connection conn = list.remove(0);
		return conn;
	}
	
	/**
	 * 用完之后,记得归还。
	 * @param conn
	 */
	public void addBack(Connection conn){
		list.add(conn);
	}
	
	//----------------------------

	@Override
	public PrintWriter getLogWriter() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setLogWriter(PrintWriter out) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setLoginTimeout(int seconds) throws SQLException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public int getLoginTimeout() throws SQLException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> T unwrap(Class<T> iface) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	

	@Override
	public Connection getConnection(String username, String password) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

}

测试类:

public class TestPool {

	@Test
	public void testPool(){
		Connection conn = null;
		PreparedStatement ps = null;
		MyDataSource dataSource = new MyDataSource();
		try {
			conn =  dataSource.getConnection();
			
			String sql = "insert into account values (null , 'xilali' , 10)";
			ps = conn.prepareStatement(sql);
			ps.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			//归还连接
			//conn.close();
			dataSource.addBack(conn);
			//JDBCUtil.release(conn, st, rs);
		}
	}
}

二:DBCP连接池技术
不使用配置文件:

public class DBCPDemo {

	
	@Test
	public void testDBCP01(){
		
		
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			
			//1. 构建数据源对象
			BasicDataSource dataSource = new BasicDataSource();
			//连的是什么类型的数据库, 访问的是哪个数据库 , 用户名, 密码。。
//			jdbc:mysql://localhost/bank 主协议:子协议 ://本地/数据库
			dataSource.setDriverClassName("com.mysql.jdbc.Driver");
			dataSource.setUrl("jdbc:mysql://localhost/bank");
			dataSource.setUsername("root");
			dataSource.setPassword("123456");
			
			
			//2. 得到连接对象
			conn = dataSource.getConnection();
			String sql = "insert into account values(null , ? , ?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "admin");
			ps.setInt(2, 1000);
			
			ps.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JDBCUtil.release(conn, ps);
		}
		
	}
}

使用配置文件:
配置文件

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bank
username=root
password=123456

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60-->
maxWait=60000


#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
#注意:"user""password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
public class DBCPDemo02 {

	@Test
	public void testDBCP02(){
		/*BasicDataSource dataSource = new BasicDataSource();
		//不知道这行能不能实现。
		dataSource.setConnectionProperties("dbcpconfig.properties");*/
		
		//ResourceBundle bundler = ResourceBundle.getBundle(baseName);
		
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			BasicDataSourceFactory factory = new BasicDataSourceFactory();
			Properties properties = new Properties();
			
//			InputStream is = new FileInputStream("src//dbcpconfig.properties");
			InputStream is = getClass().getClassLoader().getResourceAsStream("dbcpconfig.properties");
			properties.load(is);
			DataSource dataSource = factory.createDataSource(properties);
			
			//2. 得到连接对象
			conn = dataSource.getConnection();
			String sql = "insert into account values(null , ? , ?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "liangchaowei22");
			ps.setInt(2, 200);
			
			ps.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBCUtil.release(conn, ps);
		}
		
	}
}

第三版:C3P0连接池
不带配置文件版:

public class C3P0Demo {

	@Test
	public void testC3P0 (){
		
		
		
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			//1. 创建datasource
//			ComboPooledDataSource dataSource = new ComboPooledDataSource("oracle");
			
			//默认会找 xml 中的 default-config 分支。 
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			System.out.println(dataSource.hashCode() );
			ComboPooledDataSource dataSource2 = new ComboPooledDataSource();
			System.out.println(dataSource2.hashCode()+"-------");
			//2. 设置连接数据的信息
			dataSource.setDriverClass("com.mysql.jdbc.Driver");
			
			//忘记了---> 去以前的代码 ---> jdbc的文档
			dataSource.setJdbcUrl("jdbc:mysql://localhost/bank");
			dataSource.setUser("root");
			dataSource.setPassword("root");
			
			//2. 得到连接对象
			conn = dataSource.getConnection();
			String sql = "insert into account values(null , ? , ?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "admi234n");
			ps.setInt(2, 103200);
			
			ps.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBCUtil.release(conn, ps);
		}
	}
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

	<!-- default-config 默认的配置,  -->
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost/bank</property>
    <property name="user">root</property>
    <property name="password">root</property>
    
    
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
    <property name="maxStatements">200</property>
  </default-config>
  
   <!-- This app is massive! -->
  <named-config name="oracle"> 
    <property name="acquireIncrement">50</property>
    <property name="initialPoolSize">100</property>
    <property name="minPoolSize">50</property>
    <property name="maxPoolSize">1000</property>

    <!-- intergalactoApp adopts a different approach to configuring statement caching -->
    <property name="maxStatements">0</property> 
    <property name="maxStatementsPerConnection">5</property>

    <!-- he's important, but there's only one of him -->
    <user-overrides user="master-of-the-universe"> 
      <property name="acquireIncrement">1</property>
      <property name="initialPoolSize">1</property>
      <property name="minPoolSize">1</property>
      <property name="maxPoolSize">5</property>
      <property name="maxStatementsPerConnection">50</property>
    </user-overrides>
  </named-config>

 
</c3p0-config>
	
public class C3P0Demo02 {

	@Test
	public void testC3P0(){
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			
			//就new了一个对象。
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			
			//2. 得到连接对象
			conn = dataSource.getConnection();
			String sql = "insert into account values(null , ? , ?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "wangwu2");
			ps.setInt(2, 2600);
			
			ps.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBCUtil.release(conn, ps);
		}
	}
}

相关文章

    暂无相关文章
相关栏目:

用户点评