List connections in use of a JDBC Data Source - java

How do i list all connections that are in use?
This is my code:
InitialContext initialContext = new InitialContext();
DataSource dataSource = (DataSource) initialContext.lookup("jdbc/xxxxxx");
con = dataSource.getConnection();
So, having this, i want to list all connections that are currently been used to monitor the system and if needed, close the connections.

You can create a util wrapper where getConnection() will increment and returnConection will decrement. You can use connection pool like dbcp which has BasicDataSource has method getNumIdle() and getNumActive() for this kind of matrics

Related

How to set the jdbc ClientInfo in a MySQL DataSource

In Java with MySQL we want to add the jdbc ClientInfo to identify the source of each query. Currently we can do something like:
try(Connection connection = dataSource.getConnection()){
connection.setClientInfo("ApplicationName", "MyApp");
}
But I need to add it to every connection created and means checking all the source code for places where a new connection is created. I will like to set it to the DataSource level.
So far what works for me is to extends the DataSource with a custom overriden getConnection method that calls setClientInfo. This is not only a dirty workarround but datasource specific.
I have seen that mysql driver has ClientInfoProviders like the default com.mysql.cj.jdbc.CommentClientInfoProvider. A custom ClientInfoProvider can be configured like:
Properties properties = new Properties();
properties.setProperty(PropertyKey.clientInfoProvider.getKeyName(), "foo.bar.CustomClientInfoProvider");
properties.setProperty(APPLICATION_NAME, "MyApp");
HikariConfig dataSourceConfig = new HikariConfig();
dataSourceConfig.setDataSourceProperties(properties);
...
But it is only called if someone calls the getClientInfo in the connection anyway.
So I will like to know:
Is there support in the MySql driver to set the clientInfo in the DataSource just by setting properties?
If there is a way. How can it be done?
I think you can use AspectJ as a possible solution for it. You can create an aspect which will intercept calls of the DataSource.getConnection method and then call the setClientInfo method with configured parameters when the connection is established.

Create SqlSession from existing Connection directly

I'm working with existing Java code wherein there is an existing JDBC connection pooling mechanism on deployed systems and an already existing setup to get JDBC connections. I'd like to leverage this to create a MyBatis SqlSession object without creating a Configuration, DataSource, and other things
I have code that already creates a java.sql.Connection object is given the desired resource. I'd like to leverage this and get that SqlSession object and use MyBatis from that point onwards.
I don't want MyBatis to manage connection pooling, determining which data source to use, etc. Is this possible?
I'm afraid you can't avoid creation of the Configuration object. It is used by the internal mybatis machinery like executors. But even if you could it will not help you much. In this case you will need to implement most of Configuration functionality yourself so it does not make sense to do that.
You main goal is to be able to use SqlSessionFactory.openSession(Connection connection) method. To do this you need to have SqlSessionFactory. The easiest way for you is to create Configuration like it is descried in mybatis documentation:
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
// set properties to configuration here
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(configuration);
Now if your connection pool does implement DataSource you use it directly to create environment. If it does not you need to create an adapter around your pool which implements javax.sql.DataSource.
My solution is similar to Roman's above, but I needed to create an Oracle datasource. For various reasons, the connection needs to be created using the Class.forName type sequence
Class.forName("oracle.jdbc.driver.OracleDriver");
String connectionString = "jdbc:oracle:thin:#//yadayada";
String username = "myusername";
String password = "mypassword";
OracleDataSource oracleDataSource = new OracleDataSource();
oracleDataSource.setURL(connectionString);
oracleDataSource.setPassword(password);
oracleDataSource.setUser(username);
environment = new Environment("dev",transactionFactory,oracleDataSource);
configuration = new Configuration(environment);
configuration.addMappers("MyMybatisMapper");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
return sqlSessionFactory.openSession();
What I was missing was the OracleDataSource object.

When should datasource be instantiated in connection pooling

So, I was exploring on how to use connection pooling on java web application. I looked at some tutorials and I am wondering when should I do the context lookup.
Something like this
initContext = new InitialContext();
dataSource = (DataSource) initContext.lookup( "java:/comp/env/jdbc/mysql");
Should it be everytime I get a connection, or should it be a one time thing.
Obviously initialize connection pool one time only, you can do lookup any time required.
Note: The init-context is not creating connection pool

How to retrieve DB connection using DataSource without JNDI?

We want our own db connection configuration instead of using JNDI, but in the meantime, we also want to use DataSource instead of using DriverManager, how to do so?
You use a connection pool library like c3p0 or commons dbcp.
C3P0
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
cpds.setUser("dbuser");
cpds.setPassword("dbpassword");
Connection connection = cpds.getConnection();
DBCP
BasicDataSource ds= new BasicDataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUrl("jdbc:postgresql://localhost/testdb");
ds.setUsername("dbuser");
ds.setPassword("dbpassword");
Connection connection = ds.getConnection();
You can use org.apache.commons.dbcp.BasicDataSource
BasicDataSource ds= new BasicDataSource();
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
ds.setUrl("jdbc:oracle:thin:#dburl:port:sid");
ds.setUsername("uname");
ds.setPassword("pass");

Tomcat6 connect to mySQL problems

I've followed another stackover flow thread to get to this point, it was this one here:
Tomcat6 MySql JDBC Datasource configuration
The problem I have is that the line that goes:
Connection conn = ds.getConnection();
from this block:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
Eclipse gives me the error getConnection() is undefined for the type DataSource.
Its solution is to do this:
Connection conn = ((java.sql.Statement) ds).getConnection();
No tutorials show the need to do this, and its not working when I do that. I'm using mySQL jar named, mysql-connector-java-5.1.18-bin I've used it with RMI before but never Tomcat, is it the correct type for use with Tomcat?
TIA
If I look into the Java API docs http://docs.oracle.com/javase/6/docs/api/ I find the javax.sql.DataSource interface with a getConnection() method. I assume your DataSource to be something else than one implementing the javax.sql.DataSource interface. What "DataSource" is imported?

Categories