I am new to java and i have written the following:
package mypackage;
public class DBconnection {
Connection con = null;
public Connection getConnection() throws Exception, SQLException
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#zzz:1521:zzz","zzz", "zzz");
}
catch(Exception e)
{
}
return con;
}
public void removeConnection() throws SQLException
{
con.close();
}
}
When I am accesing the above code in a jsp page i have written following:
DBconnection dbconnect = new DBconnection();
dbconnect.getConnection();
I want to erite dbconnect.con.prepareStatement......("sql query here");// but error is coming as con is not public in mypackage.DBconnection ; cannot be accessed outside package
dbconnect.con is not accessible why????? I have declared variable con in public in the above code. Error is coming as con is not public in mypackage.DBconnection ; cannot be accessed outside package, how to resolve this??? please help me
In the code posted above, con is package visible and not public. That is why you get the message cannot be accessed outside package. To make it public you have to write
public Connection con = null;
Note that if you are just going to call
dbconnect.con.prepareStatement
you might end up with a NullPointerException, since con is only initialized in the getConnection() method. So I would advise to use the getter you created
dbconnect.getConnection().prepareStatement
Of course, the getter would need to be adjusted to only create a new connection when con is still null. Otherwise it can just return con directly. The removeConnection should then after closing the connection set con to null, otherwise calling the getConnection after calling removeConnection would return a closed connection, which is pretty useless
move this code to the constructor
public DBconnection(){
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#zzz:1521:zzz","zzz", "zzz");
}
catch(Exception e)
{
}
}
then make one object of it and share it to all your application classes and when you want to use connection just call getConnecion() from his object
Related
I'm wondering if anyone can shed some light on this topic, as I have been racking my brain for days and can't quite understand why this does not work. I have three classes
main, RetrieveDBVersion,GetOracleConnection I've been doing some testing with oracle JDBC, UCP and Java 1.7.
According to the Oracle documentation, If I use connection pooling the connection will be returned to the pool as soon as I close the connection, Invalidate it and set it to null See Here. So I decided to give it a whirl and see if it would perform just like the documentation says it should. In my Main application I have a simple loop which makes a connection 200 times by calling RetrieveDBVersion. RetrieveDBVersion is simply performing a query and returning the driver version. My loop works fine until I hit the magic number of 68 and then I receive an error which states
java.sql.SQLException: Exception occurred while getting connection:
oracle.ucp.UniversalConnectionPoolException:
Cannot get Connection from Datasource: java.sql.SQLException:
Listener refused the connection with the following error:
ORA-12516, TNS:listener could not find available handler with matching protocol stack
These are the detail of the 3 methods. These methods are not in a server environment. They are simply calling a local oracle express database and I'm running them from my desktop. Why would I keep getting this error? If I'm returning the connections back to the pool?
Main
import com.jam.DB.JDBCVersion;
import static java.lang.System.out;
public class MainApp {
public static void main(String[] args) {
String myMainJDBCVar;
try{
for(int i=1; i<200; i++ )
{
myMainJDBCVar= JDBCVersion.RetrieveDBVersion();
out.println(myMainJDBCVar + " " + i);
}
out.println("this is Done!");
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
RetrieveDBVersion
import java.sql.*;
import oracle.ucp.jdbc.ValidConnection;
public class JDBCVersion {
public static String DBVersion;
public static String RetrieveDBVersion()throws SQLException {
Connection conn = JDBCConnection.GetOracleConnection("test");
try {
DatabaseMetaData meta = conn.getMetaData();
//get driver info
System.out.println("JDBC driver version is " + meta.getDriverMajorVersion());
DBVersion = meta.getDriverVersion();
} catch (SQLException e) {
e.printStackTrace();
DBVersion = e.getMessage();
}
finally {
System.out.println("hit the finally clause");
((ValidConnection) conn).setInvalid();
conn.close();
conn=null;
}
return DBVersion;
}
GetOracleConnection
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;
import java.sql.*;
public class JDBCConnection {
public static Connection GetOracleConnection(String Enviroment) throws SQLException{
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
Connection conn = null; //ora.defaultConnection();
try {
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
pds.setURL("jdbc:oracle:thin:#//localhost:1521/xe");
pds.setUser("system");
//pds.setInitialPoolSize(5);
pds.setPassword("xxx");
pds.setMaxStatements(10);
conn = pds.getConnection();
return conn;
}
catch(Exception e){
e.printStackTrace();
}
return conn;
}
So after careful though and getting a little extra help from the Oracle forum. I finally understand why the above referenced code is giving the error message that I'm receiving. See Here For Response
Because I'm setting the data source everytime the loop goes around, I'm essentially creating more than one pool. The way to do this, is create one pool and than pull connections from that pool.
New code to replace the GetOracleConnection I created a singleton class for datasource and in code I simply retrieve the connection from the data source like such
Connection conn = Database.getInstance().GetPoolSource().getConnection();
package com.jam.DB;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;
public class Database {
private static Database dbIsntance;
private static PoolDataSource pds;
private Database() {
// private constructor //
}
public static Database getInstance() {
if (dbIsntance == null) {
dbIsntance = new Database();
}
return dbIsntance;
}
public PoolDataSource GetPoolSource() {
if (pds == null) {
pds = PoolDataSourceFactory.getPoolDataSource();
try {
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
pds.setURL("jdbc:oracle:thin:#//localhost:1521/xe");
pds.setUser("system");
pds.setPassword("xxxx");
pds.setMaxStatements(15);
return pds;
} catch (Exception e) {
}
return pds;
}
return pds;
}
}
I have got a program this way:
public void MethodOne()
{
String sqlquery = "select * from vendor_items where category_id = 1 ";
PreparedStatement consildatedPst = connection.prepareStatement(sqlquery);
ResultSet consilatedReslset = consildatedpst.executeQuery();
while(consilatedReslset.next())
{
String name = consilatedReslset.getString("name");
if(name!=null)
{
MethodTwo();
}
}
}
public void MethodTwo(String name)
{
String sqlquery2 = "select ename from Vendor where name=?";
PreparedStatement otherPst = connection.prepareStatement(sqlquery2);
otherPst.setString(1,name);
}
This is the way connection is established (Later I will go for Connection Pooling).
public class DBConnection {
public static Connection getDBConnection() {
String sURL="jdbc:mysql://localhost:3306/oms";
String sUserName="root";
String sPwd="";
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(sURL, sUserName,sPwd);
return conn;
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return conn;
}
}
My question is Can I use the same connection object when calling within Methods??
Yes, you can.
When you do:
connection.prepareStatement(sqlquery2);
It creates a new statement object using the same connection. So the ResultSets that you obtain from them will belong to different Statements and will be different and there will be NO PROBLEM for you.
In short: Different Statements manage different ResultSets. If you get 2 ResultSets from the same Statement when you get the second one the first one will be dropped but if you have 2 Statements you can manage 2 ResulSets without problem (while the connection is open, of course)
Only if you aren't using the connection in multiple threads or nesting your own methods. In other words, no. Use a new connection per method. To avoid overhead use a connection pool.
I am new to javaEE and trying to make database connection. I can do it but i think my way of doing it is inefficient. Here is what i do:
static String dbUrl="jdbc:mysql://localhost:3306/Bank";
static String username="root";
static String password="";
static Connection con=null;
public static void connect ()
{
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con=(Connection) DriverManager.getConnection(dbUrl,username,password);
System.out.println("Connected!");
}
catch (Exception e) {
e.printStackTrace();
System.out.println("not connected");
}
}
public void someFunctiontoConnectToDB{
try {
connect();
DO_THE_QUERY.....etc
}
}
Here is my problem, this method works fine, but i have to duplicate the same code whenever i try to connect to DB in another servlet or managed bean. I tried to create a class for connection and pass the Connection c as the parameter, but this time when it returns from the connection class, Connection object becomes null. Is there any other way i can make connection easier, and without code duplication?
Thanks
If it is possible try to get into JPA, it makes life much easier.
But if you are stuck with JDBC, here is a good approach for abstracting and encapsulating the Database Layer Core J2EE Patterns - Data Access Object
In a summary for your case I would do something like this:
The DAOFactory:
class MySqlDAOFactory {
static String dbUrl="jdbc:mysql://localhost:3306/Bank";
static String username="root";
static String password="";
static private Connection con;
public static void createConnection() {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con=(Connection) DriverManager.getConnection(dbUrl,username,password);
System.out.println("Connected!");
}
catch (Exception e) {
e.printStackTrace();
System.out.println("not connected");
}
}
public static BankDAO getBankDAO() {
return new BankDAO(con);
}
}
And the BankDAO:
class BankDAO {
Connection con;
public BankDAO(Connection con) {
this.con = con;
}
public Account getAccountFor(String name) {
//JDBC Operations
return acc;
}
}
In your Managed Bean or Servlet:
public void someFunction() {
MySqlDAOFactory.createConnection();
BankDAO dao = MySqlDAOFactory.getBankDAO();
//get other DAOs
Account acc = dao.getAccountFor("bob");
}
You can create a class that will connect to database and make a method return the connection.
When you want to use connection in other classes, you simply call that method.
Or else what you can do is
Create a ServletContextListener
Add database connection code in the listener.
Add a method to return connection
Use it whenever required.
I'm trying to setup a thread that loops every 100ms with every iteration querying a table in a SQL database. Here is what I have in my public static void main class. How can I define the connection outside of the listener and only call the query in the loop?
// Database credentials
final String url = "jdbc:mysql://192.168.0.0/";
final String db = "db";
final String driver = "com.mysql.jdbc.Driver";
final String table = "table";
public final Connection conn = null;
// Define listner
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
System.out.println("Reading Info.");
try {
Class.forName(driver);
try {
conn = DriverManager.getConnection(url+db,"root","pass");
Statement st = (Statement) conn.createStatement();
String sql = "";
st.executeUpdate(sql);
conn.close();
} catch (SQLException s) {
s.printStackTrace();
JOptionPane.showMessageDialog(null, "ERROR: Please try again!");
}
} catch (ClassNotFoundException cnfe){
JOptionPane.showMessageDialog(null, "ERROR:");
}
}
};
Timer timer = new Timer( 100 , taskPerformer);
timer.setRepeats(true);
timer.start();
Thread.sleep(100);
}
Right now it's giving me the following error:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problem:
The final local variable conn cannot be assigned, since it is defined in an enclosing type
You don't want to. Connections are not thread safe per JDBC specification. Hence there is no reason or justification for Connection variable not being local to the thread. Why isn't it?
Now that you have an answer to your non-proximate issues, let me complement that with your proximate issue. You have this: public final Connection conn = null; which makes no sense. You have assigned null to a final variable. You may have added final because the compiler complained you are using a non-final variable in an inner class. What you probably want to achieve is a lazily initialized singleton. Remove the final modifier and then write a separate synchronized function that retrieves the connection and initializes it as needed:
private Connection conn;
private synchronized Connection connection() {
if (conn == null) conn = createConnection();
return conn;
}
Of course, you'd better make sure that you never use the connection concurrenly, but your use case doesn't call for that. Another issue with this naive approach to connection pooling are connections left in an invalid state.
I am new to Java and NetBeans, and I am attempting to create a form that
connects to a database using JDBC connection
reads information from seven columns and displays them on a jTable component already on the form
I already have this working. I am now trying to optimize my code and use a better architecture to separate the database connection and the user interface (UI forms) code so that I can have a separate class to perform the connection and then simply call the method from this class in the code behind the button. The problem with using NetBeans and forms is that I don't know where to instantiate this class and such. Below is a cope of the class that I have created to perform the JDBC connection
public class ConnectionManager {
private static String url = "jdbc:mysql://localhost:3306/prototypeeop";
private static String driverName = "com.mysql.jdbc.Driver";
private static String username = "root";
private static String password = "triala";
private static Connection con;
private static String url;
public static Connection getConnection() {
try {
Class.forName(driverName);
try {
con = DriverManager.getConnection(url, username, password);
} catch (SQLException ex) {
// log an exception. fro example:
System.out.println("Failed to create the database connection.");
}
} catch (ClassNotFoundException ex) {
// log an exception. for example:
System.out.println("Driver not found.");
}
return con;
}
}
This is already a .java file. I have a JForm, and I need to call this method behind the button. Here is how I do it in the form currently without using a connection class:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
DefaultTableModel model=(DefaultTableModel)jTable1.getModel();
model.setRowCount(0);
String sql="Select * from eopdata";
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con=(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/prototypeeop","root","jakamuga");
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())
{
String Year=rs.getString("Year");
String Month=rs.getString("Month");
String Day=rs.getString("Day");
String MJD=rs.getString("MJD");
Double xarcsec=rs.getDouble("xarcsec");
Double yarcsec=rs.getDouble("yarcsec");
Double UT1UTCsec=rs.getDouble("UT1UTCsec");
model.addRow(new Object[] { Year, Month, Day, MJD,xarcsec,yarcsec,UT1UTCsec});
}
}
catch(Exception e) {
JOptionPane.showMessageDialog(this, e.getMessage());
}
How can I use the class instead of hard coding in the connection? I have already created the class but where do I instantiate it. Do I do it in the main of the form or do I do it in the actionevent code with the following code?
private Connection con = null;
private Statement stmt = null;
private ResultSet rs = null;
con = ConnectionManager.getConnection();
stmt = con.createStatement();
rs = stmt.executeQuery(sql);
To literally answer your question: your getConnection method is a public static method so you can call this from anywhere. Just call ConnectionManager.getConnection() where-ever you need that connection.
Some other remarks about your code:
You shouldn't query a database in the actionPerformed method. This method is called on the EDT, and doing a database query and looping over the results is a long-running task. Doing this task on the EDT will block your UI. Consult the Concurrency in Swing tutorial for more info about Swing and threading
Consider caching the Connection object
Do not forget to close your resources. If I remember correctly, a ResultSet must be closed afterwards. Do this in a finally block