1.数据库连接池
1.1 为什么要使用?
(1)普通查询的坏处:
进行一次查询,要进行很多次网络交互,这样导致网络IO多; 且频繁创建连接和关闭连接,浪费数据库资源。
(2)数据库连接池的作用:
数据库连接池负责分配、管理、释放数据库连接,它允许重复使用数据库连接,而非重新建立。
(3)好处:
有利于减少网络开销,提升数据库性能,对于需要大量与数据库交互的应用有利于提升执行效率。
1.2 数据库连接池如何管理连接的
参考文档:通俗易懂地聊聊Java数据库连接池和HikariCP - 知乎
(1). 应用启动时,根据配置的最小连接数,在连接池将创建此数目的数据库连接放到池中。
(2). 应用访问时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。 当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留等待再次使用。
(3). 应用关闭时,关闭池中所有连接,释放所有资源。
1.3 HikariCP
HikariCP是日本的程序员写的,号称是最快的连接池,奉行极简主义。less is more and keep it simple and stupid。
(1)初始化方式
HikariConfig config = new HikariConfig();
HikariDataSource ds = new HikariDataSource();
HikariConfig config = new HikariConfig("/some/path/hikari.properties");
Properties props = new Properties();
(2)重要参数
connectionTestQuery:如果驱动程序支持 JDBC4,强烈建议不要设置这个属性。 这是针对不支持 JDBC4 Connection.isValid() API的 "传统 "驱动程序。 这是一个查询,在一个连接从池子里给你之前会被执行,以验证与数据库的连接是否仍然有效。 同样,尝试在没有这个属性的情况下运行数据库池,如果你的驱动不符合JDBC4标准,HikariCP 会返回错误信息。
默认值:无。
(3)HikariCP为什么这么快呢?
- 优化并精简字节码:(HikariCP利用了一个第三方的Java字节码修改类库Javassist来生成委托实现动态代理,动态代理的实现在ProxyFactory类),JDK Proxy生成的字节码更少。
- 使用更好的并发集合类ConcurrentBag。(这是一款专为连接池设计的性能卓越的并发包),(支持快速插入和删除,特别是在同一线程既添加又删除项时,提高并发读写的效率)
//类的说明
* This is a specialized concurrent bag that achieves superior performance
* to LinkedBlockingQueue and LinkedTransferQueue for the purposes of a
* connection pool. It uses ThreadLocal storage when possible to avoid
* locks, but resorts to scanning a common collection if there are no
* available items in the ThreadLocal list. Not-in-use items in the
* ThreadLocal lists can be "stolen" when the borrowing thread has none
* of its own. It is a "lock-less" implementation using a specialized
* AbstractQueuedLongSynchronizer to manage cross-thread signaling.
*
* Note that items that are "borrowed" from the bag are not actually
* removed from any collection, so garbage collection will not occur
* even if the reference is abandoned. Thus care must be taken to
* "requite" borrowed objects otherwise a memory leak will result. Only
* the "remove" method can completely remove an object from the bag.
- 使用FastList替代ArrayList,避免进行范围检查。(跟ArrayList相比,少实现了Cloneable接口,少继承了AbstractList类,不进行范围检查) /**
• * Fast list without range checking.
*
* @author Brett Wooldridge
*/
public final class FastList<T> implements List<T>, RandomAccess, Serializable public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable