I am connecting to a mysql database using the DataSource object.
DataSource mysql = (DataSource) context.lookup("jdbc/MySQLDataSource");
Connection conn = mysql.getConnection();
I want to set the property
rewriteBatchedStatements=true
for when I am doing some batch uploads. I have seen examples how to do this when people are using a driver manager like below:
String myConnectionString =
"jdbc:mysql://localhost:3307/mydb?" +
"useUnicode=true&characterEncoding=UTF-8" +
"&rewriteBatchedStatements=true";
try (Connection con = DriverManager.getConnection(myConnectionString, "root", "whatever"))
How do I go about setting this property using the DataSource?
Adding to #aguibert answer, you can configure the same at global level as well, by editing the url of your Resource name as below:
<Resource name="jdbc/MySQLDataSource" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3307/mydb?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8"
username="root"
password="root"
maxActive="100"
maxIdle="20"
maxWait="10000"/>
If you cast your datasource to the specific implementation you're using, you will be able to use all the get/set methods specific to the jdbc driver you are using.
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
//...
MysqlDataSource mysql = (MysqlDataSource) context.lookup("jdbc/MySQLDataSource");
mysql.setRewriteBatchedStatements(true);
Connection conn = mysql.getConnection();
See this link for reference: http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
I have fixed this by doing the following steps:
DataSource datasource = (DataSource) context.lookup("jdbc/MySQLDataSource");
MysqlDataSource mysql_datasource = datasource.unwrap(MysqlDataSource.class);
mysql_datasource.setRewriteBatchedStatements(true);
Connection conn = mysql.getConnection();
Everything worked smoothly then. This extra unwrap() call was needed because I was attempting this on glassfish. Check the answer by aguibert below for further information.
Related
I am trying to implement Apache Tomcat's built-in JDBC connection pool. But I am confused with many things.
There are 2 methods mentioned in official page to initialize connection pool.
One using JNDI lookup and another by java PoolProperty class.
For JNDI lookup, we have to add entry to context.xmlor server.xml and initilize it in the java code. This require database connection details to be hardcoded.
For pool properties, we have to set various connection attributes in PoolProperty class using the datasource object. Does it require instantiating factory? (org.apache.tomcat.jdbc.pool.DataSourceFactory)
Whenever a try using pool properties, I am getting the error:
SEVERE: Unable to create initial connections of pool.
java.sql.SQLException: invalid arguments in call at
oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
I checked and confirmed all properties are correct. This error goes once I use the xml method. Can someone help me the correct way to configure pooling without xml?
This standalone java code gives me error:
PoolProperties p = new PoolProperties();
String dburl="jdbc:oracle:thin:#(DESCRIPTION=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=hostname) (PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=shostname2)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=Service)))";
p.setUrl(dburl);
p.setDriverClassName("oracle.jdbc.OracleDriver");
p.setUsername(username);
p.setPassword(pwd);
p.setJmxEnabled(true);
p.setTestWhileIdle(false);
p.setTestOnBorrow(true);
p.setValidationQuery("SELECT 1 from dual");
p.setTestOnReturn(false);
p.setValidationInterval(30000);
p.setTimeBetweenEvictionRunsMillis(30000);
p.setMaxActive(100);
p.setInitialSize(10);
p.setMaxWait(10000);
p.setRemoveAbandonedTimeout(600);
p.setMinEvictableIdleTimeMillis(30000);
p.setMinIdle(10);
p.setLogAbandoned(true);
p.setRemoveAbandoned(true);
p.setJdbcInterceptors(
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
+ "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");
p.setLogValidationErrors(true); datasource = new org.apache.tomcat.jdbc.pool.DataSource( );
datasource.setPoolProperties(p);
When I add A global Resource to Server.xml as below,it is working.
Resource auth="Container" description="User database that can be
updated and saved"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
name="jdbc/database" type="javax.sql.DataSource"/>
Please Help me to understand, what's the correct way of implementation.
I have created java web application in eclipse with database mysql.But now i have to deploy that web application in tomcat server.I know how to deploy web application without databas but need assistance with database.
Thank you in advance.
There are two main ways to obtain JDBC connections within a Java Web Application.
Retrieve a connection from a DataSource registered in a JNDI directory service within the container.
Creating a Connection manually within your application code.
JNDI
Using JNDI requires a connection pool to be created within tomcat. This can be done within the context.xml file in tomcat's config directory.
Example Context.xml Entry
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="org.hsql.jdbcDriver"
url="jdbc:HypersonicSQL:database"
maxActive="8"
maxIdle="4"/>
This connection would then be retrieved in your code as follows:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)
envCtx.lookup("jdbc/EmployeeDB");
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();
Manual Creation
Manually creating the connection within your code is simpler, however JNDI is recommended for its portability.
Manual Example
public class MysqlConnect{
public static void main(String[] args) {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/";
String dbName = "jdbctutorial";
String driver = "com.mysql.jdbc.Driver";
String userName = "root";
String password = "root";
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,userName,password);
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When deploying for either of these scenarios it is important that you have the appropriate JDBC driver in your classpath.
There are 2 scenarios here:
You define the connection directly in the code using simple JDBC and Class.forName() - in that case you just need to make sure the jar containing the driver is in the classpath and it should work.
This is the preferred method - Define a Datasource on the server and call it in the code by using the JNDI API:
InitialContext ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("jdbc/testDS");
conn = ds.getConnection();
in contex.xml using -- tag we can connect to any db
I know how to specific datasource connection pooling to a mysql server in Tomcat 7, add
<Resource type="javax.sql.DataSource"
name="jdbc/TestDB"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mysql"
username="mysql_user"
password="mypassword123"
/>
to my META-INF/context.xml,
Can anyone show me how to do this to Microsoft Access?
Do I need a JDBC - ODBC bridge to make connection from my Java web app to Microsoft Access?
UPDATE: This is my attempt, but I ran into SQLException
<Resource type="javax.sql.DataSource"
name="jdbc-odbc/qtl"
maxActive="100"
maxIdle="30"
maxWait="10000"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="sun.jdbc.odbc.JdbcOdbcDriver"
url="jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb)};DBQ=/Users/KingdomHeart/resources/db.mdb"
/>
When I do this, I got WARNING: Unexpected exception resolving reference
java.sql.SQLException: sun.jdbc.odbc.JdbcOdbcDriver
UPDATE 2:: I tried to write a separate program in effort to make connection to Microsoft Access db. I got java.lang.ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver Here is my code. It must be that I need a jar driver in my class path, do I not?
public static void main(String[] args) {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String fileName = "/Users/KingdomHeart/resources/MyTable.mdb";
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=";
database += fileName + ";DriverID=22;READONLY=true";
Connection con = DriverManager.getConnection(database, "", "");
System.out.println("here");
} catch (SQLException ex) {
Logger.getLogger(TestJdbcOdbc.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(TestJdbcOdbc.class.getName()).log(Level.SEVERE, null, ex);
}
}
I'd use a URL like this:
jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\\path\\your-access-database.mdb
The JDBC driver class is sun.jdbc.odbc.JdbcOdbcDriver (at least it was when I last used it; that was back in 2004).
I prefer this style because it eliminates the step of creating an ODBC data source. It keeps the precise location of the file inside the Java deployment.
Yes, you need the JDBC-ODBC bridge (unless you bought a commercial JDBC driver).
You should be aware of the pitfalls of using Access in a multi-user environment:
http://msdn.microsoft.com/en-us/library/aa167840(v=office.11).aspx
My personal recommendation would be to use MySQL or PostgreSQL instead of Access.
Here's something else you might want to read about setting up a JNDI data source on Tomcat:
http://craicpropagation.blogspot.com/2009/02/how-to-use-same-jndi-resource-name-on.html
This is my context.xml file:
...
<Resource auth="Container"
driverClass="net.sourceforge.jtds.jdbc.Driver"
type="com.jolbox.bonecp.BoneCPDataSource"
idleMaxAge="240"
idleConnectionTestPeriod="60"
partitionCount="3"
acquireIncrement="1"
maxConnectionsPerPartition="10"
minConnectionsPerPartition="3"
statementsCacheSize="50"
releaseHelperThreads="4"
name="jdbc/MyDatasource"
username="my_username"
password="my_password"
factory="org.apache.naming.factory.BeanFactory"
jdbcUrl="jdbc:jtds:sqlserver://localhost:12345/my_database"
/>
...
I already tried using ServletContext.getResource(java.lang.String) with the name of the resource ("jdbc/MyDatasource"), but Tomcat complains that the name doesn't begin with a '/'. I also tried with "/jdbc/MyDatasource", but this time it returns null.
I mainly need the jdbcUrl to perform a connection check with the database server (see if the server is online and operational).
Keyword is: JNDI. The resources in the context.xml are not 'System Resources' but JNDI Resources.
Try this:
InitialContext ic = new InitialContext();
// that's everything from the context.xml and from the global configuration
Context xmlContext = (Context) ic.lookup("java:comp/env");
DataSource myDatasource = (DataSource) xmlContext.lookup("jdbc/MyDatasource");
// now get a connection to see if everything is fine.
Connection con = ds.getConnection();
// reaching this point means everything is fine.
con.close();
You should be able to access the datasource with the following code:
Context initialContext = new InitialContext();
Context envContext = (Context)initialContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/MyDatasource");
I'm trying to follow Java's JDBC tutorials to write a Java program that can connect to SQL Server 2008. I'm getting lost at the point of making a connection.
The following snippet is from the tutorial:
InitialContext ic = new InitialContext();
DataSource ds = ic.lookup("java:comp/env/jdbc/myDB");
Connection con = ds.getConnection();
DataSource ds = (DataSource) org.apache.derby.jdbc.ClientDataSource()
ds.setPort(1527);
ds.setHost("localhost");
ds.setUser("APP")
ds.setPassword("APP");
Connection con = ds.getConnection();
There's no explanation of what comp/env/jdbc/myDB should point to, and I don't know how I should choose a port. Also, the object ds seems to be defined twice.
I'm using the JSQLDataSource driver, for the record. Can anyone point me in the right direction here?
http://java.sun.com/docs/books/tutorial/jdbc/basics/connecting.html
I'm not sure anyone above has really answered the question.
I found this microsoft sample useful.
The key information in there is really that the class you need is SQLServerDataSource
that is basically a configuration object - you use it something like this:
SQLServerDataSource dataSource = new SQLServerDataSource();
dataSource.setUser("aUser");
dataSource.setPassword("password");
dataSource.setServerName("hostname");
dataSource.setDatabaseName("db");
You would then call
dataSource.getConnection();
to get a connection object which is basically the thing you use to talk to the database.
Use
connection.prepareStatement("some sql with ? substitutions");
to make something for firing off sql and:
connection.prepareCall
for calling stored procedures.
Start with the JDBC tutorial or the Microsoft docs.
and this:
String driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
Class.forName(driver);
String url = "jdbc:microsoft:sqlserver://host:1433/database";
Connection conn = DriverManager.getConnection(url, "username", "password");
Fill in your values for host, database, username, and password. The default port for SQL server is 1433.
UPDATE: Good point below. JDBC drivers can be had from both Microsoft and jTDS. I prefer the latter.
JNDI lookups have to do with Java EE app servers that support connection pooling. You can ask the app server to create a pool of connections, which can be an expensive thing to do, and loan them out to clients like library books as needed.
If you aren't using a Java EE app server or connection pooling, you have to create the connection on your own. That's where manual processes and DriverManager come in.
EXPLANATION: As for why the Sun tutorial shows DataSource twice, I'd say it's a case of poor editing. If you look above the code sample it says you can get a DataSource "by lookup or manually". The code snippet below shows both together, when it should be one or the other.
You know it's an inadvertent error because there's no way the code as written could compile. You have "ds" declared twice.
So it should read "...lookup", followed by its code snippet, and then "...manually", followed by its code snippet.
I like the jTDS driver for connecting to SQL Server. A URL will look like this:
jdbc:jtds:sqlserver://localhost/Finance;instance=sqlexpress
Check this for jTDS Url Info.
This also has some interesting information to help troubleshoot jtds to sql express sorts of problems.
DataSource ds = new SimpleDriverDataSource(new com.mysql.jdbc.Driver(),
"jdbc:mysql://database:1433;databaseName=name", "username", "password");
JdbcTemplate jdbc = new JdbcTemplate(ds);
This question has already been answered long time ago. The question was asked about JNDI lookup. With lookup you have to see the application server log to see what the connection is bound to. For example in Jboss startup, I can see:
[ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=myDB' to JNDI name 'java:myDB'
Using that name=myDB you lookup
InitialContext ic = new InitialContext();
DataSource ds = ic.lookup("java:myDB");
Notice how the server log and the code both point to the JNDI name java:myDB.