├── .coveralls.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── cgit.bat ├── doc ├── CI集成.md ├── 发布流程.md └── 项目原型.md ├── pom.xml ├── release.bat ├── release.sh ├── release_rm.sh └── src ├── main └── java │ └── com │ └── github │ └── houbb │ └── thread │ └── pool │ ├── api │ ├── IConfig.java │ ├── IDataSourceConfig.java │ ├── ILifeCycle.java │ └── IPooledDataSourceConfig.java │ ├── bs │ └── JdbcPoolBs.java │ ├── connection │ ├── IPooledConnection.java │ └── PooledConnection.java │ ├── constant │ ├── DriverNameConst.java │ └── PooledConst.java │ ├── datasource │ ├── AbstractDataSourceConfig.java │ ├── AbstractPooledDataSourceConfig.java │ ├── DataSourceConfigAdaptor.java │ ├── PooledDataSource.java │ └── UnPooledDataSource.java │ ├── exception │ └── JdbcPoolException.java │ ├── model │ └── DataSourceConfigDto.java │ ├── package-info.java │ └── util │ └── DriverClassUtil.java └── test ├── java └── com │ └── github │ └── houbb │ └── thread │ └── pool │ └── datasource │ ├── GenTest.java │ ├── JdbcPoolbsTest.java │ ├── PooledDataSourceTest.java │ └── UnPooledDataSourceTest.java └── resources └── driverClass.txt /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # maven ignore 2 | 3 | *.jar 4 | *.war 5 | *.zip 6 | *.tar 7 | *.tar.gz 8 | target 9 | 10 | # eclipse ignore 11 | .settings/ 12 | .project 13 | .classpath 14 | 15 | # idea ignore 16 | .idea/ 17 | *.ipr 18 | *.iml 19 | *.iws 20 | 21 | # temp ignore 22 | *.log 23 | *.cache 24 | *.diff 25 | *.patch 26 | *.tmp 27 | *.java~ 28 | *.properties~ 29 | *.xml~ 30 | 31 | # system ignore 32 | .DS_Store 33 | Thumbs.db -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk8 4 | install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true 5 | script: mvn test 6 | after_success: 7 | - mvn clean cobertura:cobertura coveralls:report 8 | env: 9 | global: 10 | secure: B8JfWrbedReBipr6GBSr0/r7c5pp7E9xjcFliVhpHtbOQ5zs7O8K19pLW8ag+/ENR54FZbHlTSsXW/SNcl9XYyV+uargcveurmcnrlRFnQ376X85KIc6hBddaeJBkqlSlyUn4DoGnmM3o+bNKrHqnXvLIczCDLeH3s89MZxxIAoAUZfjoV5Fekz9dXkReeHCJo+PjuH+2JrX6p+NiKjNe2os8pdjo4+FbDl3Gds/oqfRJt+z6DVYlxv7wzLgiTgtT9162CVhEj9v1b29tSWDNqwBL1IdzgP8Jdq1ujy2qMeZRJOWGVXCwG9WYk+vcKmTirY2KnNdQeCH7fjCYEQfxlbOtKnQcFJym9Ph8ZzKSirzthGz54vV0LFxnMspGGCvCODZaShNfvzYAaKQod2Lw1j3P5at+NGTNACoEzHxsZZlJx5U2BlMFQvkg3S4eYE+zw/B1HjkCXEXIOE5uldRRL9Poc3WqqSMx5Kgxri7WkszyJMkTv2VhMmoFbXf2yOVgXCy6drv0YHm1u0WWBITsuCMQR7ByHau71EHB8cM/OOTXrHKiIgtUaYD99MefRUpgO233AdsvPLE4E0r0vXlSay6JpchMXwV2jfRbE5C+YWJPUdjZx4DhrjzktB+Ytlso+urn/I4Pu8GH4PgQVLTJESNZe1+5fgB3Ullxhx7+9k= 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 变更日志 2 | 3 | | 类型 | 说明 | 4 | |:----|:----| 5 | | A | 新增 | 6 | | U | 更新 | 7 | | D | 删除 | 8 | | T | 测试 | 9 | | O | 优化 | 10 | | F | 修复BUG | 11 | 12 | # release_1.0.0 13 | 14 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 15 | |:---|:---|:---|:---|:--| 16 | | 1 | A | 基本功能的实现 | 2020-6-30 21:12:45 | | 17 | 18 | # release_1.1.0 19 | 20 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 21 | |:---|:---|:---|:---|:--| 22 | | 1 | A | 简单的池化实现 | 2020-7-17 21:58:40 | | 23 | 24 | # release_1.2.0 25 | 26 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 27 | |:---|:---|:---|:---|:--| 28 | | 1 | A | 添加自动识别驱动类 | 2020-7-18 09:47:02 | | 29 | 30 | # release_1.3.0 31 | 32 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 33 | |:---|:---|:---|:---|:--| 34 | | 1 | A | 添加连接获取的等待时间 | 2020-7-18 10:28:12 | | 35 | 36 | # release_1.4.0 37 | 38 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 39 | |:---|:---|:---|:---|:--| 40 | | 1 | A | 添加日志整合 | 2020-7-18 10:52:03 | | 41 | | 2 | A | 添加连接状态校验 | 2020-7-18 10:52:03 | | 42 | 43 | # release_1.5.0 44 | 45 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 46 | |:---|:---|:---|:---|:--| 47 | | 1 | A | 添加连接有效性的校验 | 2020-7-18 17:00:03 | | 48 | 49 | # release_1.6.0 50 | 51 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 52 | |:---|:---|:-------------------|:--------------------|:--| 53 | | 1 | A | 添加 datasource 引导类 | 2022-10-10 17:00:03 | | 54 | 55 | # release_1.7.0 56 | 57 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 58 | |:---|:-----|:-----------------------------|:--------------------|:--| 59 | | 1 | A | 添加 DataSourceConfigDto 配置对象类 | 2023-10-22 17:00:03 | | 60 | | 2 | O | 调整配置默认到 8.0 | 2023-10-22 17:00:03 | | 61 | 62 | # release_1.7.1 63 | 64 | | 序号 | 变更类型 | 说明 | 时间 | 备注 | 65 | |:---|:-----|:-----|:---------------------|:--| 66 | | 1 | O | 日志优化 | 20234-03-20 17:00:03 | | 67 | | 2 | O | 依赖优化 | 2024-03-20 17:00:03 | | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | #set( $symbol_pound = '#' ) 2 | #set( $symbol_dollar = '$' ) 3 | #set( $symbol_escape = '\' ) 4 | 5 | Apache License 6 | Version 2.0, January 2004 7 | http://www.apache.org/licenses/ 8 | 9 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 10 | 11 | 1. Definitions. 12 | 13 | "License" shall mean the terms and conditions for use, reproduction, 14 | and distribution as defined by Sections 1 through 9 of this document. 15 | 16 | "Licensor" shall mean the copyright owner or entity authorized by 17 | the copyright owner that is granting the License. 18 | 19 | "Legal Entity" shall mean the union of the acting entity and all 20 | other entities that control, are controlled by, or are under common 21 | control with that entity. For the purposes of this definition, 22 | "control" means (i) the power, direct or indirect, to cause the 23 | direction or management of such entity, whether by contract or 24 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 25 | outstanding shares, or (iii) beneficial ownership of such entity. 26 | 27 | "You" (or "Your") shall mean an individual or Legal Entity 28 | exercising permissions granted by this License. 29 | 30 | "Source" form shall mean the preferred form for making modifications, 31 | including but not limited to software source code, documentation 32 | source, and configuration files. 33 | 34 | "Object" form shall mean any form resulting from mechanical 35 | transformation or translation of a Source form, including but 36 | not limited to compiled object code, generated documentation, 37 | and conversions to other media types. 38 | 39 | "Work" shall mean the work of authorship, whether in Source or 40 | Object form, made available under the License, as indicated by a 41 | copyright notice that is included in or attached to the work 42 | (an example is provided in the Appendix below). 43 | 44 | "Derivative Works" shall mean any work, whether in Source or Object 45 | form, that is based on (or derived from) the Work and for which the 46 | editorial revisions, annotations, elaborations, or other modifications 47 | represent, as a whole, an original work of authorship. For the purposes 48 | of this License, Derivative Works shall not include works that remain 49 | separable from, or merely link (or bind by name) to the interfaces of, 50 | the Work and Derivative Works thereof. 51 | 52 | "Contribution" shall mean any work of authorship, including 53 | the original version of the Work and any modifications or additions 54 | to that Work or Derivative Works thereof, that is intentionally 55 | submitted to Licensor for inclusion in the Work by the copyright owner 56 | or by an individual or Legal Entity authorized to submit on behalf of 57 | the copyright owner. For the purposes of this definition, "submitted" 58 | means any form of electronic, verbal, or written communication sent 59 | to the Licensor or its representatives, including but not limited to 60 | communication on electronic mailing lists, source code control systems, 61 | and issue tracking systems that are managed by, or on behalf of, the 62 | Licensor for the purpose of discussing and improving the Work, but 63 | excluding communication that is conspicuously marked or otherwise 64 | designated in writing by the copyright owner as "Not a Contribution." 65 | 66 | "Contributor" shall mean Licensor and any individual or Legal Entity 67 | on behalf of whom a Contribution has been received by Licensor and 68 | subsequently incorporated within the Work. 69 | 70 | 2. Grant of Copyright License. Subject to the terms and conditions of 71 | this License, each Contributor hereby grants to You a perpetual, 72 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 73 | copyright license to reproduce, prepare Derivative Works of, 74 | publicly display, publicly perform, sublicense, and distribute the 75 | Work and such Derivative Works in Source or Object form. 76 | 77 | 3. Grant of Patent License. Subject to the terms and conditions of 78 | this License, each Contributor hereby grants to You a perpetual, 79 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 80 | (except as stated in this section) patent license to make, have made, 81 | use, offer to sell, sell, import, and otherwise transfer the Work, 82 | where such license applies only to those patent claims licensable 83 | by such Contributor that are necessarily infringed by their 84 | Contribution(s) alone or by combination of their Contribution(s) 85 | with the Work to which such Contribution(s) was submitted. If You 86 | institute patent litigation against any entity (including a 87 | cross-claim or counterclaim in a lawsuit) alleging that the Work 88 | or a Contribution incorporated within the Work constitutes direct 89 | or contributory patent infringement, then any patent licenses 90 | granted to You under this License for that Work shall terminate 91 | as of the date such litigation is filed. 92 | 93 | 4. Redistribution. You may reproduce and distribute copies of the 94 | Work or Derivative Works thereof in any medium, with or without 95 | modifications, and in Source or Object form, provided that You 96 | meet the following conditions: 97 | 98 | (a) You must give any other recipients of the Work or 99 | Derivative Works a copy of this License; and 100 | 101 | (b) You must cause any modified files to carry prominent notices 102 | stating that You changed the files; and 103 | 104 | (c) You must retain, in the Source form of any Derivative Works 105 | that You distribute, all copyright, patent, trademark, and 106 | attribution notices from the Source form of the Work, 107 | excluding those notices that do not pertain to any part of 108 | the Derivative Works; and 109 | 110 | (d) If the Work includes a "NOTICE" text file as part of its 111 | distribution, then any Derivative Works that You distribute must 112 | include a readable copy of the attribution notices contained 113 | within such NOTICE file, excluding those notices that do not 114 | pertain to any part of the Derivative Works, in at least one 115 | of the following places: within a NOTICE text file distributed 116 | as part of the Derivative Works; within the Source form or 117 | documentation, if provided along with the Derivative Works; or, 118 | within a display generated by the Derivative Works, if and 119 | wherever such third-party notices normally appear. The contents 120 | of the NOTICE file are for informational purposes only and 121 | do not modify the License. You may add Your own attribution 122 | notices within Derivative Works that You distribute, alongside 123 | or as an addendum to the NOTICE text from the Work, provided 124 | that such additional attribution notices cannot be construed 125 | as modifying the License. 126 | 127 | You may add Your own copyright statement to Your modifications and 128 | may provide additional or different license terms and conditions 129 | for use, reproduction, or distribution of Your modifications, or 130 | for any such Derivative Works as a whole, provided Your use, 131 | reproduction, and distribution of the Work otherwise complies with 132 | the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, 135 | any Contribution intentionally submitted for inclusion in the Work 136 | by You to the Licensor shall be under the terms and conditions of 137 | this License, without any additional terms or conditions. 138 | Notwithstanding the above, nothing herein shall supersede or modify 139 | the terms of any separate license agreement you may have executed 140 | with Licensor regarding such Contributions. 141 | 142 | 6. Trademarks. This License does not grant permission to use the trade 143 | names, trademarks, service marks, or product names of the Licensor, 144 | except as required for reasonable and customary use in describing the 145 | origin of the Work and reproducing the content of the NOTICE file. 146 | 147 | 7. Disclaimer of Warranty. Unless required by applicable law or 148 | agreed to in writing, Licensor provides the Work (and each 149 | Contributor provides its Contributions) on an "AS IS" BASIS, 150 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 151 | implied, including, without limitation, any warranties or conditions 152 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 153 | PARTICULAR PURPOSE. You are solely responsible for determining the 154 | appropriateness of using or redistributing the Work and assume any 155 | risks associated with Your exercise of permissions under this License. 156 | 157 | 8. Limitation of Liability. In no event and under no legal theory, 158 | whether in tort (including negligence), contract, or otherwise, 159 | unless required by applicable law (such as deliberate and grossly 160 | negligent acts) or agreed to in writing, shall any Contributor be 161 | liable to You for damages, including any direct, indirect, special, 162 | incidental, or consequential damages of any character arising as a 163 | result of this License or out of the use or inability to use the 164 | Work (including but not limited to damages for loss of goodwill, 165 | work stoppage, computer failure or malfunction, or any and all 166 | other commercial damages or losses), even if such Contributor 167 | has been advised of the possibility of such damages. 168 | 169 | 9. Accepting Warranty or Additional Liability. While redistributing 170 | the Work or Derivative Works thereof, You may choose to offer, 171 | and charge a fee for, acceptance of support, warranty, indemnity, 172 | or other liability obligations and/or rights consistent with this 173 | License. However, in accepting such obligations, You may act only 174 | on Your own behalf and on Your sole responsibility, not on behalf 175 | of any other Contributor, and only if You agree to indemnify, 176 | defend, and hold each Contributor harmless for any liability 177 | incurred by, or claims asserted against, such Contributor by reason 178 | of your accepting any such warranty or additional liability. 179 | 180 | END OF TERMS AND CONDITIONS 181 | 182 | APPENDIX: How to apply the Apache License to your work. 183 | 184 | To apply the Apache License to your work, attach the following 185 | boilerplate notice, with the fields enclosed by brackets "[]" 186 | replaced with your own identifying information. (Don't include 187 | the brackets!) The text should be enclosed in the appropriate 188 | comment syntax for the file format. We also recommend that a 189 | file or class name and description of purpose be included on the 190 | same "printed page" as the copyright notice for easier 191 | identification within third-party archives. 192 | 193 | Copyright 2016 ShenHuaJie iBase4J@163.com 194 | 195 | Licensed under the Apache License, Version 2.0 (the "License"); 196 | you may not use this file except in compliance with the License. 197 | You may obtain a copy of the License at 198 | 199 | http://www.apache.org/licenses/LICENSE-2.0 200 | 201 | Unless required by applicable law or agreed to in writing, software 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 204 | See the License for the specific language governing permissions and 205 | limitations under the License. 206 | 207 | ====================================================================== 208 | 209 | Apache许可证 210 | 版本 2.0,2004年1月 211 | http://www.apache.org/licenses/ 212 | 213 | 使用、重生成及分发的术语和条件: 214 | 215 | 1.定义 216 | 217 | "许可证"是指根据本文档第1到第9部分关于使用、重生成和分发的术语和条件。 218 | 219 | "许可证颁发者"是指版权所有者或者由版权所有者批准的授权许可证的实体。 220 | 221 | "法律实体"是指实施实体和进行控制的所有其它实体受该实体控制,或者受该实体集中控制。 222 | 根据此定义,"控制"是指(i)让无论是否签订协议的上述实体,进行指导或管理的直接权利或间接权利, 223 | 或者(ii)拥有百分之五十(50%)或以上已发行股票的所有者,或者(iii)上述实体的实权所有者。 224 | 225 | "用户"(或"用户的")是指行使本许可证所授予权限的个人或法律实体。 226 | 227 | "源程序"形式是指对包含但不限制软件源代码、文档源程序和配置文件进行修改的首选形式。 228 | 229 | "目标"形式是指对源程序形式进行机械转换或翻译的任何形式,包括但不限于对编译的目标代码, 230 | 生成的文件以及转换为其它媒体类型。 231 | 232 | "作品"是指根据本许可证所制作的源程序形式或目标形式的著作,在著作中包含的或附加的版权通知 233 | (在下面附录中提供了一个示例)。 234 | 235 | "衍生作品"是指基于作品(或从作品衍生而来)的源程序形式或目标形式的任何作品,以及编辑修订、 236 | 注释、详细描述或其它修订等构成原创著作作品的整体。根据本许可证,衍生作品不得包括与作品及其 237 | 衍生作品分离之作品,或仅与作品及其衍生作品的接口相链接(或按名称结合)之作品。 238 | 239 | "贡献"是指任何著作作品,包括作品的原始版本和对该作品或衍生作品所做的任何修订或补充, 240 | 意在提交给许可证颁发者以让版权所有者或代表版权所有者的授权个人或法律实体包含在其作品中。 241 | 根据此定义,"提交"一词表示发送给许可证颁发者或其代表人,任何电子的、口头的或书面的交流信息形式, 242 | 包括但不限于在由许可证颁发者或者代表其管理的电子邮件清单、源代码控制系统、以及发布跟踪系统上为 243 | 讨论和提高作品的交流,但不包括由版权所有者以书面形式明显标注或指定为"非贡献"的交流活动。 244 | 245 | "贡献者"是指许可证颁发者和代表从许可证颁发者接受之贡献的并随后包含在作品之贡献中的任何个人或法律实体。 246 | 247 | 2.版权许可证的授予 248 | 249 | 根据本许可证的条款,每个贡献者授予用户永久性的、全球性的、非专有性的、免费的、无版权费的、 250 | 不可撤销的版权许可证以源程序形式或目标形式复制、准备衍生作品、公开显示、公开执行、 251 | 授予分许可证、以及分发作品和这样的衍生作品。 252 | 253 | 3.专利许可证的授予 254 | 255 | 根据本许可证的条款,每个贡献者授予用户永久性的、全球性的、非专有性的、免费的、无版权费的、 256 | 不可撤销的(除在本部分进行说明)专利许可证对作品进行制作、让人制作、使用、提供销售、销售、 257 | 进口和其它转让,且这样的许可证仅适用于在所递交作品的贡献中因可由单一的或多个这样的贡献者 258 | 授予而必须侵犯的申请专利。如果用户对任何实体针对作品或作品中所涉及贡献提出因直接性或贡献性 259 | 专利侵权而提起专利法律诉讼(包括交互诉讼请求或反索赔),那么根据本许可证,授予用户针对作品 260 | 的任何专利许可证将在提起上述诉讼之日起终止。 261 | 262 | 4.重新分发 263 | 264 | 用户可在任何媒介中复制和分发作品或衍生作品之副本,无论是否修订,还是以源程序形式或目标形式, 265 | 条件是用户需满足下列条款: 266 | 267 | a) 用户必须为作品或衍生作品的任何其他接收者提供本许可证的副本;并且 268 | 269 | b) 用户必须让任何修改过的文件附带明显的通知,声明用户已更改文件;并且 270 | 271 | c) 用户必须从作品的源程序形式中保留衍生作品源程序形式的用户所分发的所有版权、专利、 272 | 商标和属性通知,但不包括不属于衍生作品任何部分的类似通知;并且 273 | 274 | d) 如果作品将"通知"文本文件包括为其分发作品的一部分,那么用户分发的任何衍生作品中须至少 275 | 在下列地方之一包括,在这样的通知文件中所包含的属性通知的可读副本,但不包括那些不属于衍生 276 | 作品任何部分的通知:在作为衍生作品一部分而分发的通知文本文件中;如果与衍生作品一起提供则 277 | 在源程序形式或文件中;或者通常作为第三方通知出现的时候和地方,在衍生作品中产生的画面中。 278 | 通知文件的内容仅供信息提供,并未对许可证进行修改。用户可在其分发的衍生作品中在作品的通知 279 | 文本后或作为附录添加自己的属性通知,条件是附加的属性通知不得构成修改本许可证。 280 | 281 | 用户可以为自身所做出的修订添加自己的版权声明并可对自身所做出修订内容或为这样的衍生作品作为 282 | 整体的使用、复制或分发提供附加或不同的条款,条件是用户对作品的使用、复制和分发必须符合本许 283 | 可证中声明的条款。 284 | 285 | 5.贡献的提交。 286 | 287 | 除非用户明确声明,在作品中由用户向许可证颁发者的提交若要包含在贡献中,必须在无任何附加条款下 288 | 符合本许可证的条款。尽管上面如此规定,执行许可证颁发者有关贡献的条款时,任何情况下均不得替代 289 | 或修改任何单独许可证协议的条款。 290 | 291 | 6.商标。本许可证并未授予用户使用许可证颁发者的商号、商标、服务标记或产品名称,除非将这些名称 292 | 用于合理性和惯例性描述作品起源和复制通知文件的内容时。 293 | 294 | 7.保证否认条款。除非因适用法律需要或书面同意,许可证颁发者以"按原样"基础提供作品(并且每个 295 | 贡献者提供其贡献),无任何明示的或暗示的保证或条件,包括但不限于关于所有权、不侵权、 296 | 商品适销性、或适用性的保证或条件。用户仅对使用或重新分发作品的正确性负责,并需承担根据本 297 | 许可证行使权限时的任何风险。 298 | 299 | 8.责任限制条款。在任何情况下并根据任何法律,无论是因侵权(包括过失)或根据合同,还是其它原因, 300 | 除非根据适用法律需要(例如故意行为和重大过失行为)或经书面同意,即使贡献者事先已被告知发生 301 | 损害的可能性,任何贡献者不就用户因使用本许可证或不能使用或无法使用作品(包括但不限于商誉损失、 302 | 停工、计算机失效或故障,或任何商业损坏或损失)而造成的损失,包括直接的、非直接的、特殊的、意外 303 | 的或间接的字符损坏而负责。 304 | 305 | 9.接受保证或附加责任。重新分发作品或及其衍生作品时,用户可选择提供或为符合本许可证承担之支持、 306 | 担保、赔偿或其它职责义务和/或权利而收取费用。但是,在承担上述义务时,用户只可代表用户本身和 307 | 用户本身责任来执行,无需代表任何其它贡献者,并且用户仅可保证、防护并保持每个贡献者不受任何 308 | 因此而产生的责任或对因用户自身承担这样的保证或附加责任而对这样的贡献者所提出的索赔。 309 | 310 | 条款结束 311 | 312 | 附录:如何向用户作品中应用Apache许可证。 313 | 314 | 若要向用户作品应用Apache许可证,请附加下列样本通知,将括号"[]"中的字段以用户自身的 315 | 区分信息来替换(但不包括括号)。文本必须以文件格式适当的注释句法包含在其中。 316 | 另外建议将文件名或类别名以及目的说明包含在相同的"打印页"上作为版权通知,以更加容易的区分出第三方档案。 317 | 318 | 版权所有 2016 ShenHuaJie iBase4J@163.com 根据2.0版本Apache许可证("许可证")授权; 319 | 根据本许可证,用户可以不使用此文件。 320 | 321 | 用户可从下列网址获得许可证副本:http://www.apache.org/licenses/LICENSE-2.0 322 | 除非因适用法律需要或书面同意,根据许可证分发的软件是基于"按原样"基础提供, 323 | 无任何明示的或暗示的保证或条件。详见根据许可证许可下,特定语言的管辖权限和限制。 324 | 325 | ======================================================= 326 | 327 | 简要解释: 328 | 329 | 1.需要给代码的用户一份Apache Licence 330 | 2.如果你修改了代码,需要在被修改的文件中说明。 331 | 3.在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标, 332 | 专利声明和其他原来作者规定需要包含的说明。 333 | 4.如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有 Apache Licence。 334 | 你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 项目简介 2 | 3 | [jdbc-pool](https://github.com/houbb/jdbc-pool) 是一款简化版的 jdbc-pool 实现。 4 | 5 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.houbb/jdbc-pool/badge.svg)](http://mvnrepository.com/artifact/com.github.houbb/jdbc-pool) 6 | [![Build Status](https://www.travis-ci.org/houbb/jdbc-pool.svg?branch=master)](https://www.travis-ci.org/houbb/jdbc-pool?branch=master) 7 | [![](https://img.shields.io/badge/license-Apache2-FF0080.svg)](https://github.com/houbb/jdbc-pool/blob/master/LICENSE.txt) 8 | [![Open Source Love](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/houbb/jdbc-pool) 9 | 10 | ## 拓展阅读 11 | 12 | 第一节 [从零开始手写 mybatis(一)MVP 版本](https://mp.weixin.qq.com/s/8eF7oFxgLsilqLYGOVtkGg)。 13 | 14 | 第二节 [从零开始手写 mybatis(二)mybatis interceptor 插件机制详解](https://mp.weixin.qq.com/s/83GzYTQCrWiEowN0gjll0Q) 15 | 16 | 第三节 [从零开始手写 mybatis(三)jdbc pool 从零实现数据库连接池](https://mp.weixin.qq.com/s/pO1XU_PD2pHyq-bBWMAP2w) 17 | 18 | 第四节 [从零开始手写 mybatis(四)- mybatis 事务管理机制详解](https://mp.weixin.qq.com/s/6Wa5AbOrg4MhRbZL674t8Q) 19 | 20 | ## 创作目的 21 | 22 | - 学习 jdbc-pool 的原理 23 | 24 | - 便于拓展自己的数据库工具 25 | 26 | ## 特性 27 | 28 | - 基本的数据库连接池实现 29 | 30 | - 自动适配 jdbc 驱动类 31 | 32 | - 支持各种场景对于连接的校验 33 | 34 | # 快速开始 35 | 36 | ## 需要 37 | 38 | - jdk 1.7+ 39 | 40 | - maven 3.x+ 41 | 42 | ## maven 引入 43 | 44 | ```xml 45 | 46 | com.github.houbb 47 | jdbc-pool 48 | 1.7.0 49 | 50 | ``` 51 | 52 | ## 引导类 53 | 54 | ```java 55 | JdbcPoolBs jdbcPoolBs = JdbcPoolBs.newInstance() 56 | .username("root") 57 | .password("123456") 58 | .url("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8"); 59 | 60 | DataSource pooled = jdbcPoolBs.pooled(); 61 | DataSource unPooled = jdbcPoolBs.unPooled(); 62 | ``` 63 | 64 | ## 测试代码 65 | 66 | ```java 67 | UnPooledDataSource source = new UnPooledDataSource(); 68 | source.setDriverClass("com.mysql.jdbc.Driver"); 69 | source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8"); 70 | source.setUser("root"); 71 | source.setPassword("123456"); 72 | 73 | Connection connection = source.getConnection(); 74 | ``` 75 | 76 | ## 池化的实现 77 | 78 | ```java 79 | PooledDataSource source = new PooledDataSource(); 80 | source.setDriverClass("com.mysql.jdbc.Driver"); 81 | source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8"); 82 | source.setUser("root"); 83 | source.setPassword("123456"); 84 | source.setMinSize(1); 85 | 86 | // 初始化 87 | source.init(); 88 | 89 | Connection connection = source.getConnection(); 90 | System.out.println(connection.getCatalog()); 91 | 92 | Connection connection2 = source.getConnection(); 93 | System.out.println(connection2.getCatalog()); 94 | ``` 95 | 96 | ### 输出日志 97 | 98 | ``` 99 | [DEBUG] [2020-07-18 10:50:54.536] [main] [c.g.h.t.p.d.PooledDataSource.getFreeConnection] - 从连接池中获取连接 100 | test 101 | [DEBUG] [2020-07-18 10:50:54.537] [main] [c.g.h.t.p.d.PooledDataSource.getConnection] - 开始扩容连接池大小,step: 1 102 | [DEBUG] [2020-07-18 10:50:54.548] [main] [c.g.h.t.p.d.PooledDataSource.getConnection] - 从扩容后的连接池中获取连接 103 | test 104 | ``` 105 | 106 | 第一次默认直接从线程池中获取,第二次为重新创建的信息。 107 | 108 | # 后期 road-map 109 | 110 | - [x] 根据 url 自动识别 driverClass 111 | 112 | - [x] 添加获取的等待 113 | 114 | - [x] 添加设置为繁忙的状态 check 115 | 116 | - [x] 添加日志替代 sout 117 | 118 | - [x] 添加 validQuery, testOnBorrow, testOnReturn, testWhileIdle 119 | 120 | - [ ] 添加 filter-chain 121 | 122 | - [ ] JMX 添加各种监听的属性 123 | 124 | - [ ] 添加监控页面实现 125 | 126 | - [ ] 添加 druid/mybatis??/commons-pool 等常见的数据源 127 | 128 | # 中间件等工具开源矩阵 129 | 130 | [heaven: 收集开发中常用的工具类](https://github.com/houbb/heaven) 131 | 132 | [rpc: 基于 netty4 实现的远程调用工具](https://github.com/houbb/rpc) 133 | 134 | [mq: 简易版 mq 实现](https://github.com/houbb/mq) 135 | 136 | [ioc: 模拟简易版 spring ioc](https://github.com/houbb/ioc) 137 | 138 | [mybatis: 简易版 mybatis](https://github.com/houbb/mybatis) 139 | 140 | [cache: 渐进式 redis 缓存](https://github.com/houbb/cache) 141 | 142 | [jdbc-pool: 数据库连接池实现](https://github.com/houbb/jdbc-pool) 143 | 144 | [sandglass: 任务调度时间工具框架](https://github.com/houbb/sandglass) 145 | 146 | [sisyphus: 支持注解的重试框架](https://github.com/houbb/sisyphus) 147 | 148 | [resubmit: 防止重复提交框架,支持注解](https://github.com/houbb/resubmit) 149 | 150 | [auto-log: 日志自动输出](https://github.com/houbb/auto-log) 151 | 152 | [async: 多线程异步并行框架](https://github.com/houbb/async) 153 | 154 | -------------------------------------------------------------------------------- /cgit.bat: -------------------------------------------------------------------------------- 1 | :: 用于提交当前变更(windows) 2 | :: author: houbb 3 | :: LastUpdateTime: 2018-11-22 09:08:52 4 | :: 用法:双击运行,或者当前路径 cmd 直接输入 .\cgit.bat 5 | 6 | git pull 7 | git add . 8 | git commit -m "[Feature] add for new" 9 | git push 10 | git status 11 | 12 | -------------------------------------------------------------------------------- /doc/CI集成.md: -------------------------------------------------------------------------------- 1 | # 文档说明 2 | 3 | 作者:侯宾宾 4 | 5 | 时间:2018-04-24 10:11:43 6 | 7 | 说明:如何进行项目的持续集成+测试覆盖率 8 | 9 | # Travis-CI 10 | 11 | [https://www.travis-ci.org](https://www.travis-ci.org) 直接添加此项目 12 | 13 | # Coveralls 14 | 15 | - 添加项目 16 | 17 | [https://coveralls.io/repos/new](https://coveralls.io/repos/new) 直接添加项目 18 | 19 | - 生成密匙 20 | 21 | ``` 22 | travis encrypt COVERALLS_TOKEN=${your_repo_token} 23 | ``` 24 | 25 | - 添加到文件 26 | 27 | ``` 28 | travis encrypt COVERALLS_TOKEN=${your_repo_token} --add 29 | ``` 30 | 31 | -------------------------------------------------------------------------------- /doc/发布流程.md: -------------------------------------------------------------------------------- 1 | # 文档说明 2 | 3 | 本文档用于说明当前项目如何进行发布。 4 | 5 | 6 | # 发布流程 7 | 8 | ## push to mvn center 9 | 10 | ``` 11 | mvn clean deploy -P release 12 | ``` 13 | 14 | ## commit to github 15 | 16 | ``` 17 | git push 18 | ``` 19 | 20 | ## merge to master 21 | 22 | ``` 23 | git checkout master 24 | git pull 25 | git checkout branch 26 | git rebase master (用rebase合并主干的修改,如果有冲突在此时解决) 27 | git checkout master 28 | git merge branch 29 | git push 30 | ``` 31 | 32 | ## create new branch & checkout 33 | 34 | ``` 35 | git branch release_XXX 36 | git checkout release_XXX 37 | ``` 38 | 39 | ## modify project version 40 | 41 | ``` 42 | mvn versions:set -DgroupId=com.github.houbb -DartifactId=paradise* -DoldVersion=1.1.2 -DnewVersion=1.1.3-SNAPSHOT--> 43 | mvn -N versions:update-child-modules 44 | mvn versions:commit 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /doc/项目原型.md: -------------------------------------------------------------------------------- 1 | # 原型创建 2 | 3 | - create 4 | 5 | ``` 6 | $ mvn archetype:create-from-project 7 | ``` 8 | 9 | - config 10 | 11 | ``` 12 | ~/target/generated-sources/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml 13 | ``` 14 | 15 | [archetype-descriptor](http://maven.apache.org/archetype/archetype-models/archetype-descriptor/archetype-descriptor.html) 16 | 17 | # 文件内容 18 | 19 | `~/maven-archetype/target/generated-sources/archetype/src/main/resources/META-INF/maven/archetype-metadata.xml` 20 | 21 | 22 | ```xml 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | .gitignore 33 | README.md 34 | release.sh 35 | .coveralls.yml 36 | .travis.yml 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | LICENSE.txt 45 | release.sh 46 | README.md 47 | 48 | 49 | 50 | 51 | src/main/java 52 | 53 | **/*.md 54 | 55 | 56 | 57 | src/main/resources 58 | 59 | **/*.md 60 | 61 | 62 | 63 | src/test/java 64 | 65 | **/*.md 66 | 67 | 68 | 69 | 70 | doc 71 | 72 | **/*.md 73 | 74 | 75 | 76 | 77 | 78 | ``` 79 | 80 | - install 81 | 82 | ``` 83 | $ cd target/generated-sources/archetype/ 84 | $ mvn install 85 | ``` 86 | 87 | 88 | - use 89 | 90 | ``` 91 | $ mkdir /tmp/archetype 92 | $ cd /tmp/archetype 93 | $ mvn archetype:generate -DarchetypeCatalog=local 94 | ``` 95 | 96 | ## 注意 97 | 98 | `.gitignore` 文件默认没有添加,需要手动添加。 99 | 100 | `*.iml` 文件是多余的,手动删除 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.github.houbb 7 | jdbc-pool 8 | 1.7.1 9 | 10 | 11 | 12 | 3.2 13 | 3.2 14 | 2.18.1 15 | true 16 | true 17 | 18 | 2.2.1 19 | 2.9.1 20 | 1.5 21 | 22 | 4.3.0 23 | 2.7 24 | 25 | 26 | UTF-8 27 | 1.7 28 | 29 | 30 | 0.9.0 31 | 1.1.8 32 | 33 | 34 | 4.13.1 35 | 8.0.13 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | com.github.houbb 46 | heaven 47 | ${heaven.version} 48 | 49 | 50 | com.github.houbb 51 | log-integration 52 | ${log-integration.version} 53 | 54 | 55 | 56 | 57 | junit 58 | junit 59 | ${junit.version} 60 | test 61 | true 62 | 63 | 64 | mysql 65 | mysql-connector-java 66 | ${mysql.version} 67 | true 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-compiler-plugin 77 | ${plugin.compiler.version} 78 | 79 | ${project.compiler.level} 80 | ${project.compiler.level} 81 | ${project.build.sourceEncoding} 82 | 83 | 84 | 85 | 86 | org.apache.maven.plugins 87 | maven-surefire-plugin 88 | 2.22.2 89 | 90 | true 91 | 92 | 93 | 94 | 95 | 96 | 97 | jdbc-pool 98 | The simple jdbc-pool for java. 99 | 100 | 101 | org.sonatype.oss 102 | oss-parent 103 | 7 104 | 105 | 106 | 107 | The Apache Software License, Version 2.0 108 | http://www.apache.org/licenses/LICENSE-2.0.txt 109 | repo 110 | 111 | 112 | 113 | https://github.com/houbb/jdbc-pool 114 | https://github.com/houbb/jdbc-pool.git 115 | https://houbb.github.io/ 116 | 117 | 118 | 119 | houbb 120 | houbinbin.echo@gmail.com 121 | https://houbb.github.io/ 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | release 131 | 132 | 133 | 134 | 135 | org.apache.maven.plugins 136 | maven-source-plugin 137 | ${plugin.maven-source-plugin.version} 138 | 139 | 140 | package 141 | 142 | jar-no-fork 143 | 144 | 145 | 146 | 147 | 148 | 149 | org.apache.maven.plugins 150 | maven-javadoc-plugin 151 | ${plugin.maven-javadoc-plugin.version} 152 | 153 | 154 | package 155 | 156 | jar 157 | 158 | 159 | 160 | 161 | 162 | 163 | org.apache.maven.plugins 164 | maven-gpg-plugin 165 | ${plugin.maven-gpg-plugin.version} 166 | 167 | 168 | verify 169 | 170 | sign 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | org.eluder.coveralls 180 | coveralls-maven-plugin 181 | ${plugin.coveralls.version} 182 | 183 | 184 | 185 | org.codehaus.mojo 186 | cobertura-maven-plugin 187 | ${plugin.cobertura.version} 188 | 189 | xml 190 | 256m 191 | 192 | true 193 | 194 | 195 | **/*Test.class 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | oss 207 | https://oss.sonatype.org/content/repositories/snapshots/ 208 | 209 | 210 | oss 211 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 212 | 213 | 214 | 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /release.bat: -------------------------------------------------------------------------------- 1 | :: 用于 release 当前项目(windows) 2 | :: author: houbb 3 | :: LastUpdateTime: 2018-1-22 09:08:52 4 | :: 用法:双击运行,或者当前路径 cmd 直接输入 release.bat 5 | 6 | :: 关闭回显 7 | @echo OFF 8 | 9 | ECHO "============================= RELEASE START..." 10 | 11 | :: 版本号信息(需要手动指定) 12 | :::: 旧版本名称 13 | SET version=1.7.1 14 | :::: 新版本名称 15 | SET newVersion=1.8.0 16 | :::: 组织名称 17 | SET groupName=com.github.houbb 18 | :::: 项目名称 19 | SET projectName=jdbc-pool 20 | 21 | :: release 项目版本 22 | :::: snapshot 版本号 23 | SET snapshot_version=%version%"-SNAPSHOT" 24 | :::: 新的版本号 25 | SET release_version=%version% 26 | 27 | call mvn versions:set -DgroupId=%groupName% -DartifactId=%projectName% -DoldVersion=%snapshot_version% -DnewVersion=%release_version% 28 | call mvn -N versions:update-child-modules 29 | call mvn versions:commit 30 | call echo "1. RELEASE %snapshot_version% TO %release_version% DONE." 31 | 32 | 33 | :: 推送到 github 34 | git add . 35 | git commit -m "release branch %version%" 36 | git push 37 | git status 38 | 39 | ECHO "2. PUSH TO GITHUB DONE." 40 | 41 | :: 推送到 maven 中央仓库 42 | call mvn clean deploy -P release 43 | ECHO "3 PUSH TO MVN CENTER DONE." 44 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "============================= RELEASE START..." 3 | 4 | ## 版本号信息(需要手动指定) 5 | oldVersion="0.0.1" 6 | newVersion="0.0.2" 7 | projectName="jdbc-pool" 8 | 9 | # release 项目版本 10 | ## snapshot 版本号 11 | snapshot_version=${oldVersion}"-SNAPSHOT" 12 | ## 新的版本号 13 | release_version=${oldVersion} 14 | 15 | mvn versions:set -DgroupId=com.github.houbb -DartifactId=${projectName} -DoldVersion=${snapshot_version} -DnewVersion=${release_version} 16 | mvn -N versions:update-child-modules 17 | mvn versions:commit 18 | echo "1. RELEASE ${snapshot_version} TO ${release_version} DONE." 19 | 20 | 21 | # 推送到 github 22 | git add . 23 | git commit -m "release branch ${version}" 24 | git push 25 | git status 26 | 27 | echo "2. PUSH TO GITHUB DONE." 28 | 29 | 30 | # 推送到 maven 中央仓库 31 | mvn clean deploy -P release 32 | 33 | echo "3. PUSH TO MAVEN CENTER DONE." 34 | 35 | # 合并到 master 分支 36 | branchName="release_"${version} # 分支名称 37 | git checkout master 38 | git pull 39 | git checkout ${branchName} 40 | git rebase master 41 | git checkout master 42 | git merge ${branchName} 43 | git push 44 | 45 | echo "4. MERGE TO MASTER DONE." 46 | 47 | 48 | # 拉取新的分支 49 | newBranchName="release_"${newVersion} 50 | git branch ${newBranchName} 51 | git checkout ${newBranchName} 52 | git push --set-upstream origin ${newBranchName} 53 | 54 | echo "5. NEW BRANCH DONE." 55 | 56 | # 修改新分支的版本号 57 | ## snapshot 版本号 58 | snapshot_new_version=${newVersion}"-SNAPSHOT" 59 | mvn versions:set -DgroupId=com.github.houbb -DartifactId=${projectName} -DoldVersion=${release_version} -DnewVersion=${snapshot_new_version} 60 | mvn -N versions:update-child-modules 61 | mvn versions:commit 62 | 63 | git add . 64 | git commit -m "modify branch ${release_version} TO ${snapshot_new_version}" 65 | git push 66 | git status 67 | echo "6. MODIFY ${release_version} TO ${snapshot_new_version} DONE." 68 | 69 | echo "============================= RELEASE END..." 70 | 71 | 72 | # 使用方式: 73 | # 1. 赋值权限: chmod +x ./release.sh 74 | # 2. 执行: ./release.sh 75 | # Last Update Time: 2018-01-20 12:07:34 76 | # Author: houbb 77 | 78 | 79 | -------------------------------------------------------------------------------- /release_rm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "============================= RELEASE START..." 3 | 4 | ## 版本号信息(需要手动指定) 5 | oldVersion="1.0.0" 6 | newVersion="1.0.0" 7 | projectName="${artifactId}" 8 | 9 | # 删除分支 10 | oldBranchName="release_"${oldVersion} 11 | git branch -d ${oldBranchName} 12 | git push origin --delete ${oldBranchName} 13 | 14 | echo "1. Branch remove success..." 15 | 16 | # 拉取新的分支 17 | newBranchName="release_"${newVersion} 18 | git branch ${newBranchName} 19 | git checkout ${newBranchName} 20 | git push --set-upstream origin ${newBranchName} 21 | 22 | echo "2. NEW BRANCH DONE." 23 | 24 | # 修改新分支的版本号 25 | ## snapshot 版本号 26 | snapshot_new_version=${newVersion}"-SNAPSHOT" 27 | mvn versions:set -DgroupId=com.github.houbb -DartifactId=${projectName} -DoldVersion=${release_version} -DnewVersion=${snapshot_new_version} 28 | mvn -N versions:update-child-modules 29 | mvn versions:commit 30 | 31 | git add . 32 | git commit -m "modify branch ${release_version} TO ${snapshot_new_version}" 33 | git push 34 | git status 35 | echo "3. MODIFY ${release_version} TO ${snapshot_new_version} DONE." 36 | 37 | echo "============================= BRANCH RE-CREATE END..." 38 | 39 | echo "============================= BRANCH LIST =============================" 40 | git branch -a 41 | 42 | # 使用方式: 43 | # 注意:本脚本用于删除分支,谨慎使用! 44 | # 1. 赋值权限: chmod +x ./release_rm.sh 45 | # 2. 执行: ./release_rm.sh 46 | # Last Update Time: 2018-06-21 11:10:42 47 | # Author: houbb -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/api/IConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.api; 2 | 3 | /** 4 | * 配置接口 5 | * @author binbin.hou 6 | * @since 1.0.0 7 | */ 8 | public interface IConfig { 9 | 10 | /** 11 | * 设置驱动类 12 | * 13 | * @param driverClass 驱动类 14 | * @since 1.0.0 15 | */ 16 | void setDriverClass(final String driverClass); 17 | 18 | /** 19 | * jdbc url 20 | * @param jdbcUrl url 21 | * @since 1.0.0 22 | */ 23 | void setJdbcUrl(final String jdbcUrl); 24 | 25 | /** 26 | * 设置用户信息 27 | * @param user 用户信息 28 | * @since 1.0.0 29 | */ 30 | void setUser(final String user); 31 | 32 | /** 33 | * 设置密码 34 | * @param password 密码 35 | * @since 1.0.0 36 | */ 37 | void setPassword(final String password); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/api/IDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.api; 2 | 3 | import javax.sql.DataSource; 4 | 5 | /** 6 | * 配置接口 7 | * @author binbin.hou 8 | * @since 1.0.0 9 | */ 10 | public interface IDataSourceConfig extends IConfig, DataSource { 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/api/ILifeCycle.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.api; 2 | 3 | /** 4 | * 生命周期管理 5 | * @since 1.1.0 6 | */ 7 | public interface ILifeCycle { 8 | 9 | /** 10 | * 生命的初始化 11 | * @since 1.1.0 12 | */ 13 | void init(); 14 | 15 | /** 16 | * 生命的销毁 17 | * @since 1.1.0 18 | */ 19 | void destroy(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/api/IPooledDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.api; 2 | 3 | import com.github.houbb.thread.pool.connection.IPooledConnection; 4 | 5 | /** 6 | * 池化的接口 7 | * @author binbin.hou 8 | * @since 1.0.0 9 | */ 10 | public interface IPooledDataSourceConfig extends IDataSourceConfig { 11 | 12 | /** 13 | * 归还连接 14 | * @param pooledConnection 连接池信息 15 | * @since 1.5.0 16 | */ 17 | void returnConnection(IPooledConnection pooledConnection); 18 | 19 | /** 20 | * 设置最小尺寸 21 | * 22 | * @param minSize 大小 23 | * @since 1.1.0 24 | */ 25 | void setMinSize(final int minSize); 26 | 27 | /** 28 | * 设置最大的大小 29 | * 30 | * @param maxSize 最大的大小 31 | * @since 1.1.0 32 | */ 33 | void setMaxSize(final int maxSize); 34 | 35 | /** 36 | * 设置最大的等待时间 37 | * @param maxWaitMills 最大的等待时间 38 | * @since 1.1.0 39 | */ 40 | void setMaxWaitMills(final long maxWaitMills); 41 | 42 | /** 43 | * 设置验证查询的语句 44 | * 45 | * 如果这个值为空,那么 {@link #setTestOnBorrow(boolean)} 46 | * {@link #setTestOnIdle(boolean)}} 47 | * {@link #setTestOnReturn(boolean)} 48 | * 都将无效 49 | * @param validQuery 验证查询的语句 50 | * @since 1.5.0 51 | */ 52 | void setValidQuery(final String validQuery); 53 | 54 | /** 55 | * 验证的超时秒数 56 | * @param validTimeOutSeconds 验证的超时秒数 57 | * @since 1.5.0 58 | */ 59 | void setValidTimeOutSeconds(final int validTimeOutSeconds); 60 | 61 | /** 62 | * 获取连接时进行校验 63 | * 64 | * 备注:影响性能 65 | * @param testOnBorrow 是否 66 | * @since 1.5.0 67 | */ 68 | void setTestOnBorrow(final boolean testOnBorrow); 69 | 70 | /** 71 | * 归还连接时进行校验 72 | * 73 | * 备注:影响性能 74 | * @param testOnReturn 归还连接时进行校验 75 | * @since 1.5.0 76 | */ 77 | void setTestOnReturn(final boolean testOnReturn); 78 | 79 | /** 80 | * 闲暇的时候进行校验 81 | * @param testOnIdle 闲暇的时候进行校验 82 | * @since 1.5.0 83 | */ 84 | void setTestOnIdle(final boolean testOnIdle); 85 | 86 | /** 87 | * 闲暇时进行校验的时间间隔 88 | * @param testOnIdleIntervalSeconds 时间间隔 89 | * @since 1.5.0 90 | */ 91 | void setTestOnIdleIntervalSeconds(final long testOnIdleIntervalSeconds); 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/bs/JdbcPoolBs.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.bs; 2 | 3 | import com.github.houbb.thread.pool.constant.DriverNameConst; 4 | import com.github.houbb.thread.pool.constant.PooledConst; 5 | import com.github.houbb.thread.pool.datasource.PooledDataSource; 6 | import com.github.houbb.thread.pool.datasource.UnPooledDataSource; 7 | 8 | import javax.sql.DataSource; 9 | 10 | /** 11 | * jdbc 线程池引导类 12 | * @since 1.6.0 13 | */ 14 | public class JdbcPoolBs { 15 | 16 | /** 17 | * 驱动类 18 | * @since 0.0.9 19 | */ 20 | private String driverClass = DriverNameConst.MYSQL_8; 21 | 22 | private String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"; 23 | 24 | private String username = "root"; 25 | 26 | private String password = "123456"; 27 | 28 | /** 29 | * 最小尺寸 30 | * @since 1.1.0 31 | */ 32 | private int minSize = PooledConst.DEFAULT_MIN_SIZE; 33 | 34 | /** 35 | * 最大尺寸 36 | * @since 1.1.0 37 | */ 38 | private int maxSize = PooledConst.DEFAULT_MAX_SIZE; 39 | 40 | /** 41 | * 最大的等待时间 42 | * @since 1.3.0 43 | */ 44 | private long maxWaitMills = PooledConst.DEFAULT_MAX_WAIT_MILLS; 45 | 46 | /** 47 | * 验证查询 48 | * @since 1.5.0 49 | */ 50 | private String validQuery = PooledConst.DEFAULT_VALID_QUERY; 51 | 52 | /** 53 | * 验证的超时时间 54 | * @since 1.5.0 55 | */ 56 | private int validTimeOutSeconds = PooledConst.DEFAULT_VALID_TIME_OUT_SECONDS; 57 | 58 | /** 59 | * 获取时验证 60 | * @since 1.5.0 61 | */ 62 | private boolean testOnBorrow = PooledConst.DEFAULT_TEST_ON_BORROW; 63 | 64 | /** 65 | * 归还时验证 66 | * @since 1.5.0 67 | */ 68 | private boolean testOnReturn = PooledConst.DEFAULT_TEST_ON_RETURN; 69 | 70 | /** 71 | * 闲暇时验证 72 | * @since 1.5.0 73 | */ 74 | private boolean testOnIdle = PooledConst.DEFAULT_TEST_ON_IDLE; 75 | 76 | /** 77 | * 闲暇时验证的时间间隔 78 | * @since 1.5.0 79 | */ 80 | private long testOnIdleIntervalSeconds = PooledConst.DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS; 81 | 82 | public JdbcPoolBs driverClass(String driverClass) { 83 | this.driverClass = driverClass; 84 | return this; 85 | } 86 | 87 | public JdbcPoolBs url(String url) { 88 | this.url = url; 89 | return this; 90 | } 91 | 92 | public JdbcPoolBs username(String username) { 93 | this.username = username; 94 | return this; 95 | } 96 | 97 | public JdbcPoolBs password(String password) { 98 | this.password = password; 99 | return this; 100 | } 101 | 102 | public JdbcPoolBs minSize(int minSize) { 103 | this.minSize = minSize; 104 | return this; 105 | } 106 | 107 | public JdbcPoolBs maxSize(int maxSize) { 108 | this.maxSize = maxSize; 109 | return this; 110 | } 111 | 112 | public JdbcPoolBs maxWaitMills(long maxWaitMills) { 113 | this.maxWaitMills = maxWaitMills; 114 | return this; 115 | } 116 | 117 | public JdbcPoolBs validQuery(String validQuery) { 118 | this.validQuery = validQuery; 119 | return this; 120 | } 121 | 122 | public JdbcPoolBs validTimeOutSeconds(int validTimeOutSeconds) { 123 | this.validTimeOutSeconds = validTimeOutSeconds; 124 | return this; 125 | } 126 | 127 | public JdbcPoolBs testOnBorrow(boolean testOnBorrow) { 128 | this.testOnBorrow = testOnBorrow; 129 | return this; 130 | } 131 | 132 | public JdbcPoolBs testOnReturn(boolean testOnReturn) { 133 | this.testOnReturn = testOnReturn; 134 | return this; 135 | } 136 | 137 | public JdbcPoolBs testOnIdle(boolean testOnIdle) { 138 | this.testOnIdle = testOnIdle; 139 | return this; 140 | } 141 | 142 | public JdbcPoolBs testOnIdleIntervalSeconds(long testOnIdleIntervalSeconds) { 143 | this.testOnIdleIntervalSeconds = testOnIdleIntervalSeconds; 144 | return this; 145 | } 146 | 147 | public static JdbcPoolBs newInstance() { 148 | return new JdbcPoolBs(); 149 | } 150 | 151 | /** 152 | * 简单的池化功能 153 | * @return 池化 154 | */ 155 | public DataSource pooled() { 156 | PooledDataSource dataSource = new PooledDataSource(); 157 | dataSource.setDriverClass(driverClass); 158 | dataSource.setUser(username); 159 | dataSource.setPassword(password); 160 | dataSource.setJdbcUrl(url); 161 | 162 | dataSource.setMinSize(minSize); 163 | dataSource.setMaxSize(maxSize); 164 | dataSource.setMaxWaitMills(maxWaitMills); 165 | 166 | dataSource.setTestOnBorrow(testOnBorrow); 167 | dataSource.setTestOnIdle(testOnIdle); 168 | dataSource.setTestOnIdleIntervalSeconds(testOnIdleIntervalSeconds); 169 | dataSource.setTestOnReturn(testOnReturn); 170 | 171 | dataSource.setValidQuery(validQuery); 172 | dataSource.setValidTimeOutSeconds(validTimeOutSeconds); 173 | 174 | dataSource.init(); 175 | return dataSource; 176 | } 177 | 178 | /** 179 | * 非池化 180 | * @return 结果 181 | */ 182 | public DataSource unPooled() { 183 | UnPooledDataSource dataSource = new UnPooledDataSource(); 184 | dataSource.setDriverClass(driverClass); 185 | dataSource.setUser(username); 186 | dataSource.setPassword(password); 187 | dataSource.setJdbcUrl(url); 188 | return dataSource; 189 | } 190 | 191 | } 192 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/connection/IPooledConnection.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.connection; 2 | 3 | import com.github.houbb.thread.pool.api.IPooledDataSourceConfig; 4 | 5 | import java.sql.Connection; 6 | 7 | /** 8 | * 池化的连接池 9 | * @since 1.1.0 10 | */ 11 | public interface IPooledConnection extends Connection { 12 | 13 | 14 | /** 15 | * 是否繁忙 16 | * @since 1.1.0 17 | * @return 状态 18 | */ 19 | boolean isBusy(); 20 | 21 | /** 22 | * 设置状态 23 | * @param busy 状态 24 | * @since 1.1.0 25 | */ 26 | void setBusy(boolean busy); 27 | 28 | /** 29 | * 获取真正的连接 30 | * @return 连接 31 | * @since 1.1.0 32 | */ 33 | Connection getConnection(); 34 | 35 | /** 36 | * 设置连接信息 37 | * @param connection 连接信息 38 | * @since 1.1.0 39 | */ 40 | void setConnection(Connection connection); 41 | 42 | /** 43 | * 设置对应的数据源 44 | * @param dataSource 数据源 45 | * @since 1.5.0 46 | */ 47 | void setDataSource(final IPooledDataSourceConfig dataSource); 48 | 49 | /** 50 | * 获取对应的数据源信息 51 | * @return 数据源 52 | * @since 1.5.0 53 | */ 54 | IPooledDataSourceConfig getDataSource(); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/connection/PooledConnection.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.connection; 2 | 3 | import com.github.houbb.log.integration.core.Log; 4 | import com.github.houbb.log.integration.core.LogFactory; 5 | import com.github.houbb.thread.pool.api.IPooledDataSourceConfig; 6 | import com.github.houbb.thread.pool.exception.JdbcPoolException; 7 | 8 | import java.sql.*; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | import java.util.concurrent.Executor; 12 | 13 | /** 14 | * 池化的连接 15 | * 16 | * @since 1.1.0 17 | */ 18 | public class PooledConnection implements IPooledConnection { 19 | 20 | private static final Log LOG = LogFactory.getLog(PooledConnection.class); 21 | 22 | /** 23 | * 是否繁忙 24 | * @since 1.1.0 25 | */ 26 | private volatile boolean isBusy; 27 | 28 | /** 29 | * 数据库链接信息 30 | * @since 1.1.0 31 | */ 32 | private Connection connection; 33 | 34 | /** 35 | * 对应的数据源信息 36 | * 37 | * @since 1.1.0 38 | */ 39 | private IPooledDataSourceConfig dataSource; 40 | 41 | @Override 42 | public Statement createStatement() throws SQLException { 43 | checkStatus(); 44 | 45 | return connection.createStatement(); 46 | } 47 | 48 | @Override 49 | public PreparedStatement prepareStatement(String sql) throws SQLException { 50 | checkStatus(); 51 | 52 | return connection.prepareStatement(sql); 53 | } 54 | 55 | @Override 56 | public CallableStatement prepareCall(String sql) throws SQLException { 57 | checkStatus(); 58 | 59 | return connection.prepareCall(sql); 60 | } 61 | 62 | @Override 63 | public String nativeSQL(String sql) throws SQLException { 64 | checkStatus(); 65 | 66 | return connection.nativeSQL(sql); 67 | } 68 | 69 | @Override 70 | public void setAutoCommit(boolean autoCommit) throws SQLException { 71 | checkStatus(); 72 | 73 | connection.setAutoCommit(autoCommit); 74 | } 75 | 76 | @Override 77 | public boolean getAutoCommit() throws SQLException { 78 | checkStatus(); 79 | 80 | return connection.getAutoCommit(); 81 | } 82 | 83 | @Override 84 | public void commit() throws SQLException { 85 | checkStatus(); 86 | 87 | connection.commit(); 88 | } 89 | 90 | @Override 91 | public void rollback() throws SQLException { 92 | checkStatus(); 93 | 94 | connection.rollback(); 95 | } 96 | 97 | @Override 98 | public void close() throws SQLException { 99 | checkStatus(); 100 | 101 | this.dataSource.returnConnection(this); 102 | } 103 | 104 | @Override 105 | public boolean isClosed() throws SQLException { 106 | checkStatus(); 107 | 108 | return connection.isClosed(); 109 | } 110 | 111 | @Override 112 | public DatabaseMetaData getMetaData() throws SQLException { 113 | checkStatus(); 114 | 115 | return connection.getMetaData(); 116 | } 117 | 118 | @Override 119 | public void setReadOnly(boolean readOnly) throws SQLException { 120 | checkStatus(); 121 | 122 | connection.setReadOnly(readOnly); 123 | } 124 | 125 | @Override 126 | public boolean isReadOnly() throws SQLException { 127 | checkStatus(); 128 | 129 | return connection.isReadOnly(); 130 | } 131 | 132 | @Override 133 | public void setCatalog(String catalog) throws SQLException { 134 | checkStatus(); 135 | 136 | connection.setCatalog(catalog); 137 | } 138 | 139 | @Override 140 | public String getCatalog() throws SQLException { 141 | checkStatus(); 142 | 143 | return connection.getCatalog(); 144 | } 145 | 146 | @Override 147 | public void setTransactionIsolation(int level) throws SQLException { 148 | checkStatus(); 149 | 150 | connection.setTransactionIsolation(level); 151 | } 152 | 153 | @Override 154 | public int getTransactionIsolation() throws SQLException { 155 | checkStatus(); 156 | 157 | return connection.getTransactionIsolation(); 158 | } 159 | 160 | @Override 161 | public SQLWarning getWarnings() throws SQLException { 162 | checkStatus(); 163 | 164 | return connection.getWarnings(); 165 | } 166 | 167 | @Override 168 | public void clearWarnings() throws SQLException { 169 | checkStatus(); 170 | 171 | connection.clearWarnings(); 172 | } 173 | 174 | @Override 175 | public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { 176 | checkStatus(); 177 | 178 | return connection.createStatement(resultSetType, resultSetConcurrency); 179 | } 180 | 181 | @Override 182 | public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { 183 | checkStatus(); 184 | 185 | return connection.prepareStatement(sql, resultSetType, resultSetConcurrency); 186 | } 187 | 188 | @Override 189 | public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { 190 | checkStatus(); 191 | 192 | return connection.prepareCall(sql, resultSetType, resultSetConcurrency); 193 | } 194 | 195 | @Override 196 | public Map> getTypeMap() throws SQLException { 197 | checkStatus(); 198 | 199 | return connection.getTypeMap(); 200 | } 201 | 202 | @Override 203 | public void setTypeMap(Map> map) throws SQLException { 204 | checkStatus(); 205 | 206 | connection.setTypeMap(map); 207 | } 208 | 209 | @Override 210 | public void setHoldability(int holdability) throws SQLException { 211 | checkStatus(); 212 | 213 | connection.setHoldability(holdability); 214 | } 215 | 216 | @Override 217 | public int getHoldability() throws SQLException { 218 | checkStatus(); 219 | 220 | return connection.getHoldability(); 221 | } 222 | 223 | @Override 224 | public Savepoint setSavepoint() throws SQLException { 225 | checkStatus(); 226 | 227 | return connection.setSavepoint(); 228 | } 229 | 230 | @Override 231 | public Savepoint setSavepoint(String name) throws SQLException { 232 | checkStatus(); 233 | 234 | return connection.setSavepoint(name); 235 | } 236 | 237 | @Override 238 | public void rollback(Savepoint savepoint) throws SQLException { 239 | checkStatus(); 240 | 241 | connection.rollback(savepoint); 242 | } 243 | 244 | @Override 245 | public void releaseSavepoint(Savepoint savepoint) throws SQLException { 246 | checkStatus(); 247 | 248 | connection.releaseSavepoint(savepoint); 249 | } 250 | 251 | @Override 252 | public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { 253 | checkStatus(); 254 | 255 | return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); 256 | } 257 | 258 | @Override 259 | public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { 260 | checkStatus(); 261 | 262 | return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); 263 | } 264 | 265 | @Override 266 | public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { 267 | checkStatus(); 268 | 269 | return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); 270 | } 271 | 272 | @Override 273 | public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { 274 | checkStatus(); 275 | 276 | return connection.prepareStatement(sql, autoGeneratedKeys); 277 | } 278 | 279 | @Override 280 | public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { 281 | checkStatus(); 282 | 283 | return connection.prepareStatement(sql, columnIndexes); 284 | } 285 | 286 | @Override 287 | public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { 288 | checkStatus(); 289 | 290 | return connection.prepareStatement(sql, columnNames); 291 | } 292 | 293 | @Override 294 | public Clob createClob() throws SQLException { 295 | checkStatus(); 296 | 297 | return connection.createClob(); 298 | } 299 | 300 | @Override 301 | public Blob createBlob() throws SQLException { 302 | checkStatus(); 303 | 304 | return connection.createBlob(); 305 | } 306 | 307 | @Override 308 | public NClob createNClob() throws SQLException { 309 | checkStatus(); 310 | 311 | return connection.createNClob(); 312 | } 313 | 314 | @Override 315 | public SQLXML createSQLXML() throws SQLException { 316 | checkStatus(); 317 | 318 | return connection.createSQLXML(); 319 | } 320 | 321 | @Override 322 | public boolean isValid(int timeout) throws SQLException { 323 | checkStatus(); 324 | 325 | return connection.isValid(timeout); 326 | } 327 | 328 | @Override 329 | public void setClientInfo(String name, String value) throws SQLClientInfoException { 330 | checkStatus(); 331 | 332 | connection.setClientInfo(name, value); 333 | } 334 | 335 | @Override 336 | public void setClientInfo(Properties properties) throws SQLClientInfoException { 337 | checkStatus(); 338 | 339 | connection.setClientInfo(properties); 340 | } 341 | 342 | @Override 343 | public String getClientInfo(String name) throws SQLException { 344 | checkStatus(); 345 | 346 | return connection.getClientInfo(name); 347 | } 348 | 349 | @Override 350 | public Properties getClientInfo() throws SQLException { 351 | checkStatus(); 352 | 353 | return connection.getClientInfo(); 354 | } 355 | 356 | @Override 357 | public Array createArrayOf(String typeName, Object[] elements) throws SQLException { 358 | checkStatus(); 359 | 360 | return connection.createArrayOf(typeName, elements); 361 | } 362 | 363 | @Override 364 | public Struct createStruct(String typeName, Object[] attributes) throws SQLException { 365 | checkStatus(); 366 | 367 | return connection.createStruct(typeName, attributes); 368 | } 369 | 370 | @Override 371 | public void setSchema(String schema) throws SQLException { 372 | checkStatus(); 373 | 374 | connection.setSchema(schema); 375 | } 376 | 377 | @Override 378 | public String getSchema() throws SQLException { 379 | checkStatus(); 380 | 381 | return connection.getSchema(); 382 | } 383 | 384 | @Override 385 | public void abort(Executor executor) throws SQLException { 386 | checkStatus(); 387 | 388 | connection.abort(executor); 389 | } 390 | 391 | @Override 392 | public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { 393 | checkStatus(); 394 | 395 | connection.setNetworkTimeout(executor, milliseconds); 396 | } 397 | 398 | @Override 399 | public int getNetworkTimeout() throws SQLException { 400 | checkStatus(); 401 | 402 | return connection.getNetworkTimeout(); 403 | } 404 | 405 | @Override 406 | public T unwrap(Class iface) throws SQLException { 407 | checkStatus(); 408 | 409 | return connection.unwrap(iface); 410 | } 411 | 412 | @Override 413 | public boolean isWrapperFor(Class iface) throws SQLException { 414 | checkStatus(); 415 | 416 | return connection.isWrapperFor(iface); 417 | } 418 | 419 | @Override 420 | public boolean isBusy() { 421 | return isBusy; 422 | } 423 | 424 | @Override 425 | public void setBusy(boolean busy) { 426 | isBusy = busy; 427 | } 428 | 429 | @Override 430 | public Connection getConnection() { 431 | return connection; 432 | } 433 | 434 | @Override 435 | public void setConnection(Connection connection) { 436 | this.connection = connection; 437 | } 438 | 439 | @Override 440 | public IPooledDataSourceConfig getDataSource() { 441 | return dataSource; 442 | } 443 | 444 | @Override 445 | public void setDataSource(IPooledDataSourceConfig dataSource) { 446 | this.dataSource = dataSource; 447 | } 448 | 449 | /** 450 | * 对于设置为繁忙的连接,等价于关闭 451 | * @since 1.4.0 452 | */ 453 | private void checkStatus() { 454 | if(!isBusy) { 455 | throw new JdbcPoolException("Connection has been closed"); 456 | } 457 | } 458 | 459 | } 460 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/constant/DriverNameConst.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.constant; 2 | 3 | /** 4 | * 数据库加在类名称常量 5 | * 6 | * @author bbhou 7 | * date 2017/7/31 8 | * @since 0.0.1 9 | */ 10 | public final class DriverNameConst { 11 | 12 | private DriverNameConst(){} 13 | 14 | /** 15 | * SQL Server 数据库 16 | * com.microsoft.sqlserver.jdbc. 17 | */ 18 | public static final String SQL_SERVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; 19 | 20 | /** 21 | * MySQL 数据库 22 | */ 23 | public static final String MYSQL = "com.mysql.jdbc.Driver"; 24 | 25 | /** 26 | * MYSQL 8.0 及其以后的版本 27 | */ 28 | //jdbc.url=jdbc:mysql://localhost:3306/k3c?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&serverTimezone=Hongkong 29 | public static final String MYSQL_8 = "com.mysql.cj.jdbc.Driver"; 30 | 31 | /** 32 | * Oracle 数据库 33 | */ 34 | public static final String ORACLE = "oracle.jdbc.OracleDriver"; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/constant/PooledConst.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.constant; 2 | 3 | /** 4 | * 线程池常量 5 | * @since 1.1.0 6 | */ 7 | public final class PooledConst { 8 | 9 | private PooledConst(){} 10 | 11 | /** 12 | * 默认的最小连接数 13 | * @since 1.1.0 14 | */ 15 | public static final int DEFAULT_MIN_SIZE = 10; 16 | 17 | /** 18 | * 默认最大的连接数 19 | * @since 1.1.0 20 | */ 21 | public static final int DEFAULT_MAX_SIZE = 300; 22 | 23 | /** 24 | * 默认最大的等待毫秒数 25 | * 26 | * 默认:1 min 27 | * 28 | * @since 1.3.0 29 | */ 30 | public static final int DEFAULT_MAX_WAIT_MILLS = 60 * 1000; 31 | 32 | /** 33 | * 默认验证查询的语句 34 | * @since 1.5.0 35 | */ 36 | public static final String DEFAULT_VALID_QUERY = "select 1 from dual"; 37 | 38 | /** 39 | * 默认的验证的超时时间 40 | * @since 1.5.0 41 | */ 42 | public static final int DEFAULT_VALID_TIME_OUT_SECONDS = 5; 43 | 44 | /** 45 | * 获取连接时,默认不校验 46 | * @since 1.5.0 47 | */ 48 | public static final boolean DEFAULT_TEST_ON_BORROW = false; 49 | 50 | 51 | /** 52 | * 归还连接时,默认不校验 53 | * @since 1.5.0 54 | */ 55 | public static final boolean DEFAULT_TEST_ON_RETURN = false; 56 | 57 | /** 58 | * 默认闲暇的时候,进行校验 59 | * 60 | * @since 1.5.0 61 | */ 62 | public static final boolean DEFAULT_TEST_ON_IDLE = true; 63 | 64 | /** 65 | * 1min 自动校验一次 66 | * 67 | * @since 1.5.0 68 | */ 69 | public static final long DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS = 60; 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/datasource/AbstractDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | /** 4 | * @author binbin.hou 5 | * @since 1.0.0 6 | */ 7 | public class AbstractDataSourceConfig extends DataSourceConfigAdaptor { 8 | 9 | /** 10 | * 驱动类 11 | * @since 1.0.0 12 | */ 13 | protected String driverClass; 14 | 15 | /** 16 | * jdbc url 17 | * @since 1.0.0 18 | */ 19 | protected String jdbcUrl; 20 | 21 | /** 22 | * 用户 23 | * @since 1.0.0 24 | */ 25 | protected String user; 26 | 27 | /** 28 | * 密码 29 | * @since 1.0.0 30 | */ 31 | protected String password; 32 | 33 | public String getDriverClass() { 34 | return driverClass; 35 | } 36 | 37 | @Override 38 | public void setDriverClass(String driverClass) { 39 | this.driverClass = driverClass; 40 | } 41 | 42 | public String getJdbcUrl() { 43 | return jdbcUrl; 44 | } 45 | 46 | @Override 47 | public void setJdbcUrl(String jdbcUrl) { 48 | this.jdbcUrl = jdbcUrl; 49 | } 50 | 51 | public String getUser() { 52 | return user; 53 | } 54 | 55 | @Override 56 | public void setUser(String user) { 57 | this.user = user; 58 | } 59 | 60 | public String getPassword() { 61 | return password; 62 | } 63 | 64 | @Override 65 | public void setPassword(String password) { 66 | this.password = password; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/datasource/AbstractPooledDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import com.github.houbb.thread.pool.api.ILifeCycle; 4 | import com.github.houbb.thread.pool.api.IPooledDataSourceConfig; 5 | import com.github.houbb.thread.pool.constant.PooledConst; 6 | 7 | /** 8 | * @author binbin.hou 9 | * @since 1.1.0 10 | */ 11 | public abstract class AbstractPooledDataSourceConfig extends AbstractDataSourceConfig 12 | implements IPooledDataSourceConfig, ILifeCycle { 13 | 14 | /** 15 | * 最小尺寸 16 | * @since 1.1.0 17 | */ 18 | protected int minSize = PooledConst.DEFAULT_MIN_SIZE; 19 | 20 | /** 21 | * 最大尺寸 22 | * @since 1.1.0 23 | */ 24 | protected int maxSize = PooledConst.DEFAULT_MAX_SIZE; 25 | 26 | /** 27 | * 最大的等待时间 28 | * @since 1.3.0 29 | */ 30 | protected long maxWaitMills = PooledConst.DEFAULT_MAX_WAIT_MILLS; 31 | 32 | /** 33 | * 验证查询 34 | * @since 1.5.0 35 | */ 36 | protected String validQuery = PooledConst.DEFAULT_VALID_QUERY; 37 | 38 | /** 39 | * 验证的超时时间 40 | * @since 1.5.0 41 | */ 42 | protected int validTimeOutSeconds = PooledConst.DEFAULT_VALID_TIME_OUT_SECONDS; 43 | 44 | /** 45 | * 获取时验证 46 | * @since 1.5.0 47 | */ 48 | protected boolean testOnBorrow = PooledConst.DEFAULT_TEST_ON_BORROW; 49 | 50 | /** 51 | * 归还时验证 52 | * @since 1.5.0 53 | */ 54 | protected boolean testOnReturn = PooledConst.DEFAULT_TEST_ON_RETURN; 55 | 56 | /** 57 | * 闲暇时验证 58 | * @since 1.5.0 59 | */ 60 | protected boolean testOnIdle = PooledConst.DEFAULT_TEST_ON_IDLE; 61 | 62 | /** 63 | * 闲暇时验证的时间间隔 64 | * @since 1.5.0 65 | */ 66 | protected long testOnIdleIntervalSeconds = PooledConst.DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS; 67 | 68 | public int getMinSize() { 69 | return minSize; 70 | } 71 | 72 | @Override 73 | public void setMinSize(int minSize) { 74 | this.minSize = minSize; 75 | } 76 | 77 | public int getMaxSize() { 78 | return maxSize; 79 | } 80 | 81 | @Override 82 | public void setMaxSize(int maxSize) { 83 | this.maxSize = maxSize; 84 | } 85 | 86 | public long getMaxWaitMills() { 87 | return maxWaitMills; 88 | } 89 | 90 | @Override 91 | public void setMaxWaitMills(long maxWaitMills) { 92 | this.maxWaitMills = maxWaitMills; 93 | } 94 | 95 | public String getValidQuery() { 96 | return validQuery; 97 | } 98 | 99 | @Override 100 | public void setValidQuery(String validQuery) { 101 | this.validQuery = validQuery; 102 | } 103 | 104 | public int getValidTimeOutSeconds() { 105 | return validTimeOutSeconds; 106 | } 107 | 108 | @Override 109 | public void setValidTimeOutSeconds(int validTimeOutSeconds) { 110 | this.validTimeOutSeconds = validTimeOutSeconds; 111 | } 112 | 113 | public boolean isTestOnBorrow() { 114 | return testOnBorrow; 115 | } 116 | 117 | @Override 118 | public void setTestOnBorrow(boolean testOnBorrow) { 119 | this.testOnBorrow = testOnBorrow; 120 | } 121 | 122 | public boolean isTestOnReturn() { 123 | return testOnReturn; 124 | } 125 | 126 | @Override 127 | public void setTestOnReturn(boolean testOnReturn) { 128 | this.testOnReturn = testOnReturn; 129 | } 130 | 131 | public boolean isTestOnIdle() { 132 | return testOnIdle; 133 | } 134 | 135 | @Override 136 | public void setTestOnIdle(boolean testOnIdle) { 137 | this.testOnIdle = testOnIdle; 138 | } 139 | 140 | public long getTestOnIdleIntervalSeconds() { 141 | return testOnIdleIntervalSeconds; 142 | } 143 | 144 | @Override 145 | public void setTestOnIdleIntervalSeconds(long testOnIdleIntervalSeconds) { 146 | this.testOnIdleIntervalSeconds = testOnIdleIntervalSeconds; 147 | } 148 | 149 | @Override 150 | public void init() { 151 | 152 | } 153 | 154 | @Override 155 | public void destroy() { 156 | 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/datasource/DataSourceConfigAdaptor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import com.github.houbb.thread.pool.api.IDataSourceConfig; 4 | 5 | import javax.sql.DataSource; 6 | import java.io.PrintWriter; 7 | import java.sql.Connection; 8 | import java.sql.SQLException; 9 | import java.sql.SQLFeatureNotSupportedException; 10 | import java.util.logging.Logger; 11 | 12 | /** 13 | * @author binbin.hou 14 | * @since 1.0.0 15 | */ 16 | public class DataSourceConfigAdaptor implements IDataSourceConfig { 17 | 18 | @Override 19 | public Connection getConnection() throws SQLException { 20 | return null; 21 | } 22 | 23 | @Override 24 | public Connection getConnection(String username, String password) throws SQLException { 25 | return null; 26 | } 27 | 28 | @Override 29 | public T unwrap(Class iface) throws SQLException { 30 | return null; 31 | } 32 | 33 | @Override 34 | public boolean isWrapperFor(Class iface) throws SQLException { 35 | return false; 36 | } 37 | 38 | @Override 39 | public PrintWriter getLogWriter() throws SQLException { 40 | return null; 41 | } 42 | 43 | @Override 44 | public void setLogWriter(PrintWriter out) throws SQLException { 45 | 46 | } 47 | 48 | @Override 49 | public void setLoginTimeout(int seconds) throws SQLException { 50 | 51 | } 52 | 53 | @Override 54 | public int getLoginTimeout() throws SQLException { 55 | return 0; 56 | } 57 | 58 | @Override 59 | public Logger getParentLogger() throws SQLFeatureNotSupportedException { 60 | return null; 61 | } 62 | 63 | @Override 64 | public void setDriverClass(String driverClass) { 65 | 66 | } 67 | 68 | @Override 69 | public void setJdbcUrl(String jdbcUrl) { 70 | 71 | } 72 | 73 | @Override 74 | public void setUser(String user) { 75 | 76 | } 77 | 78 | @Override 79 | public void setPassword(String password) { 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/datasource/PooledDataSource.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import com.github.houbb.heaven.util.lang.StringUtil; 4 | import com.github.houbb.heaven.util.util.DateUtil; 5 | import com.github.houbb.heaven.util.util.Optional; 6 | import com.github.houbb.log.integration.core.Log; 7 | import com.github.houbb.log.integration.core.LogFactory; 8 | import com.github.houbb.thread.pool.connection.IPooledConnection; 9 | import com.github.houbb.thread.pool.connection.PooledConnection; 10 | import com.github.houbb.thread.pool.exception.JdbcPoolException; 11 | import com.github.houbb.thread.pool.util.DriverClassUtil; 12 | 13 | import java.sql.Connection; 14 | import java.sql.DriverManager; 15 | import java.sql.SQLException; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.concurrent.Executor; 19 | import java.util.concurrent.Executors; 20 | import java.util.concurrent.ScheduledExecutorService; 21 | import java.util.concurrent.TimeUnit; 22 | 23 | /** 24 | * 池化的数据源 25 | * @author binbin.hou 26 | * @since 1.1.0 27 | */ 28 | public class PooledDataSource extends AbstractPooledDataSourceConfig { 29 | 30 | private static final Log LOG = LogFactory.getLog(PooledDataSource.class); 31 | 32 | /** 33 | * 内置的队列 34 | * @since 1.1.0 35 | */ 36 | private List pool = new ArrayList<>(); 37 | 38 | @Override 39 | public synchronized void init() { 40 | DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl); 41 | 42 | this.initJdbcPool(); 43 | 44 | // 初始化 idle check 45 | this.initTestOnIdle(); 46 | } 47 | 48 | @Override 49 | public synchronized Connection getConnection() throws SQLException { 50 | //1. 获取第一个不是 busy 的连接 51 | Optional connectionOptional = getFreeConnectionFromPool(); 52 | if(connectionOptional.isPresent()) { 53 | return connectionOptional.get(); 54 | } 55 | 56 | //2. 考虑是否可以扩容 57 | if(pool.size() >= maxSize) { 58 | //2.1 立刻返回 59 | if(maxWaitMills <= 0) { 60 | LOG.error("[JdbcPool] Can't get connection from pool!"); 61 | throw new JdbcPoolException("Can't get connection from pool!"); 62 | } 63 | 64 | 65 | //2.2 循环等待 66 | final long startWaitMills = System.currentTimeMillis(); 67 | final long endWaitMills = startWaitMills + maxWaitMills; 68 | while (System.currentTimeMillis() < endWaitMills) { 69 | Optional optional = getFreeConnectionFromPool(); 70 | if(optional.isPresent()) { 71 | return optional.get(); 72 | } 73 | 74 | DateUtil.sleep(1); 75 | // LOG.debug("等待连接池归还,wait for 1 mills"); 76 | } 77 | 78 | //2.3 等待超时 79 | LOG.error("[JdbcPool] Can't get connection from pool, wait time out for mills: {}", maxWaitMills); 80 | throw new JdbcPoolException("Can't get connection from pool, wait time out for mills: " + maxWaitMills); 81 | } 82 | 83 | //3. 扩容(暂时只扩容一个) 84 | LOG.info("[JdbcPool] start to resize jdbc pool,step: 1"); 85 | IPooledConnection pooledConnection = createPooledConnection(); 86 | pooledConnection.setBusy(true); 87 | this.pool.add(pooledConnection); 88 | LOG.info("[JdbcPool] end to resize jdbc pool"); 89 | return pooledConnection; 90 | } 91 | 92 | @Override 93 | public void returnConnection(IPooledConnection pooledConnection) { 94 | // 验证状态 95 | if(testOnReturn) { 96 | checkValid(pooledConnection); 97 | } 98 | 99 | // 设置为不繁忙 100 | pooledConnection.setBusy(false); 101 | // LOG.debug("归还连接,状态设置为不繁忙"); 102 | } 103 | 104 | /** 105 | * 获取空闲的连接 106 | * @return 连接 107 | * @since 1.3.0 108 | */ 109 | private Optional getFreeConnectionFromPool() { 110 | for(IPooledConnection pc : pool) { 111 | if(!pc.isBusy()) { 112 | pc.setBusy(true); 113 | // LOG.debug("从连接池中获取连接"); 114 | 115 | // 验证有效性 116 | if(testOnBorrow) { 117 | // LOG.debug("Test on borrow start"); 118 | checkValid(pc); 119 | // LOG.debug("Test on borrow finish"); 120 | } 121 | 122 | return Optional.of(pc); 123 | } 124 | } 125 | // 空 126 | return Optional.empty(); 127 | } 128 | 129 | 130 | /** 131 | * https://stackoverflow.com/questions/3668506/efficient-sql-test-query-or-validation-query-that-will-work-across-all-or-most 132 | * 133 | * 真正支持标准的,直接使用 {@link Connection#isValid(int)} 验证比较合适 134 | * @param pooledConnection 连接池信息 135 | * @since 1.5.0 136 | */ 137 | private void checkValid(final IPooledConnection pooledConnection) { 138 | if(StringUtil.isNotEmpty(super.validQuery)) { 139 | Connection connection = pooledConnection.getConnection(); 140 | try { 141 | // 如果连接无效,重新申请一个新的替代 142 | if(!connection.isValid(super.validTimeOutSeconds)) { 143 | // LOG.debug("Old connection is inValid, start create one for it."); 144 | 145 | Connection newConnection = createConnection(); 146 | pooledConnection.setConnection(newConnection); 147 | // LOG.debug("Old connection is inValid, finish create one for it."); 148 | } 149 | } catch (SQLException throwables) { 150 | LOG.error("[JdbcPool] checkValid failed", throwables); 151 | 152 | throw new JdbcPoolException(throwables); 153 | } 154 | } else { 155 | // LOG.debug("valid query is empty, ignore valid."); 156 | } 157 | } 158 | 159 | /** 160 | * 初始化连接池 161 | * @since 1.1.0 162 | */ 163 | private void initJdbcPool() { 164 | final int minSize = super.minSize; 165 | pool = new ArrayList<>(minSize); 166 | 167 | for(int i = 0; i < minSize; i++) { 168 | IPooledConnection pooledConnection = createPooledConnection(); 169 | 170 | pool.add(pooledConnection); 171 | } 172 | } 173 | 174 | /** 175 | * 创建一个池化的连接 176 | * @return 连接 177 | * @since 1.1.0 178 | */ 179 | private IPooledConnection createPooledConnection() { 180 | Connection connection = createConnection(); 181 | 182 | IPooledConnection pooledConnection = new PooledConnection(); 183 | pooledConnection.setBusy(false); 184 | pooledConnection.setConnection(connection); 185 | pooledConnection.setDataSource(this); 186 | 187 | return pooledConnection; 188 | } 189 | 190 | /** 191 | * 创建新连接 192 | * @return 连接 193 | * @since 1.1.0 194 | */ 195 | private Connection createConnection() { 196 | try { 197 | return DriverManager.getConnection(super.getJdbcUrl(), 198 | super.getUser(), super.getPassword()); 199 | } catch (SQLException e) { 200 | LOG.error("[JdbcPool] createConnection failed", e); 201 | 202 | throw new JdbcPoolException(e); 203 | } 204 | } 205 | 206 | 207 | /** 208 | * 初始化空闲时检验 209 | * @since 1.5.0 210 | */ 211 | private void initTestOnIdle() { 212 | if(StringUtil.isNotEmpty(validQuery)) { 213 | ScheduledExecutorService idleExecutor = Executors.newSingleThreadScheduledExecutor(); 214 | 215 | idleExecutor.scheduleAtFixedRate(new Runnable() { 216 | @Override 217 | public void run() { 218 | testOnIdleCheck(); 219 | } 220 | }, super.testOnIdleIntervalSeconds, testOnIdleIntervalSeconds, TimeUnit.SECONDS); 221 | // LOG.debug("Test on idle config with interval seconds: " + testOnIdleIntervalSeconds); 222 | } 223 | } 224 | 225 | /** 226 | * 验证所有的空闲连接是否有效 227 | * @since 1.5.0 228 | */ 229 | private void testOnIdleCheck() { 230 | // LOG.debug("start check test on idle"); 231 | for(IPooledConnection pc : this.pool) { 232 | if(!pc.isBusy()) { 233 | checkValid(pc); 234 | } 235 | } 236 | // LOG.debug("finish check test on idle"); 237 | } 238 | 239 | } 240 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/datasource/UnPooledDataSource.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import com.github.houbb.thread.pool.util.DriverClassUtil; 4 | 5 | import java.sql.Connection; 6 | import java.sql.DriverManager; 7 | import java.sql.SQLException; 8 | 9 | /** 10 | * @author binbin.hou 11 | * @since 1.0.0 12 | */ 13 | public class UnPooledDataSource extends AbstractDataSourceConfig { 14 | 15 | @Override 16 | public Connection getConnection() throws SQLException { 17 | DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl); 18 | 19 | return DriverManager.getConnection(super.getJdbcUrl(), 20 | super.getUser(), super.getPassword()); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/exception/JdbcPoolException.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.exception; 2 | 3 | /** 4 | * @author binbin.hou 5 | * @since 1.0.0 6 | */ 7 | public class JdbcPoolException extends RuntimeException { 8 | 9 | public JdbcPoolException() { 10 | } 11 | 12 | public JdbcPoolException(String message) { 13 | super(message); 14 | } 15 | 16 | public JdbcPoolException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public JdbcPoolException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public JdbcPoolException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 25 | super(message, cause, enableSuppression, writableStackTrace); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/model/DataSourceConfigDto.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 配置对象 7 | * 8 | * @since 1.7.0 9 | */ 10 | public class DataSourceConfigDto implements Serializable { 11 | 12 | /** 13 | * 驱动类 14 | * @since 1.0.0 15 | */ 16 | protected String driverClass; 17 | 18 | /** 19 | * jdbc url 20 | * @since 1.0.0 21 | */ 22 | protected String jdbcUrl; 23 | 24 | /** 25 | * 用户 26 | * @since 1.0.0 27 | */ 28 | protected String user; 29 | 30 | /** 31 | * 密码 32 | * @since 1.0.0 33 | */ 34 | protected String password; 35 | 36 | public String getDriverClass() { 37 | return driverClass; 38 | } 39 | 40 | public void setDriverClass(String driverClass) { 41 | this.driverClass = driverClass; 42 | } 43 | 44 | public String getJdbcUrl() { 45 | return jdbcUrl; 46 | } 47 | 48 | public void setJdbcUrl(String jdbcUrl) { 49 | this.jdbcUrl = jdbcUrl; 50 | } 51 | 52 | public String getUser() { 53 | return user; 54 | } 55 | 56 | public void setUser(String user) { 57 | this.user = user; 58 | } 59 | 60 | public String getPassword() { 61 | return password; 62 | } 63 | 64 | public void setPassword(String password) { 65 | this.password = password; 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return "DataSourceConfigDto{" + 71 | "driverClass='" + driverClass + '\'' + 72 | ", jdbcUrl='" + jdbcUrl + '\'' + 73 | ", user='" + user + '\'' + 74 | ", password='" + password + '\'' + 75 | '}'; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/package-info.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/thread/pool/util/DriverClassUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.util; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.lang.StringUtil; 5 | import com.github.houbb.thread.pool.exception.JdbcPoolException; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * 驱动类工具 12 | * 13 | * 1. 默认添加对应的驱动类信息 14 | *

project: jdbc-pool-JdbcDriveUtil

15 | *

create on 2020/7/18 9:21

16 | * 17 | * @author binbin.hou 18 | * @since 1.2.0 19 | */ 20 | public final class DriverClassUtil { 21 | 22 | /** 23 | * 存放驱动类信息 24 | * @since 1.2.0 25 | */ 26 | private static final Map DRIVER_CLASS_MAP; 27 | 28 | static { 29 | DRIVER_CLASS_MAP = new HashMap<>(32); 30 | DRIVER_CLASS_MAP.put("jdbc:db2", "COM.ibm.db2.jdbc.app.DB2Driver"); 31 | DRIVER_CLASS_MAP.put("jdbc:firebirdsql", "org.firebirdsql.jdbc.FBDriver"); 32 | DRIVER_CLASS_MAP.put("jdbc:edbc", "ca.edbc.jdbc.EdbcDriver"); 33 | DRIVER_CLASS_MAP.put("jdbc:pointbase", "com.pointbase.jdbc.jdbcUniversalDriver"); 34 | DRIVER_CLASS_MAP.put("jdbc:fake", "com.alibaba.druid.mock.MockDriver"); 35 | DRIVER_CLASS_MAP.put("jdbc:informix-sqli", "com.informix.jdbc.IfxDriver"); 36 | DRIVER_CLASS_MAP.put("jdbc:sqlite", "org.sqlite.JDBC"); 37 | DRIVER_CLASS_MAP.put("jdbc:microsoft", "com.microsoft.jdbc.sqlserver.SQLServerDriver"); 38 | DRIVER_CLASS_MAP.put("jdbc:hsqldb", "org.hsqldb.jdbcDriver"); 39 | DRIVER_CLASS_MAP.put("jdbc:postgresql", "org.postgresql.Driver"); 40 | DRIVER_CLASS_MAP.put("jdbc:ingres", "com.ingres.jdbc.IngresDriver"); 41 | DRIVER_CLASS_MAP.put("jdbc:cloudscape", "COM.cloudscape.core.JDBCDriver"); 42 | DRIVER_CLASS_MAP.put("jdbc:JSQLConnect", "com.jnetdirect.jsql.JSQLDriver"); 43 | DRIVER_CLASS_MAP.put("jdbc:derby", "org.apache.derby.jdbc.EmbeddedDriver"); 44 | DRIVER_CLASS_MAP.put("jdbc:timesten", "com.timesten.jdbc.TimesTenDriver"); 45 | DRIVER_CLASS_MAP.put("jdbc:interbase", "interbase.interclient.Driver"); 46 | DRIVER_CLASS_MAP.put("jdbc:h2", "org.h2.Driver"); 47 | DRIVER_CLASS_MAP.put("jdbc:as400", "com.ibm.as400.access.AS400JDBCDriver"); 48 | DRIVER_CLASS_MAP.put("jdbc:sybase:Tds", "com.sybase.jdbc2.jdbc.SybDriver"); 49 | DRIVER_CLASS_MAP.put("jdbc:mock", "com.alibaba.druid.mock.MockDriver"); 50 | DRIVER_CLASS_MAP.put("jdbc:oracle", "oracle.jdbc.driver.OracleDriver"); 51 | DRIVER_CLASS_MAP.put("jdbc:mysql", "com.mysql.cj.jdbc.Driver"); 52 | DRIVER_CLASS_MAP.put("jdbc:odps", "com.aliyun.odps.jdbc.OdpsDriver"); 53 | DRIVER_CLASS_MAP.put("jdbc:mckoi", "com.mckoi.JDBCDriver"); 54 | DRIVER_CLASS_MAP.put("jdbc:jtds", "net.sourceforge.jtds.jdbc.Driver"); 55 | DRIVER_CLASS_MAP.put("jdbc:sapdb", "com.sap.dbtech.jdbc.DriverSapDB"); 56 | DRIVER_CLASS_MAP.put("jdbc:JTurbo", "com.newatlanta.jturbo.driver.Driver"); 57 | DRIVER_CLASS_MAP.put("jdbc:mimer:multi1", "com.mimer.jdbc.Driver"); 58 | } 59 | 60 | /** 61 | * 加载驱动类信息 62 | * @param driverClass 驱动类 63 | * @param url 连接信息 64 | * @since 1.2.0 65 | */ 66 | public static void loadDriverClass(String driverClass, final String url) { 67 | ArgUtil.notEmpty(url, url); 68 | 69 | if(StringUtil.isEmptyTrim(driverClass)) { 70 | driverClass = getDriverClassByUrl(url); 71 | } 72 | 73 | try { 74 | Class.forName(driverClass); 75 | } catch (ClassNotFoundException e) { 76 | throw new JdbcPoolException(e); 77 | } 78 | } 79 | 80 | 81 | /** 82 | * 根据 URL 获取对应的驱动类 83 | * 84 | * 1. 禁止 url 为空 85 | * 2. 如果未找到,则直接报错。 86 | * @param url url 87 | * @return 驱动信息 88 | */ 89 | private static String getDriverClassByUrl(final String url) { 90 | ArgUtil.notEmpty(url, "url"); 91 | 92 | for(Map.Entry entry : DRIVER_CLASS_MAP.entrySet()) { 93 | String urlPrefix = entry.getKey(); 94 | if(url.startsWith(urlPrefix)) { 95 | return entry.getValue(); 96 | } 97 | } 98 | 99 | throw new JdbcPoolException("Can't auto find match driver class for url: " + url); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/thread/pool/datasource/GenTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import com.github.houbb.heaven.util.io.FileUtil; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | *

project: jdbc-pool-GenTest

11 | *

create on 2020/7/18 9:25

12 | * 13 | * @author binbin.hou 14 | * @since 1.2.0 15 | */ 16 | @Ignore 17 | public class GenTest { 18 | 19 | @Test 20 | public void driverClassTest() { 21 | Map map = FileUtil.readToMap("D:\\_github\\jdbc-pool\\src\\test\\resources\\driverClass.txt", " "); 22 | 23 | final String format = "DRIVER_CLASS_MAP.put(\"%s\", \"%s\");"; 24 | for(Map.Entry entry : map.entrySet()) { 25 | String result = String.format(format, entry.getKey(), entry.getValue()); 26 | System.out.println(result); 27 | } 28 | } 29 | 30 | @Test 31 | public void driverClassMDTest() { 32 | Map map = FileUtil.readToMap("D:\\_github\\jdbc-pool\\src\\test\\resources\\driverClass.txt", " "); 33 | 34 | final String format = "| %s | %s |"; 35 | for(Map.Entry entry : map.entrySet()) { 36 | String result = String.format(format, entry.getKey(), entry.getValue()); 37 | System.out.println(result); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/thread/pool/datasource/JdbcPoolbsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import com.github.houbb.thread.pool.bs.JdbcPoolBs; 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | 7 | import javax.sql.DataSource; 8 | 9 | /** 10 | *

project: jdbc-pool-GenTest

11 | *

create on 2020/7/18 9:25

12 | * 13 | * @author binbin.hou 14 | * @since 1.2.0 15 | */ 16 | @Ignore 17 | public class JdbcPoolbsTest { 18 | 19 | @Test 20 | public void bsTest() { 21 | JdbcPoolBs jdbcPoolBs = JdbcPoolBs.newInstance() 22 | .username("root") 23 | .password("123456") 24 | .url("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"); 25 | 26 | DataSource pooled = jdbcPoolBs.pooled(); 27 | DataSource unPooled = jdbcPoolBs.unPooled(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/thread/pool/datasource/PooledDataSourceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import com.github.houbb.heaven.util.util.DateUtil; 4 | import com.github.houbb.thread.pool.exception.JdbcPoolException; 5 | import org.junit.Test; 6 | 7 | import java.sql.Connection; 8 | import java.sql.SQLException; 9 | 10 | /** 11 | * @author binbin.hou 12 | * @since 1.1.0 13 | */ 14 | public class PooledDataSourceTest { 15 | 16 | @Test 17 | public void simpleTest() throws SQLException { 18 | PooledDataSource source = new PooledDataSource(); 19 | source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"); 20 | source.setUser("root"); 21 | source.setPassword("123456"); 22 | source.setMinSize(1); 23 | 24 | // 初始化 25 | source.init(); 26 | 27 | Connection connection = source.getConnection(); 28 | System.out.println(connection.getCatalog()); 29 | 30 | Connection connection2 = source.getConnection(); 31 | System.out.println(connection2.getCatalog()); 32 | } 33 | 34 | @Test 35 | public void notWaitTest() throws SQLException { 36 | PooledDataSource source = new PooledDataSource(); 37 | source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"); 38 | source.setUser("root"); 39 | source.setPassword("123456"); 40 | source.setMinSize(1); 41 | source.setMaxSize(1); 42 | source.setMaxWaitMills(0); 43 | 44 | // 初始化 45 | source.init(); 46 | 47 | Connection connection = source.getConnection(); 48 | System.out.println(connection.getCatalog()); 49 | 50 | // 新的线程执行 51 | newThreadExec(source); 52 | 53 | DateUtil.sleep(100); 54 | } 55 | 56 | private void newThreadExec(final PooledDataSource source) { 57 | // 另起一个线程 58 | new Thread(new Runnable() { 59 | @Override 60 | public void run() { 61 | // 预期报错 62 | Connection connection2 = null; 63 | try { 64 | connection2 = source.getConnection(); 65 | System.out.println(connection2.getCatalog()); 66 | } catch (SQLException e) { 67 | throw new JdbcPoolException(e); 68 | } 69 | } 70 | }).start(); 71 | } 72 | 73 | @Test 74 | public void waitTest() throws SQLException { 75 | PooledDataSource source = new PooledDataSource(); 76 | source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"); 77 | source.setUser("root"); 78 | source.setPassword("123456"); 79 | source.setMinSize(1); 80 | source.setMaxSize(1); 81 | source.setMaxWaitMills(100); 82 | 83 | // 初始化 84 | source.init(); 85 | 86 | Connection connection = source.getConnection(); 87 | System.out.println(connection.getCatalog()); 88 | 89 | // 新的线程执行 90 | newThreadExec(source); 91 | 92 | DateUtil.sleep(10); 93 | connection.close(); 94 | System.out.println("释放第一个线程的资源。。。"); 95 | 96 | DateUtil.sleep(100); 97 | } 98 | 99 | @Test 100 | public void testOnIdleTest() throws SQLException { 101 | PooledDataSource source = new PooledDataSource(); 102 | source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"); 103 | source.setUser("root"); 104 | source.setPassword("123456"); 105 | source.setTestOnIdleIntervalSeconds(5); 106 | 107 | // 初始化配置 108 | source.init(); 109 | 110 | Connection connection = source.getConnection(); 111 | System.out.println(connection.getCatalog()); 112 | 113 | DateUtil.sleep(30 * 1000); 114 | 115 | connection.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/thread/pool/datasource/UnPooledDataSourceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.thread.pool.datasource; 2 | 3 | import org.junit.Test; 4 | 5 | import java.sql.Connection; 6 | import java.sql.SQLException; 7 | 8 | /** 9 | * @author binbin.hou 10 | * @since 1.0.0 11 | */ 12 | public class UnPooledDataSourceTest { 13 | 14 | @Test 15 | public void simpleTest() throws SQLException { 16 | UnPooledDataSource source = new UnPooledDataSource(); 17 | source.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"); 18 | source.setUser("root"); 19 | source.setPassword("123456"); 20 | 21 | Connection connection = source.getConnection(); 22 | System.out.println(connection.getCatalog()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/resources/driverClass.txt: -------------------------------------------------------------------------------- 1 | jdbc:odps com.aliyun.odps.jdbc.OdpsDriver 2 | jdbc:derby org.apache.derby.jdbc.EmbeddedDriver 3 | jdbc:mysql com.mysql.jdbc.Driver 4 | jdbc:oracle oracle.jdbc.driver.OracleDriver 5 | jdbc:microsoft com.microsoft.jdbc.sqlserver.SQLServerDriver 6 | jdbc:sybase:Tds com.sybase.jdbc2.jdbc.SybDriver 7 | jdbc:jtds net.sourceforge.jtds.jdbc.Driver 8 | jdbc:postgresql org.postgresql.Driver 9 | jdbc:fake com.alibaba.druid.mock.MockDriver 10 | jdbc:mock com.alibaba.druid.mock.MockDriver 11 | jdbc:hsqldb org.hsqldb.jdbcDriver 12 | jdbc:db2 COM.ibm.db2.jdbc.app.DB2Driver 13 | jdbc:sqlite org.sqlite.JDBC 14 | jdbc:ingres com.ingres.jdbc.IngresDriver 15 | jdbc:h2 org.h2.Driver 16 | jdbc:mckoi com.mckoi.JDBCDriver 17 | jdbc:cloudscape COM.cloudscape.core.JDBCDriver 18 | jdbc:informix-sqli com.informix.jdbc.IfxDriver 19 | jdbc:timesten com.timesten.jdbc.TimesTenDriver 20 | jdbc:as400 com.ibm.as400.access.AS400JDBCDriver 21 | jdbc:sapdb com.sap.dbtech.jdbc.DriverSapDB 22 | jdbc:JSQLConnect com.jnetdirect.jsql.JSQLDriver 23 | jdbc:JTurbo com.newatlanta.jturbo.driver.Driver 24 | jdbc:firebirdsql org.firebirdsql.jdbc.FBDriver 25 | jdbc:interbase interbase.interclient.Driver 26 | jdbc:pointbase com.pointbase.jdbc.jdbcUniversalDriver 27 | jdbc:edbc ca.edbc.jdbc.EdbcDriver 28 | jdbc:mimer:multi1 com.mimer.jdbc.Driver --------------------------------------------------------------------------------