概述

  数据库连接池是负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。那么其中的运行机制又是怎样的呢?今天主要介绍一下数据库连接池原理和常用的连接池。

一、为什么要使用连接池

  数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。 一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的性能低下。

  数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并讲这些连接组成一个连接池(简单说:在一个“池”里放了好多半成品的数据库连接对象),由应用程序动态地对池中的连接进行申请、使用和释放。对于多于连接池中连接数的并发请求,应该在请求队列中排队等待。并且应用程序可以根据池中连接的使用率,动态增加或减少池中的连接数。

  连接池技术尽可能多地重用了消耗内存地资源,大大节省了内存,提高了服务器地服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。

数据库连接池技术带来的优势:

  1. 资源重用
    由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程/线程的数量)。
  2. 更快的系统响应速度
    数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。
  3. 新的资源分配手段
    对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接池技术,几年钱也许还是个新鲜话题,对于目前的业务系统而言,如果设计中还没有考虑到连接池的应用,那么…….快在设计文档中加上这部分的内容吧。某一应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。
  4. 统一的连接管理,避免数据库连接泄漏
    在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接。从而避免了常规数据库连接操作中可能出现的资源泄漏。

二、传统的连接机制与数据库连接池运行机制区别

1、不使用连接池流程

下面以访问MySQL为例,执行一个SQL命令,如果不使用连接池,需要经过哪些流程。

不使用数据库连接池的步骤:

  1. TCP建立连接的三次握手
  2. MySQL认证的三次握手
  3. 真正的SQL执行
  4. MySQL的关闭
  5. TCP的四次握手关闭

可以看到,为了执行一条SQL,却多了非常多网络交互。

优点:

  • 实现简单

缺点:

  • 网络IO较多
  • 数据库的负载较高
  • 响应时间较长及QPS较低
  • 应用频繁的创建连接和关闭连接,导致临时对象较多,GC频繁
  • 在关闭连接后,会出现大量TIME_WAIT 的TCP状态(在2个MSL之后关闭)

2、使用连接池流程

使用数据库连接池的步骤:

第一次访问的时候,需要建立连接。 但是之后的访问,均会复用之前创建的连接,直接执行SQL语句。

优点:

  • 较少了网络开销
  • 系统的性能会有一个实质的提升
  • 没了麻烦的TIME_WAIT状态

三、数据库连接池的工作原理

连接池的工作原理主要由三部分组成,分别为

  • 连接池的建立
  • 连接池中连接的使用管理
  • 连接池的关闭

一、连接池的建立

  一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。

Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。

二、连接池的管理

  连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:

当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。

当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。

该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。

三、连接池的关闭

当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。

四、都有那些连接池方案

1、c3p0、dbcp、druid三大连接池的区别

c3p0、dbcp、druid三大连接池的区别
c3p0 开放的源代码的JDBC连接池,
DBCP 依赖Jakarta commons-pool对象池机制的数据库连接池  
druid 阿里出品,淘宝与支付宝专用的数据库连接池,它还包括了一个ProxyDriver、一系列内置的JDBC组件库,一个SQL Parser。支持所有JDBC兼容的数据库
属性对比
连接池的配置大体可以分为:基本配置、关键配置、性能配置等主要配置
基本配置:连接池进行数据库连接的四个必须配置
基本配置   DBPC C3P0 Druid
用户名 username uer username
密码 password password password
URL url jdbcUrl jdbcUrl
驱动类名 driverClassName driverClass driverClassName
注:在Druid连接池配置中,driverClassName可配可不配,不配置的话可以根据url自动识别数据库类型,然后选择相应的driverClassName。
关键配置:为了发挥数据库连接池的作用。
关键配置   DBCP c3p0 Druid
最小连接数 minldle(0) miniPoolSize(3) minldle(0)
初始化连接数 innitialSize(0) initialPoolSize(3) initialSize
最大连接数 maxTotal(8) maxPoolSize(15) maxActive(8)
最大等待时间 maxWaitMillis(毫秒) maxIdleTime(0秒) maxWait(毫秒)
说明 最小连接数 是数据库一直保持的数据库连接数
初始化连接数 连接池启动时创建的初始化数据库连接数量
最大连接数 连接池能申请的最大连接数,请求超出此数时,后面的数据库连接请求被加入等待队列中。
最大等待时间 当没有可用连接时,连接池等待连接被归还的最大时间,超过时间则抛出异常,可设置为0或负数,无限等待。
在DBCP连接池的配置中,还有一个maxldle的属性,表示最大空闲连接数,超过的空闲连接将被释放。对应的该属性在Druid中不再使用,配置了也不会有效果;而c3p0就没有对应的属性。

数据库连接池在初始化的时候回创建initialSize个连接,当有数据库操作时,会从池中取出一个连接。

如果连接数等于maxActive,则会等待一段时间,等待其他操作释放掉一个连接,如果这个时间超过了maxWait,就会报错。如果当前使用的数量没有达到maxActive,则会判断当前是否空闲连接,有的话直接使用空闲连接,没有的话,则新建一个连接。连接使用完毕后,放入池中,等待其他操作复用。

性能配置:预缓存设置、连接有效性检测设置、连接超时关闭设置
  预缓存设置:用于控制PreparedStatement数量,提升数据库性能。
预缓存   DBCP c3p0 Druid 性能配置
开启缓存功能 poolPreparedStatements maxStatements poolPreparedStatements
单个连接拥有的最大缓存数 maxOpenPreparedStatements maxStatementsPerConnection maxOpenPreparedStatements
  连接有效性检测设置:连接池内部有机制判断,如果当前的总连接数少于minildle,则会建立新的空闲连接,以保证连接数达到minildle。如果当前连接池中某个连接处于空闲,则被物理性的关闭掉。有些数据库连接的时候有超时的限制(mysql连接8小时后断开),或者由于网络中断等原因,连接池的连接会出现失效,这时候,设置一个testWhileldle参数为true,可以保证连接池中,定时检测连接可用性,不可用的连接会被抛出或者重建,保证池中connection可用。
连接有效性检测设置   DBCP c3p0 Druid
申请连接检测 testOnBorrow testConnectionOnCheckin testOnBorrow
是否超时检测 testWhileldle   testWhileldle
空闲时间 timeBetweenEvictionRuns Millis idleConnectionTestPeriod timeBetweenEvictionRunsMillis
校验sql语句 validationQuery preferredTestQuery validationQuery
归还连接检测 testOnReturn testConnectionOnCheckout testOnReturn
  超时连接关闭设置:用来检测当前使用的连接是否发生泄漏,所以在代码内部就假定如果一个连接建立连接时间很长,则认定为泄漏,继而强制关闭。
超时连接关闭设置   DBCP c3p0 Druid
是否超时关闭连接 removeAbandoned breakAfterAcquireFailure removeAbandoned
超时时间 removeAbandonedTimeout checkoutTimeout removeAbandonedTimeout
是否记录日志 logAbandoned   logAbandoned

2、c3p0、dbcp、druid三大连接池的技术实现

C3P0技术

  导包操作:c3p0-0.9.1.2.jar

  查看说明文档:

 实现的方式一:硬编码的形式

 1 @Test2     public void testGetConnection() throws Exception {3         // 获取数据库连接池的实例化对象4         ComboPooledDataSource cpds = new ComboPooledDataSource() ;5         6         // 设置连接需要的基本信息7         cpds.setDriverClass("com.mysql.cj.jdbc.Driver");8         cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");9         cpds.setUser("root");
10         cpds.setPassword("password");
11         // 设置与管理数据库连接池相关的属性
12         // 设置连接池中初始连接的数量
13         cpds.setInitialPoolSize(10);
14
15         // 获取数据库连接
16         Connection conn = cpds.getConnection() ;
17         System.out.println(conn);
18     }

实现的方式二:配置文件的方式

  配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>2 <c3p0-config>3     <named-config name="myc3p0">4             <!-- 提供用于获取连接的基本信息 -->5         <property name="driverClass">com.mysql.cj.jdbc.Driver</property>6         <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8</property>7             <!-- 主机号与端口号为本机3306时,可以省略:即jdbc:mysql:///test?serverTimezone=GMT%2B8 -->8         <property name="user">root</property>9         <property name="password">password</property>
10
11             <!-- 管理数据库连接池的基本信息 -->
12             <!-- 当数据库连接池的连接不够时,c3p0 一次性向数据库服务器申请的连接数 -->
13         <property name="acquireIncrement">5</property>
14             <!-- c3p0数据库连接池中初始化时的连接数 -->
15         <property name="initialPoolSize">10</property>
16
17             <!-- c3p0数据库连接池中维护的最少连接数 -->
18         <property name="minPoolSize">10</property>
19             <!-- c3p0数据库连接池中维护的最多连接数 -->
20         <property name="maxPoolSize">100</property>
21
22             <!-- c3p0数据库连接池中最多维护的Statement的个数 -->
23         <property name="maxStatements">50</property>
24             <!-- 每个连接中最多可以使用的Statement的个数 -->
25         <property name="maxStatementsPerConnection">2</property>
26     </named-config>
27 </c3p0-config>

说明:

  1. 配置文件的名称要求必须为 “c3p0-config.xml”  ;

  2. 第 3 行的 <named-config name="myc3p0"> 主要用于设置该配置文件的名称 ;

  3. 提供用于获取连接的基本信息的 “name” 可以参考方式一中的方法名,注意不能出现错误。

1 @Test
2     public void testGetConnection2() throws Exception {
3         // 实例化数据库连接池的对象并传入配置文件
4         ComboPooledDataSource cpds = new ComboPooledDataSource("myc3p0");
5         // 获取数据库连接
6         Connection conn = cpds.getConnection() ;
7         System.out.println("myc3p0:" + conn);
8 }

DBCP数据连接池技术:

  导包操作:commons-dbcp-1.4.jar、commons-pool-1.5.5.jar

  查看说明文档:

方式一:

 1 @Test2     public void testGetConnection() throws Exception {3         // 获取DBCP数据库连接池的实例化对象4         BasicDataSource bds = new BasicDataSource() ;5         6         // 设置连接需要的基本信息7         bds.setDriverClassName("com.mysql.cj.jdbc.Driver");8         bds.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");9         bds.setUsername("root");
10         bds.setPassword("password");
11         // 设置其他与数据库连接池管理的相关信属性
12         bds.setInitialSize(10);
13
14         // 获取数据库连接
15         Connection conn = bds.getConnection() ;
16         System.out.println(conn);
17     }

dbcp连接池常用基本配置属性:

属性 默认值 说明
initialSize 0 连接池启动时创建的初始化连接数量
maxActive 8 连接池中可同时连接的最大的连接数
maxIdle 8 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制
minIdle 0 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接。该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大。
maxWait 无限制 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待
poolPreparedStatements false 开启池的Statement是否prepared
maxOpenPreparedStatements 无限制 开启池的prepared 后的同时最大连接数
minEvictableIdleTimeMillis 连接池中连接,在时间段内一直空闲, 被逐出连接池的时间
removeAbandonedTimeout 300 超过时间限制,回收没有用(废弃)的连接
removeAbandoned false 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收

方式二:使用配置文件:

配置文件如下:

1 driverClassName=com.mysql.cj.jdbc.Driver
2 url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
3 username=root
4 password=password
 1     @Test2     public void testGetConnection2() throws Exception{3 //        方式一:使用类的加载器4 //        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");5 //        方式二:普通的文件流(当前工程下)6         FileInputStream is = new FileInputStream(new File("src/dbcp.properties")) ;7         Properties pros = new Properties() ;8         pros.load(is) ;9         DataSource ds = BasicDataSourceFactory.createDataSource(pros) ;
10
11         Connection conn = ds.getConnection() ;
12         System.out.println(conn);
13     }

Druid数据库连接池技术:

  配置文件的方式:

1 driverClassName=com.mysql.cj.jdbc.Driver
2 url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
3 username=root
4 password=password
1 @Test
2     public void testGetConnection() throws Exception {
3         InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties") ;
4         Properties pros = new Properties() ;
5         pros.load(is);
6         DataSource ds = DruidDataSourceFactory.createDataSource(pros) ;
7         Connection conn = ds.getConnection() ;
8         System.out.println(conn);
9     }

详细配置参数

配置 缺省 说明
name 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 如果没有配置,将会生成一个名字,格式是:”DataSource-” + System.identityHashCode(this)
url 连接数据库的url,不同数据库不一样。例如:mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
username 连接数据库的用户名
password 连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。
driverClassName 根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
initialSize 0 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive 8 最大连接池数量
maxIdle 8 已经不再使用,配置了也没效果
minIdle 最小连接池数量
maxWait 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatements false 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
maxOpenPreparedStatements -1 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuery 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
testOnBorrow true 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturn false 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdle false 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
timeBetweenEvictionRunsMillis 有两个含义: 1)Destroy线程会检测连接的间隔时间2)testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun 不再使用,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillis
connectionInitSqls 物理连接初始化的时候执行的sql
exceptionSorter 根据dbType自动识别 当数据库抛出一些不可恢复的异常时,抛弃连接
filters 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall
proxyFilters 类型是List,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

总结:利用以上三种数据库连接池技术实现数据库的工具类"JDBCUtil“

  1 package edu.cn.ahpu4.util;2 3 import java.io.InputStream;4 import java.sql.Connection;5 import java.sql.ResultSet;6 import java.sql.SQLException;7 import java.sql.Statement;8 import java.util.Properties;9 import javax.sql.DataSource;10 import org.apache.commons.dbcp.BasicDataSourceFactory;11 import com.alibaba.druid.pool.DruidDataSourceFactory;12 import com.mchange.v2.c3p0.ComboPooledDataSource;13 14 /**15  * 16  * @Description 操作数据库的工具类17  * @author XiaoFeng Email:1431230065@qq.com18  * @version19  * @date 2020年8月20日下午4:02:5920  *21  */22 public class JDBCUtil {23 24     /***25      * 26      * @Description 使用C3P0技术获取数据库连接27      * @author XiaoFeng28      * @date 2020年8月20日下午4:12:1729      * @return 数据库连接30      * @throws SQLException 31      */32     // 实例化数据库连接池的对象并传入配置文件33     private static ComboPooledDataSource cpds = new ComboPooledDataSource("myc3p0");34     public static Connection getConnection1() throws SQLException {35         // 获取并返回数据库连接36         return cpds.getConnection() ;37     }38     39     /***40      * 41      * @Description    使用DBCP技术获取数据库连接42      * @author XiaoFeng  43      * @date 2020年8月26日上午11:16:47  44      * @return45      * @throws Exception46      */47     private static DataSource ds2 ;48     static {49         try {50             InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");51             Properties pros = new Properties() ;52             pros.load(is) ;53             // 创建一个DBCP数据库连接池54             ds2 = BasicDataSourceFactory.createDataSource(pros) ;55         } catch (Exception e) {56             e.printStackTrace();57         }58     }59     public static Connection testGetConnection2() throws Exception{60         Connection conn = ds2.getConnection() ;61         return conn ;62     }63 64     /***65      * 66      * @Description    使用druid技术获取数据库连接67      * @author XiaoFeng  68      * @date 2020年8月26日上午11:38:41  69      * @return70      * @throws Exception71      */72     private static DataSource ds3 ;73     static {74         try {75             InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties") ;76             Properties pros = new Properties() ;77             pros.load(is);78             ds3 = DruidDataSourceFactory.createDataSource(pros) ;79         } catch (Exception e) {80             e.printStackTrace();81         }82     }83     public static Connection testGetConnection3() throws SQLException{84         Connection conn = ds3.getConnection() ;85         return conn ;86     }87     88     /***89      * 90      * @Description    关闭资源91      * @author XiaoFeng  92      * @date 2020年8月20日下午4:15:35  93      * @param conn    connection资源94      * @param ps PreparedStatement资源95      */96     public static void closeResource(Connection conn,Statement ps) {97         if (ps != null) {98             try {99                 ps.close();
100             } catch (SQLException e) {
101                 e.printStackTrace();
102             }
103         }
104         if (conn != null) {
105             try {
106                 conn.close();
107             } catch (SQLException e) {
108                 e.printStackTrace();
109             }
110         }
111     }
112
113     /***
114      *
115      * @Description    关闭资源
116      * @author XiaoFeng
117      * @date 2020年8月20日下午5:39:25
118      * @param conn
119      * @param ps
120      * @param rs ResultSet资源
121      */
122     public static void closeResource(Connection conn,Statement ps,ResultSet rs) {
123         if (ps != null) {
124             try {
125                 ps.close();
126             } catch (SQLException e) {
127                 e.printStackTrace();
128             }
129         }
130         if (conn != null) {
131             try {
132                 conn.close();
133             } catch (SQLException e) {
134                 e.printStackTrace();
135             }
136         }
137         if(rs != null) {
138             try {
139                 rs.close();
140             } catch (SQLException e) {
141                 e.printStackTrace();
142             }
143         }
144     }
145 }

参考:数据库连接池的实现及原理(图文详解) - 知乎

参考:c3p0、dbcp、druid三大连接池的区别_不务正业且不专业的程序猿的博客-CSDN博客_druid和c3p0哪个好

java—数据库连接池看这篇就够了相关推荐

  1. Java String,看这篇就够了

    String,是Java中最重要的类.这句肯定的推断不是Java之父詹姆斯·高斯林说的,而是沉默王二说的,因此你不必怀疑它的准确性. 关于字符串,有很多的面试题,但我总觉得理论知识绕来绕去没多大意思. ...

  2. Java分布式锁看这篇就够了,java基础面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  3. java基础复习看这篇就够了

    目录 Java重要特点 Java运行机制及运行过程 什么是JDK,JRE 配置环境变量path Java开发注意事项和细节说明 Java转义字符 注释的重要性 DOS命令了解 相对路径和绝对路径 变量 ...

  4. Java序列化,看这篇就够了!

    一.序列化的含义.意义及使用场景 序列化:将对象写入到IO流中 反序列化:从IO流中恢复对象 意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输 ...

  5. JAVA反射----->看这篇就够了

    目录 反射概述 反射获取类对象 反射获取构造器对象 反射获取成员变量对象 反射获取方法对象 反射的作用-绕过编译阶段为集合添加数据 反射的作用-通用框架的底层原理 反射的作用-----总结 反射概述 ...

  6. python java混合编程_详解java调用python的几种用法(看这篇就够了)

    java调用python的几种用法如下: 在java类中直接执行python语句 在java类中直接调用本地python脚本 使用Runtime.getRuntime()执行python脚本文件(推荐 ...

  7. Java应用系统监控看这篇就够了

    Java应用系统监控看这篇就够了 文章目录 业务背景 系统监控发展历程 技术方案 日志监控技术方案 Grafana+阿里云SLS日志服务 分布式链路追踪技术方案 阿里云jaeger方案 开源框架sky ...

  8. 主流Java数据库连接池比较及前瞻

    本文转载自微信公众号「工匠小猪猪的技术世界」 主流数据库连接池 常用的主流开源数据库连接池有C3P0.DBCP.Tomcat Jdbc Pool.BoneCP.Druid等 C3p0: 开源的JDBC ...

  9. .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了

    本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新手朋友),但是转念一想不如来点猛的(考虑到急性子的朋友),让你通过本文的学习就能快速的入门ASP.NET Core.既 ...

  10. Spring Cloud入门,看这篇就够了!

    点击▲关注 "中生代技术"   给公众号标星置顶 更多精彩 第一时间直达 概述 首先我给大家看一张图,如果大家对这张图有些地方不太理解的话,我希望你们看完我这篇文章会恍然大悟. 什 ...

最新文章

  1. ViewPager的简单使用说明
  2. iptables从入门到精通
  3. java mp3 暂停,Java MP3播放器 - 使用jLayer播放,暂停和搜索不能正常工作
  4. 从tcp到netty(一)
  5. zk 布局_ZK实际应用:样式和布局
  6. mysql分组失效_请教MySql中使用表子查询时,试着先排序后分组,出现排序失效的原因?...
  7. php软件开发--html进阶
  8. python取两个列表的并集、交集、差集
  9. MySQL-01-linux安装MySQL的两种方式及其遇到的问题
  10. Shell学习笔记---变量赋值与运算(原创)
  11. iOS8中添加的extensions总结(一)——今日扩展
  12. 系统签名文件pk8x509.pem 转成jks或者keystore签名文件
  13. css行内样式的属性设置,css的外部样式的设置
  14. dnSpy反编译C#编译以后dll文件并调试
  15. 关于举办“2020·中国边缘计算企业20强”榜单评选通知
  16. c语言sql数据库大作业,c语言连接sql数据库.docx
  17. KindEditor实现WORD粘贴图片自动上传
  18. Dota 2 with Large Scale Deep Reinforcement Learning翻译
  19. quartus ii引脚分配再学习下
  20. win7java浏览器崩溃_win7系统浏览器页面一直崩溃的修复方法

热门文章

  1. Ubuntu MPEG-4 AAC 与 H.264 解码器安装
  2. java来电报名字的软件_教你一招,手机来电话可以语音报出来电人的姓名和电话号码,收藏...
  3. 第一期:浙大版《JAVA语言程序设计教程》(第二版)翁凯等 主编 ——小白的入门之路(上)(一)
  4. JAVA 算法之穷举法
  5. 数字电路课程设计--电子钟实验报告
  6. 数据库基础入门知识总结
  7. 基于android的订餐系统 答辩ppt,外卖订餐系统答辩PPT
  8. 数字信号处理实验二 IIR数字滤波器设计及软件实现
  9. 记一个老年机的逆向工程与主线linux移植 (一)—— 信息收集与Bootloader移植
  10. 企业计算机仿真技术应用,基于计算机仿真技术的企业生产物流系统优化研究