④ 提供将连接放回连接池中方法
1、连接池代码
public class MyDataSource implements DataSource { //链表 --- 实现栈结构 privateLinkedList<Connection> dataSources = new LinkedList<Connection>(); //初始化连接数量 publicMyDataSource() { //一次性创建10个连接 for(int i = 0; i < 10; i++) { try { //1、装载sqlserver驱动对象 DriverManager.registerDriver(new SQLServerDriver()); //2、通过JDBC建立数据库连接 Connection con =DriverManager.getConnection( "jdbc:sqlserver://192.168.2.6:1433;DatabaseName=customer", "sa", "123"); //3、将连接加入连接池中 dataSources.add(con); } catch (Exception e) { e.printStackTrace(); } } } @Override publicConnection getConnection() throws SQLException { //取出连接池中一个连接 final Connection conn = dataSources.removeFirst(); // 删除第一个连接返回 return conn; } //将连接放回连接池 publicvoid releaseConnection(Connection conn) { dataSources.add(conn);}}2、使用连接池重构我们的用户查询函数
//查询所有用户public void FindAllUsers(){ //1、使用连接池建立数据库连接 MyDataSource dataSource = new MyDataSource(); Connection conn =dataSource.getConnection(); //2、创建状态 Statement state =con.createStatement(); //3、查询数据库并返回结果 ResultSet result =state.executeQuery("select * from users"); //4、输出查询结果 while(result.next()){ System.out.println(result.getString("email")); }//5、断开数据库连接 result.close(); state.close(); //6、归还数据库连接给连接池 dataSource.releaseConnection(conn);}这就是数据库连接池的原理 , 它大大提供了数据库连接的利用率 , 减小了内存吞吐的开销 。我们在开发过程中 , 就不需要再关心数据库连接的问题 , 自然有数据库连接池帮助我们处理 , 这回放心了吧 。但连接池需要考虑的问题不仅仅如此 , 下面我们就看看还有哪些问题需要考虑 。
三、连接池还要考虑更多的问题1、并发问题
为了使连接管理服务具有最大的通用性 , 必须考虑多线程环境 , 即并发问题 。这个问题相对比较好解决 , 因为java语言自身提供了对并发管理的支持 , 使用synchronized关键字即可确保线程是同步的 。使用方法为直接在类方法前面加上synchronized关键字 , 如:
publicsynchronized connection getconnection()2、多数据库服务器和多用户
对于大型的企业级应用 , 常常需要同时连接不同的数据库(如连接oracle和sybase) 。如何连接不同的数据库呢?我们采用的策略是:设计一个符合单例模式的连接池管理类 , 在连接池管理类的唯一实例被创建时读取一个资源文件 , 其中资源文件中存放着多个数据库的url地址等信息 。根据资源文件提供的信息 , 创建多个连接池类的实例 , 每一个实例都是一个特定数据库的连接池 。连接池管理类实例为每个连接池实例取一个名字 , 通过不同的名字来管理不同的连接池 。
对于同一个数据库有多个用户使用不同的名称和密码访问的情况 , 也可以通过资源文件处理 , 即在资源文件中设置多个具有相同url地址 , 但具有不同用户名和密码的数据库连接信息 。
3、事务处理
我们知道 , 事务具有原子性 , 此时要求对数据库的操作符合“all-all-nothing”原则即对于一组sql语句要么全做 , 要么全不做 。
在java语言中 , connection类本身提供了对事务的支持 , 可以通过设置connection的autocommit属性为false 然后显式的调用commit或rollback方法来实现 。但要高效的进行connection复用 , 就必须提供相应的事务支持机制 。可采用每一个事务独占一个连接来实现 , 这种方法可以大大降低事务管理的复杂性 。
4、连接池的分配与释放
连接池的分配与释放 , 对系统的性能有很大的影响 。合理的分配与释放 , 可以提高连接的复用度 , 从而降低建立新连接的开销 , 同时还可以加快用户的访问速度 。
对于连接的管理可使用空闲池 。即把已经创建但尚未分配出去的连接按创建时间存放到一个空闲池中 。每当用户请求一个连接时 , 系统首先检查空闲池内有没有空闲连接 。如果有就把建立时间最长(通过容器的顺序存放实现)的那个连接分配给他(实际是先做连接是否有效的判断 , 如果可用就分配给用户 , 如不可用就把这个连接从空闲池删掉 , 重新检测空闲池是否还有连接);如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxconn)如果没有达到 , 就新建一个连接 , 如果已经达到 , 就等待一定的时间(timeout) 。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户 , 如果等待时间超过预定时间timeout 则返回空值(null) 。系统对已经分配出去正在使用的连接只做计数 , 当使用完后再返还给空闲池 。对于空闲连接的状态 , 可开辟专门的线程定时检测 , 这样会花费一定的系统开销 , 但可以保证较快的响应速度 。也可采取不开辟专门线程 , 只是在分配前检测的方法 。
推荐阅读
- 用电脑控制Android手机,玩游戏看视频都可以,还支持无线连接
- iPhone电池寿命减短的秘密,居然就这?
- 面试很有用哦 SQL常用语句总结
- 拆解|iPad Air 5拆解实测:内部有拉片设计电池更容易更换
- 为什么手机电池上有四个触点?除了正负极外,还有什么?
- 梦见在游泳池里游泳后来水没了啥意思? 梦见在游泳池里游泳水是浑的
- 华为手环能不能连接小米手机 小米手环6可以连接华为手机吗
- 梦见床下面全是水,水里有蛇有水 梦见床下面全是水池
- 比亚迪|刀片电池+DM-i混动卖爆!比亚迪3月销量破10万辆
- 华为手机电池不耐用?过来人:做好这3点,手机再用半年没问题
