[C3p0] Article 2: Using c3p0,
Preface
According to the c3p0-0.9.5.1 version of the official documents, coupled with their own understanding, compiled into the translation. Limited capabilities. If the translation content is incorrect or your understanding is biased, please correct it!
Use c3p0
From the user's perspective, c3p0 simply provides users with DataSource objects that comply with the jdbc standard. When creating these DataSource objects, you can control various attributes related to them. Once DataSource is created, the items behind DataSource are completely transparent to users.
Three methods to obtain DataSource with connection pool of c3p0
1. Directly instantiate and configure a CombopooledDataSource bean;
2. Use the DataSource factory class;
3. DataSource with connection pool created by directly instantiating PoolBackedDataSource and setting ConnectionPoolDataSource.
Most users will find that instantiation of CombopooledDataSource is generally the most convenient way. Once instantiated, The c3p0 DataSource can almost be bound to any JNDI-compatible Naming Service.
When you create a DataSource, if you do not specify its attributes, c3p0 provides the default attribute value, which is implemented by hard encoding. However, you can also rewrite these attribute values by using the configuration file. If you rewrite these attributes by using the configuration file, you need to put the configuration file under CLASSPATH or where ClassLoader can find them.
C3p0 data sources can be configured in multiple ways
1. the java. util. properties property file named c3p0. Properties.
2. More advanced HOCON configuration files (such as application. conf and application. json ).
3. XML file named c3p0-config.xml.
Instantiate and configure ComboPooledDataSource
The simplest and most direct creation of DataSource with connection pool in c3p0 is to instantiate com. mchange. v2.c3p0. comboPooledDataSource. this is a JavaBean-style class with a public constructor. However, before using DataSource, you must make sure to set at least one jdbcUrl attribute. You can also set user and password. If you use an old JDBC driver that cannot be preloaded, you should also set driverClass.
ComboPooledDataSource cpds = new ComboPooledDataSource();cpds.setDriverClass("org.postgresql.Driver");// loads the drivercpds.setJdbcUrl("jdbc:postgresql://localhost/testdb");cpds.setUser("swaldman");cpds.setPassword("test-password");// The settings below are potional -- c3p0 can work with defaultscpds.setMinPoolSize(5);cpds.setAcquireIncrement(5);cpds.setMaxPoolSize(20);// The DataSource cpds is now a fully configured and usable pooled DataSource
You can configure the attribute values of the c3p0 data source or use the default values directly. C3p0 supports naming, so you can configure multiple DataSource at the same time. If you want to use the name configuration, you need to use the "configuration name" as the construction parameter to construct com. mchange. v2.c3p0. ComboPooledDataSource
ComboPooledDataSource cpds = new ComboPooledDataSource("intergalactoApp");...
Of course, you can also rewrite any of its configuration attributes, just like above.
Use data source factory
You can use the static factory class com. mchange. v2.c3p0. dataSource uses a traditional JDBC driver to create a DataSource without a connection pool, and then creates a data source with a connection pool from a data source without a connection pool.
DataSource ds_unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/testdb", "swaldman", "test-password");DataSource ds_pooled = DataSources.pooledDataSource(ds_unpooled);// The DataSource ds_pooled is now a fully configured and usable pooled DataSource.// The DataSource is using a default pool configuration and Postgres' JDBC driver// is presumed to have already been loaded via the jdbc.drivers system property or an// explicit call to Class.forName("org.postgresql.Driver") elsewhere....
If you use the DataSources factory class and want to rewrite the default configuration parameters programmatically, you can provide a map set attribute.
DataSource ds_unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/testdb", "swaldman", "test-password");Map overrides = new HashMap();overrides.put("maxStatements", "200");// Stringified property values workoverrides.put("maxPoolSize", new Integer(50));// "boxed primitives" also work// create the PooledDataSource using the default configuration and our overridesDataSource ds_pooled = DataSources.pooledDataSource(ds_unpooled, overrides);// The DataSource ds_pooled is now a fully configured and usable pooled DataSource,// with Statement caching enabled for a maximum of up to 200 statements and a maximum of 50 Connection....
If you use the naming configuration, you can directly specify the default configuration of the data source.
// Create the PooledDataSource using the a named configuration and specified overrides "intergalactoApp" is a named configurationds_pooled = DataSources.pooledDataSource(ds_unpooled, "intergalactoApp", overrides);
Query the current status of PooledDataSource
C3p0 DataSource supports pools, including ComboPooledDataSource implementation and CES. pooledDataSource (...) returned object, all com. mchange. v2.c3p0. you can use multiple methods to query the status of the DataSource connection pool. The following is a simple code to query DataSource:
// Fetch a JNDI-bound DataSourceInitialContext ictx = new InitialContext();DataSource ds = (DataSource) ictx.lookup("java:comp/env/jdbc/myDataSource");// make sure it's a c3p0 PooledDataSourceif (ds instanceof PooledDataSource) {PooledDataSource pds = (PooledDataSource) ds;System.err.println("num_connections: " + pds.getNumConnectionsDefaultUser());System.err.println("num_busy_connections: " + pds.getNumBusyConnectionsDefaultUser());System.err.println("num_idle_connections: " + pds.getNumIdleConnectionsDefaultUser());System.err.println();} else {System.err.println("Not a c3p0 PooledDataSource!");}
Status query methods are similar to the following three methods:
public int getNumConnectionsDefaultUser();public int getNumCOnnections(String username, String password);public int getNumConnectionsAllUsers();
C3p0 maintains the connection pool with different authentication information. There are many ways for you to query the status of a separate pool or summarize all the data. It is worth noting that pool configuration parameters such as maxPoolSize are used for each authentication. For example, if you have set maxPoolSize = 20, DataSource is managing two pairs of username-password, the default one, and the other is created by calling getConnection (user, password, call getNumConnectionsAllUsers (). The maximum number of connections displayed is 40.
Most applications only need to obtain the Default Authentication connection from DataSource. Typically, getXXXDefaultUser () is used to collect connection data.
There is also real data in the connection pool. You can obtain the status data of the thread pool of each DataSource. See the complete list of optional PooledDataSource operations.
Use C3P0Registry to reference DataSource
If using JNDI or other methods is inconvenient or is unlikely to get a reference to DataSource, you can use the C3P0Registry class to find a valid c3p0 DataSource, which contains three static methods:
public static Set getPooledDataSources();public static Set pooledDataSourcesByName(String dataSourceName);public static PooledDataSource pooledDataSourceByName(String dataSourceName);
The first method returns the Set of c3p0 PooledDataSources. If you are sure that your application will generate only one PooledDataSources, or you can differentiate DataSource by configuring parameters (through the "getters" Check), the first method is enough.
This is not always the case. c3p0 PooledDataSources has a special attribute called dataSourceName. When constructing DataSource, you can directly set the dataSourceName attribute or configure it like other attributes. Otherwise, CENAME will have two default conditions:
1. If you use a naming configuration to construct DataSource, it is your configuration name.
2. If you use the default configuration, there will be a unique name, but it is unpredictable.
It is not guaranteed that CENAME is unique here. For example, if two c3p0 DataSource instances share a naming configuration and you do not programmatically set CENAME, the two data sources share the configuration name. You can use pooledDataSourcesByName (...) to obtain all data sources of a specific CENAME.
If you are sure that the DataSource name is unique (if you want to use C3P0Registry to find the DataSource, you will usually be willing to do so), you can use the more convenient method pooledDataSourceByName (...), it directly returns the reference of the DataSource with the specified name or null (if no DataSource exists ). If you use pooledDataSourceByName (...) in DataSource with multiple shared names, the returned DataSource is not explicitly defined.
Cleaning after c3p0 PooledDataSources is used
After creating DataSources in c3p0, the simplest cleaning method is to use the static destruction method defined by the DataSources class. Only PooledDataSources needs to be cleared, and DataSources. destroy (...) is harmless if used in a DataSource without a connection pool or a non-c3p0 DataSource.
DataSource ds_pooled = null;try {DataSource ds_unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/testdb", "swaldman", "test-password");ds_pooled = DataSources.pooledDataSource(ds_unpooled);// Do all kinds of stuff with that sweet pooled DataSource...} finally {DataSources.destroy(ds_pooled);}
Optional. The PooledDataSource interface of c3p0 contains a close () method. You can call it after you use DataSource to complete the work. Therefore, you can convert a DataSource derived from c3p0 to PooledDataSource and disable it.
static void cleanup(DataSource ds) throws SQLException {// Make sure it's a c3p0 PooledDataSourceif (ds instanceof PooledDataSource) {PooledDataSource pds = (PooledDataSource) ds;pds.close();} elseSystem.err.println("Not a c3p0 PooledDataSource!");}
ComboPooledDataSource is an instance of PooledDataSource and can be closed directly through close. PooledDataSource implements java. lang. AutoCloseable, so they can be managed by Java 7 + try-with-resources blocks.
Instances that are not PooledDataSource cannot use the close () method. If you want to disable them, use the garbage collection mechanism in their finalize ). As always, finalization should be regarded as a catcher, rather than a way to prompt or clean up resources.
Advanced: build your own PoolBackedDataSource
Most programmers do this for some reason, but you can build PooledDataSource step by step. Instantiate and configure a non-pooled DriverManagerDataSource, instantiate a WrapperConnectionPoolDataSource, and set a non-pooled DataSource as its nestedDataSource attribute. Then PoolBackedDataSource uses these settings to set connectionPoolDataSource attributes.
If your driver provides a ConnectionPoolDataSource implementation, these event sequences are the primary key points. You will prefer to use c3p0 instead of using WrapperConnectionPoolDataSource of c3p0, you can create a PoolBackedDataSource to set its connectionPoolDataSource attribute. Statement pool, connectionmizmizers, and many attributes specified by c3p0 are not supported by third-party ConnectionPoolDataSource (the third-party DataSource implementation can only replace the DriverManagerDataSource function of c3p0 without significant losses ).
Advanced: original connection and statement operations
Note: From the c3p0-0.9.5, the standard JDBC4 unwrap () method is supported by the agent c3p0. Note that if you use the unwrap () method, c3p0 cannot clear any Statement or ResultSet object generated from the original Connections or Statements. You must carefully and directly clear these objects. In addition, you should be careful not to modify the underlying Connections in some way, so that they cannot be replaced with other Connections, because they must be kept suitable for the connection pool.
JDBC drivers sometimes define the implementation of Connection and Statement based on non-standard APIs of specific vendors. C3P0 uses proxies to wrap these objects, so you cannot convert Connections or Statements returned by C3P0 to classes implemented by specific vendors. C3P0 does not provide any way to directly access the original Connections and Statements, because C3P0 needs to keep track of the creation of Statements and ResultSets to prevent resource leakage and damage to the connection pool.
C3P0 does provide an API that allows you to call non-standard methods on the underlying Connection. To use it, the first step is to convert the Connection to a C3P0ProxyConnection. Then call rawConnectionOperation () to apply the java. lang. reflect. Method object. The non-standard Method you want to call is used as its parameter. The Method object you provide will be called by the second parameter target you provide (the static Method is null), and the third parameter you provide will be used. For this purpose, you can apply specific C3P0ProxyConnection. RAW_CONNECTION to any Method parameter. Before Method is called, it will be replaced by the Connection object of a specific underlying supplier.
C3P0ProxyStatement provides a similar API.
Statements (including Prepared and CallableStatements) and ResultSets returned by any original operation will be c3p0-managed and cleaned up correctly by close () of the parent proxy Connection. The user must carefully clean up any non-standard resources returned by a specific supplier.
Here is an example of calling the static method of the original Connection on the Oracle-specific API:
C3P0ProxyConnection castCon = (C3P0ProxyConnection) c3p0DataSource.getConnection();Method m = CLOB.class.getMethod("createTemporary", new Class[] { Connection.class, boolean.class, int.class });Object[] args = new Object[] { C3P0ProxyConnection.RAW_CONNECTION, Boolean.valueOf(true), new Integer(10) };CLOB oracleCLOB = (CLOB) castCon.rawConnectionOperation(m, null, args);
C3P0 contains special support for some Oracle-specific methods. For more information, see the official documentation.
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.