一.连接池采用的创建连接方式
1.1 POOLED(集合,重复):
采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
使用了连接池技术,不会安抚创建和销毁连接
1.1.1 如何查看pooled监听方式日志
1.1.2 源码分析
第一步进入 PooledDataSource,的396行看到这个方法
while (conn == null) {
synchronized (state) {
if (!state.idleConnections.isEmpty()) {
// Pool has available connection
conn = state.idleConnections.remove(0);
if (log.isDebugEnabled()) {
log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");
}
} else {
说明了
说明他通过调用idleConnections.remove(0)去删除连接
第二步进入 idleConnections
//看到List集合就很清楚的明白POOLED的理念是通过集合存储
protected final List<PooledConnection> idleConnections = new ArrayList<PooledConnection>();
protected final List<PooledConnection> activeConnections = new ArrayList<PooledConnection>();
1.2 UNPOOLED(数组,不重复):
采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的
思想。
与上面相反,没有采用连接池技术,会反复的创建和销毁连接,利用数组存储
1.2.1 来查看源码
1.2.1.1
进入了UnpooledDataSource,映入眼帘的是一堆的方法
public class UnpooledDataSource implements DataSource {
private ClassLoader driverClassLoader;
private Properties driverProperties;
private static Map<String, Driver> registeredDrivers = new ConcurrentHashMap();
private String driver;
private String url;
private String username;
private String password;
private Boolean autoCommit;
private Integer defaultTransactionIsolationLevel;
public UnpooledDataSource() {
}
public UnpooledDataSource(String driver, String url, String username, String password) {
this.driver = driver;
this.url = url;
this.username = username;
this.password = password;
}
public UnpooledDataSource(String driver, String url, Properties driverProperties) {
this.driver = driver;
this.url = url;
this.driverProperties = driverProperties;
}
public UnpooledDataSource(ClassLoader driverClassLoader, String driver, String url, String username, String password) {
this.driverClassLoader = driverClassLoader;
this.driver = driver;
this.url = url;
this.username = username;
this.password = password;
}
public UnpooledDataSource(ClassLoader driverClassLoader, String driver, String url, Properties driverProperties) {
this.driverClassLoader = driverClassLoader;
this.driver = driver;
this.url = url;
this.driverProperties = driverProperties;
}
public Connection getConnection() throws SQLException {
return this.doGetConnection(this.username, this.password);
}
public Connection getConnection(String username, String password) throws SQLException {
return this.doGetConnection(username, password);
}
public void setLoginTimeout(int loginTimeout) throws SQLException {
DriverManager.setLoginTimeout(loginTimeout);
}
public int getLoginTimeout() throws SQLException {
return DriverManager.getLoginTimeout();
}
public void setLogWriter(PrintWriter logWriter) throws SQLException {
DriverManager.setLogWriter(logWriter);
}
public PrintWriter getLogWriter() throws SQLException {
return DriverManager.getLogWriter();
}
public ClassLoader getDriverClassLoader() {
return this.driverClassLoader;
}
public void setDriverClassLoader(ClassLoader driverClassLoader) {
this.driverClassLoader = driverClassLoader;
}
public Properties getDriverProperties() {
return this.driverProperties;
}
public void setDriverProperties(Properties driverProperties) {
this.driverProperties = driverProperties;
}
public String getDriver() {
return this.driver;
}
public synchronized void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public Boolean isAutoCommit() {
return this.autoCommit;
}
public void setAutoCommit(Boolean autoCommit) {
this.autoCommit = autoCommit;
}
public Integer getDefaultTransactionIsolationLevel() {
return this.defaultTransactionIsolationLevel;
}
public void setDefaultTransactionIsolationLevel(Integer defaultTransactionIsolationLevel) {
this.defaultTransactionIsolationLevel = defaultTransactionIsolationLevel;
}
private Connection doGetConnection(String username, String password) throws SQLException {
Properties props = new Properties();
if (this.driverProperties != null) {
props.putAll(this.driverProperties);
}
if (username != null) {
props.setProperty("user", username);
}
if (password != null) {
props.setProperty("password", password);
}
return this.doGetConnection(props);
}
private Connection doGetConnection(Properties properties) throws SQLException {
this.initializeDriver();
Connection connection = DriverManager.getConnection(this.url, properties);
this.configureConnection(connection);
return connection;
}
private synchronized void initializeDriver() throws SQLException {
if (!registeredDrivers.containsKey(this.driver)) {
try {
Class driverType;
if (this.driverClassLoader != null) {
driverType = Class.forName(this.driver, true, this.driverClassLoader);
} else {
driverType = Resources.classForName(this.driver);
}
Driver driverInstance = (Driver)driverType.newInstance();
DriverManager.registerDriver(new UnpooledDataSource.DriverProxy(driverInstance));
registeredDrivers.put(this.driver, driverInstance);
} catch (Exception var3) {
throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + var3);
}
}
}
private void configureConnection(Connection conn) throws SQLException {
if (this.autoCommit != null && this.autoCommit != conn.getAutoCommit()) {
conn.setAutoCommit(this.autoCommit);
}
if (this.defaultTransactionIsolationLevel != null) {
conn.setTransactionIsolation(this.defaultTransactionIsolationLevel);
}
}
public <T> T unwrap(Class<T> iface) throws SQLException {
throw new SQLException(this.getClass().getName() + " is not a wrapper.");
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
public Logger getParentLogger() {
return Logger.getLogger("global");
}
static {
Enumeration drivers = DriverManager.getDrivers();
while(drivers.hasMoreElements()) {
Driver driver = (Driver)drivers.nextElement();
registeredDrivers.put(driver.getClass().getName(), driver);
}
}
private static class DriverProxy implements Driver {
private Driver driver;
DriverProxy(Driver d) {
this.driver = d;
}
public boolean acceptsURL(String u) throws SQLException {
return this.driver.acceptsURL(u);
}
public Connection connect(String u, Properties p) throws SQLException {
return this.driver.connect(u, p);
}
public int getMajorVersion() {
return this.driver.getMajorVersion();
}
public int getMinorVersion() {
return this.driver.getMinorVersion();
}
public DriverPropertyInfo[] getPropertyInfo(String u, Properties p) throws SQLException {
return this.driver.getPropertyInfo(u, p);
}
public boolean jdbcCompliant() {
return this.driver.jdbcCompliant();
}
public Logger getParentLogger() {
return Logger.getLogger("global");
}
}
}
1.2.1.2 去找UnPooledDataSource中获取连接的地方(即方法开始的地方)
进入doGetConnection方法
private Connection doGetConnection(String username, String password) throws SQLException {
Properties props = new Properties();
if (this.driverProperties != null) {
props.putAll(this.driverProperties);
}
if (username != null) {
props.setProperty("user", username);
}
if (password != null) {
props.setProperty("password", password);
}
//发现他下面又调用了一个doGetConnection,进入此方法
return this.doGetConnection(props);
}
1.2.1.3 发现上一个doGetConnection又调用了一个doGetConnection,进入此doGetConnection方法
private Connection doGetConnection(Properties properties) throws SQLException {
this.initializeDriver();
//创建连接
Connection connection = DriverManager.getConnection(this.url, properties);
this.configureConnection(connection);
return connection;
}
1.2.14 进入initializeDriver
private synchronized void initializeDriver() throws SQLException {
if (!registeredDrivers.containsKey(driver)) {
Class<?> driverType;
try {
if (driverClassLoader != null) {
//Class.forName通过反射加载驱动
driverType = Class.forName(driver, true, driverClassLoader);
} else {
driverType = Resources.classForName(driver);
}
// DriverManager requires the driver to be loaded via the system ClassLoader.
// http://www.kfu.com/~nsayer/Java/dyn-jdbc.html
Driver driverInstance = (Driver)driverType.newInstance();
DriverManager.registerDriver(new DriverProxy(driverInstance));
registeredDrivers.put(driver, driverInstance);
} catch (Exception e) {
throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + e);
}
}
}
说明了
第一点:
//1.Class.forName通过反射加载驱动
driverType = Class.forName(driver, true, driverClassLoader);
说明UNPOOLED每次都是通过反射去加载驱动的,
进一步明确了
第二点:
就可以说明UNPOOLED每次都是通过1.2.1.3的doGetConnection方法的
DriverManager去加载驱动获取新的连接
//创建连接
Connection connection = DriverManager.getConnection(this.url, properties);
分析出:
第三点:
因为每次都是穿建新的连接,所以UNPOOLED一定是用数组存储的。
1.3JNDI:
采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是
不一样。
注意:如果不是web或者maven的war工程,JNDI是不能使用的