013 数据库连接池和DBUtils

===============================

数据库连接池

连接池的原理如上,可以写一个简单的代码来说明,这部分代码不完整,随便看看就好

public class MyDataSource implements DataSource
{
	private List<Connection>list1=new ArrayList<Connection>();
	public MyDataSource()
	{
		//一开始就获取10个连接
		for(int i=0;i<10;i++)
		{
			Connection conn1=JDBCUtil.getConnection();
			list1.add(conn1);
		}
		
	}
	
	@Override
	public Connection getConnection() throws SQLException
	{
		//如果连接池满了,自动扩容
				if (list1.size()==0)
				{
					for(int i=0;i<5;i++)
					{
						Connection conn1=JDBCUtil.getConnection();
						list1.add(conn1);
					}
				}
				
				//拿走一个对象
				//remove会把第一个删除并且返回,且后面所有元素会向前移
				Connection coon1=list1.remove(0);
				
				//利用装饰者模式对原本的对象进行包装,我们传出去的是我们自己的对象
				//我们的对象只实现了3个方法,getConnection,close,prepareStatement(伪实现)
				//所以这个包装出去的对象,调用不了除这3个之外的其他方法
				Connection connection1=new MyConnection(coon1, list1);
				
				return connection1;
	}
	
	public Connection getConnection(String username, String password) throws SQLException
	{
		return null;
	}
	
	//归返对象
	public void addBack(Connection con)
	{
		list1.add(con);
	}
	
	
	
	@Override
	public PrintWriter getLogWriter() throws SQLException
	{
		// TODO 自动生成的方法存根
		return null;
	}

	@Override
	public void setLogWriter(PrintWriter out) throws SQLException
	{
		
	}

	@Override
	public void setLoginTimeout(int seconds) throws SQLException
	{
		// TODO 自动生成的方法存根
		
	}

	@Override
	public int getLoginTimeout() throws SQLException
	{
		// TODO 自动生成的方法存根
		return 0;
	}

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException
	{
		// TODO 自动生成的方法存根
		return null;
	}

	@Override
	public <T> T unwrap(Class<T> iface) throws SQLException
	{
		// TODO 自动生成的方法存根
		return null;
	}

	@Override
	public boolean isWrapperFor(Class<?> iface) throws SQLException
	{
		// TODO 自动生成的方法存根
		return false;
	}


}

DBCP连接池

由Apache开发,tomcat就是他们开发的,导入dbcp的jar包,dbcp的jar有2个,还有一个是pool.jar

public class DBCPDemo
{
	public static void main(String[] args)
	{
		test2();
	}
	
	//使用配置文件的方法获取参数连接数据库
	public static void test2()
	{
		Connection conn1=null;
		PreparedStatement ps1=null;
		
		try
		{			
			//加载配置文件,配置文件放到src下面,这样发布到tomcat后就是在classes文件夹里
			Properties properties1=new Properties();
			InputStream iStream1=DBCPDemo.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
			
			//加载配置文件
			properties1.load(iStream1);
			
			//通过配置文件获取连接池对象
			//createDataSource是一个静态的对象,在BasicDataSourceFactory(资源工厂)里
			DataSource dataSource1=BasicDataSourceFactory.createDataSource(properties1);
			
			//获取连接对象
			conn1=dataSource1.getConnection();
			
			//执行语句
			String sql="insert into bank values(null,?,?)"; 
		    ps1=conn1.prepareStatement(sql);
			ps1.setString(1, "test");
			ps1.setInt(2, 10000);
			ps1.executeUpdate();
			
			
		} catch (Exception e)
		{
			e.printStackTrace();
		}finally {
			
			//释放资源
			JDBCUtil.release(null, ps1, conn1);
		}
	}
	
	//使用普通set方法设置连接数据库的参数
	public static void test1()
	{
		//创建连接池对象
		BasicDataSource dataSource1=new BasicDataSource();
		Connection conn1=null;
		PreparedStatement ps1=null;
		try
		{
			
			//设置连接数据库的参数
			dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
			dataSource1.setUrl("jdbc:mysql://localhost/test");
			dataSource1.setUsername("root");
			dataSource1.setPassword("123");
			
			//获取连接对象
			conn1=dataSource1.getConnection();
			
			//执行语句
			String sql="insert into bank values(null,?,?)"; 
		    ps1=conn1.prepareStatement(sql);
			ps1.setString(1, "test");
			ps1.setInt(2, 10000);
			ps1.executeUpdate();
			
		} catch (SQLException e)
		{
			e.printStackTrace();
		}finally {
			
			//释放资源
			JDBCUtil.release(null, ps1, conn1);
		}
	}
}

c3p0连接池(一般都用这个)

c3p0配置文件,这个直接从c3p0的文档复制过来的,名字要固定,就叫c3p0-config.xml  且放到src目录下

c3p0可以方便的切换数据库

<?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/test</property>
    <property name="user">root</property>
    <property name="password">123</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>
  
   <!-- 下面这是配置另外一个数据库的-->
  <named-config name="oracle"> 
     <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost/test</property>
    <property name="user">root</property>
    <property name="password">123</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>
  </named-config>
 
</c3p0-config>

c3p0的使用

public class C3P0Demo
{
	public static void main(String[] args)
	{
		test2();
	}

	//使用xml配置文件的方法获取参数连接数据库
	public static void test2()
	{
		Connection conn1=null;
		PreparedStatement ps1=null;
		try
		{
			//创建连接池对象并且自动加载配置文件,可以指定数据库,不指定就是用默认的
//			ComboPooledDataSource dataSource1=new ComboPooledDataSource("oracle");
			ComboPooledDataSource dataSource1=new ComboPooledDataSource();
			//获取连接对象
			conn1=dataSource1.getConnection();
			
			//执行语句
			String sql="insert into bank values(null,?,?)"; 
		    ps1=conn1.prepareStatement(sql);
			ps1.setString(1, "test");
			ps1.setInt(2, 10000);
			ps1.executeUpdate();
			
		} catch (Exception e)
		{
			e.printStackTrace();
		}finally {
			
			//释放资源
			JDBCUtil.release(null, ps1, conn1);
		}
		
	}
	
	
	//使用普通set方法设置连接数据库的参数
	public static void test1()
	{
		Connection conn1=null;
		PreparedStatement ps1=null;
		try
		{
			//创建连接池对象
			ComboPooledDataSource dataSource1=new ComboPooledDataSource();
			
			//设置连接数据库的参数
			dataSource1.setDriverClass("com.mysql.jdbc.Driver");
			dataSource1.setJdbcUrl("jdbc:mysql://localhost/test");
			dataSource1.setUser("root");
			dataSource1.setPassword("123");
			
			//获取连接对象
			conn1=dataSource1.getConnection();
			
			//执行语句
			String sql="insert into bank values(null,?,?)"; 
		    ps1=conn1.prepareStatement(sql);
			ps1.setString(1, "test");
			ps1.setInt(2, 10000);
			ps1.executeUpdate();
			
		} catch (Exception e)
		{
			e.printStackTrace();
		}finally {
			
			//释放资源
			JDBCUtil.release(null, ps1, conn1);
		}
	}
}

DBUtils 

可以更加方便的操作sql语句,连接数据库的部分还需要我们自己来

我们甚至可以改造之前的JDBCUtils

public class JDBCUtil
{
	static ComboPooledDataSource dataSource1 = null;

	static
	{
		// 因为我们是使用配置文件xml的,所以直接创建里面会自动加载xml
		dataSource1 = new ComboPooledDataSource();
	}

	public static DataSource getDataSource()
	{
		return dataSource1;
	}

	public static Connection getConnection()
	{
		try
		{
			// 直接返回Connection
			return dataSource1.getConnection();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}

	public static void release(ResultSet rs, Statement state1, Connection conn1)
	{
		closeRs(rs);
		closeState(state1);
		closeConn(conn1);
	}

	private static void closeRs(ResultSet rs)
	{
		try
		{
			// 需要先判断是不是等于空,如果等于空,去释放就触发异常了
			// 最后的时候还需要把rs置空
			if (rs != null)
			{
				rs.close();
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			rs = null;
		}
	}

	private static void closeState(Statement state1)
	{
		try
		{
			if (state1 != null)
			{
				state1.close();
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			state1 = null;
		}
	}

	private static void closeConn(Connection conn1)
	{
		try
		{
			if (conn1 != null)
			{
				conn1.close();
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			conn1 = null;
		}
	}
}

使用DBUtils

public class DBUtilsDemo
{
	 public static void main(String[] args) 
	{
		 testSelect2();
	}
	 
	 //测试查询,用的反射机制,常用
	 public static void testSelect2()
	 {
		 try
			{
				// 创建连接池对象并且自动加载配置文件,这里我们使用的是C3P0
				ComboPooledDataSource dataSource1 = new ComboPooledDataSource();

				//创建查询对象,我们传入dataSource,里面应该会自动调用getConnection
				QueryRunner queryRunner1 = new QueryRunner(dataSource1);
				
				String sql = "select * from bank where id=?";
				
				//第2个参数传入类的描述符,然后函数内部会自动去调用get,set方法,如果我们去掉了get set方法就获取不到数值
				Account account1=queryRunner1.query(sql, new BeanHandler<Account>(Account.class),1);
				
				account1.toString();
				
				System.out.println("==========下面是查询多个===================");
				
				sql = "select * from bank";
				List<Account> list1= queryRunner1.query(sql, new BeanListHandler<Account>(Account.class));
				for (Account account : list1)
				{
					account.toString();
				}
				
				
			} catch (Exception e)
			{
				e.printStackTrace();
			}
		 
	 }
	 
	 //测试查询,用匿名内部类
	 public static void testSelect() 
	{
		try
		{
			// 创建连接池对象并且自动加载配置文件,这里我们使用的是C3P0
			ComboPooledDataSource dataSource1 = new ComboPooledDataSource();

			// DBUtils只是帮我们简化CRUB代码,还是需要传递连接对象的
			// 里面应该会自动调用getConnection
			QueryRunner queryRunner1 = new QueryRunner(dataSource1);

			String sql = "select * from bank where id=?";
			
			//采用匿名内部类
			 queryRunner1.query(sql, new ResultSetHandler<Account>()
			{
				 //ResultSetHandler接口的方法,需要我们实现
				public Account handle(ResultSet rs) throws SQLException
				{
					Account account2 = new Account();
					
					//用while可以实现多条查询
					while (rs.next())
					{
						int id = rs.getInt("id");
						String name = rs.getString("name");
						int money = rs.getInt("money");

						account2.setId(id);
						account2.setName(name);
						account2.setMoney(money);
						
						//输出结果
						System.out.println(account2.toString());
					}

					return account2;
				}

			}, 1);
			
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	 	
	}
	 
	 //测试增加,删除,更新
	 public static void testUpdate()
	{
		try
		{
			//创建连接池对象并且自动加载配置文件,这里我们使用的是C3P0
			ComboPooledDataSource dataSource1=new ComboPooledDataSource();
			
			//DBUtils只是帮我们简化CRUB代码,还是需要传递连接对象的
			//里面应该会自动调用getConnection
			QueryRunner queryRunner1=new QueryRunner(dataSource1);
			
			//update可以实现增加,删除,更新
			String sql="insert into bank values(null,'test1',123)";
			
			queryRunner1.update(sql);
		} catch (Exception e)
		{
			e.printStackTrace();
		}finally {
			
		}
		
	}

}
				//如果使用了聚合函数,那么就用ScalarHandler
			 String sql="select count(*) from stu where sname=?";
			 Long num=(Long)runner.query(sql,new ScalarHandler(),name);

猜你喜欢

转载自blog.csdn.net/yzj17025693/article/details/82840539
013