So I just finished learning JDBC this weekend and have successfully transferred my code from the main method into an MVC app. The purpose of this application is to hold a roster of players and display a users credentials if requested. The program works great and when I request a url like...
http://localhost:8084/gmustudent/players?id=1
I get the correct output for that player! The problem is I am performing the database connection within my PlayersDAO class and I assume that this is not the "best" way to do this. So I have two questions.
Is there a way to perform the database connection within the web.xml
file or some other file so that when the server is initially started it will
immediately perform the connection to the database and be ready to
query when asked?
And is this actually a better alternative to having the connection in the DAO or would this have unforeseen negative drawbacks. AKA would a constant connection to my database be exactly what I do not want?
Any comments or links would be greatly appreciated. And I'll share the code I currently have for my DAO class so that you can see what I have so far. Thank you all!
package com.jdbc.test;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.DriverManager;
public class PlayersDAO
{
public static Players viewPlayer(int id) throws SQLException
{
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
Players playerObject = null;
try
{
String url = "jdbc:mysql://localhost:3306/gmustudent";
String username = "root";
String password = "root";
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch(ClassNotFoundException error)
{
System.out.println("Error: " + error.getMessage());
}
connection = DriverManager.getConnection(url, username, password);
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM players WHERE id = " + id);
if(resultSet.next())
playerObject = new Players(resultSet.getLong("id"), resultSet.getString("name"), resultSet.getString("position"), resultSet.getString("height"), resultSet.getString("year"), resultSet.getString("hometown"), resultSet.getString("highschool"), resultSet.getString("headshot"));
}
finally
{
if (connection != null) try{connection.close();} catch(SQLException ignore) {}
if (statement != null) try{statement.close();} catch(SQLException ignore) {}
if (resultSet != null) try{resultSet.close();} catch(SQLException ignore) {}
}
return playerObject;
}
}
You can create database connection in web.xml file by using resource. I hope this tutorial will help you.
http://viralpatel.net/blogs/database-connection-pooling-tomcat-eclipse-db/
You can use JDBC Connection Pooling.It can provide significant benefits in terms of application performance, concurrency and scalability.
IMHO, its always a good approach to hide the instantiation details of any resources. You can use factory method to do this. The advantage of this approach is that you can always change the way to manage the resources - e.g. You can have one instance of JDBCConnection per DAO or you can have connection pool. Any time you can provide your development specific db connection, test specific db connection or production db connection. All these details you can hide doing such approach.
Related
This question already has answers here:
Connect Java to a MySQL database
(14 answers)
Closed 1 year ago.
am getting an exception as java.sql.Connection.prepareStatement(String) because con is null, I don't know why as I have already added MySQL Connector jar file.
import java.sql.Connection;
import java.sql.PreparedStatement;
public class Studentdao {
public static boolean insertStudenttoDB(Student st) {
boolean f=false;
try {
Connection con =CP.createc();
//jdbc code
String q="insert into students(sname,sphone scity)values(?,?,?)";
PreparedStatement pstmt=con.prepareStatement(q);
pstmt.setString(1,st.getStudentname());
pstmt.setString(2,st.getStudentcity());
pstmt.setLong(3,st.getStudentphone());
//execute
pstmt.executeUpdate();
f=true;
}
catch(Exception e) {
e.printStackTrace();
}
return f;
}
}
This is my connection program
import java.sql.Connection;
import java.sql.DriverManager;
public class CP {
static Connection con;
//load driver
public static Connection createc() {
try {
Class.forName("com.sql.jdbc.Driver");
//creating connection
String user="mysql";
String password="mysql";
String url="jdbc:mysql://localhost:3306/student_manage";
con=DriverManager.getConnection(url,user,password);
}catch(Exception e) {
e.printStackTrace();
}
return con;
}
}
Incorrect class name
You appear to have an incorrect class name, if you are using the Connector/J product as your JDBC driver.
Section 3.6.1 of the Connector/J manual shows the use of "com.mysql.cj.jdbc.Driver" versus your use of "com.sql.jdbc.Driver". Here is their code example:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
// Notice, do not import com.mysql.cj.jdbc.*
// or you will have problems!
public class LoadDriver {
public static void main(String[] args) {
try {
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
}
}
}
DataSource
Note that your use of Class.forName is generally not needed in modern Java. The JDBC architecture was years ago revamped so that now drivers are automatically located and loaded using the Java Service Provider Interface (SPI) technology.
I do suggest you make a habit of using a DataSource to obtain connections rather than calling on the DriverManager. Using DataSource makes your code much more flexible. You will be able to switch JDBC drivers, add connection pooling, and externalize configuration info (server address, database name, user name, password, etc.) for deployment.
Usually your JDBC driver comes with a basic implementation of DataSource. Check the documentation for all the various options you can set, specific to your database (MySQL in this case).
For MySQL, I understand the implementation of DataSource currently provided in Connector/J is com.mysql.cj.jdbc.MysqlDataSource. Caveat: I make regular use of Postgres & H2, not MySQL, so I may not be up-to-date.
See my Answer to another Question for source code of a full example of connecting and working with MySQL. Here are the parts relating to DataSource and Connection.
private DataSource configureDataSource ( )
{
System.out.println( "INFO - `configureDataSource` method. " + Instant.now() );
com.mysql.cj.jdbc.MysqlDataSource dataSource = Objects.requireNonNull( new com.mysql.cj.jdbc.MysqlDataSource() ); // Implementation of `DataSource` bundled with H2.
dataSource.setServerName( "db-mysql-sfo3-422-do-user-8982-1.x.db.ondigitalocean.com" );
dataSource.setPortNumber( 24_090 );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "scott" );
dataSource.setPassword( "tiger" );
return dataSource;
}
Early in the lifecycle of your app, instantiate and retain the DataSource object returned from that method. Remember, a DataSource holds only the configuration details; it is not an open resource itself, and need not be closed.
DataSource dataSource = this.configureDataSource();
To open a connection, pass the DataSource to your method that wants to connect to the database.
private void dumpTable ( DataSource dataSource ) { … }
Here is a piece of that dumpTable method.
Notice the use of try-with-resources syntax to automatically close the open resources in the order in which they were declared, even in case of failure with exceptions being thrown.
String sql = "SELECT * FROM event_ ;";
try (
Connection conn = dataSource.getConnection() ; // 🡄 Use the passed `DataSource` object to ask for a `Connection` object.
Statement stmt = conn.createStatement() ;
ResultSet rs = stmt.executeQuery( sql ) ;
)
{
…
}
catch ( SQLException e )
{
e.printStackTrace();
}
here's the code I tried to connect java class with mysql. Make sure you have to add the required driver to your libraries.
import java.sql.Connection;
import java.sql.DriverManager;
public class Server {
public static Connection getConnection()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
String urls = "127.0.0.1";//you can even replace this with localhost
String username = "yourusername";
String password = "1234";
Connection conn = DriverManager.getConnection("jdbc:mysql://"+urls+":3306/yourdb?useUnicode=yes&characterEncoding=UTF-8", username, password);
return conn;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
I have a new H2 test DB all setup and have no issue getting to it locally.
I used this site to help https://www.tutorialspoint.com/h2_database/h2_database_jdbc_connection.htm
I took the code and put it up on an Amazon web server and can confirm it is indeed running and can, again, locally add data to it and access it VIA code and the H2 console. The H2 console can even be reached from my remote PC.
Now on my PC I am trying to get to the server VIA JDBC but cannot. Server is even set up for the TCP server.
in the properties file
spring.datasource.url=jdbc.h2.mem.test
In the application.java file, in a try-catch, and it reports the server did start.
Server.createTcp.Server().start();
The DB has a table called testable in there with server columns and test rows. And Again locally and even in the H2 console, I can get to the data no problem.
I tried several ways to list the URL in Java code to get to the server VIA JDBC.
here is the fake URL that I can get to a website hosted there just fine as well as the H2 console.
https://www.mywebsitehostedonamazon.com/h2
I have added this to my code to the connection for the URL.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class H2jdbcCreateDemo {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "org.h2.Driver";
static final String DB_URL = "jdbc:h2:tcp://https://www.mywebsitehostedonamazon.com:8082/test";
// Database credentials
static final String USER = "sa";
static final String PASS = "password";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
// STEP 1: Register JDBC driver
Class.forName(JDBC_DRIVER);
//STEP 2: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//STEP 3: Execute a query
System.out.println("Creating table in given database...");
stmt = conn.createStatement();
String sql = "SELECT * FROM testable LIMIT 1";
stmt.executeUpdate(sql);
System.out.println("Created table in given database...");
// STEP 4: Clean-up environment
stmt.close();
conn.close();
} catch(SQLException se) {
//Handle errors for JDBC
se.printStackTrace();
} catch(Exception e) {
//Handle errors for Class.forName
e.printStackTrace();
} finally {
//finally block used to close resources
try{
if(stmt!=null) stmt.close();
} catch(SQLException se2) {
} // nothing we can do
try {
if(conn!=null) conn.close();
} catch(SQLException se){
se.printStackTrace();
} //end finally try
} //end try
System.out.println("Goodbye!");
}
}
When I run this I receive a Zero length string error for line conn = DriverManager.getConnection(DB_URL,USER,PASS);
If I change up the URL then I get a connection time out. jdbc:h2:tcp://www.mywebsitehostedonamazon.com:8082/test
If I change up the URL then I get a connection time out. jdbc:h2:tcp://www.mywebsitehostedonamazon.com:8082/mem:test
If I change up the URL then I get an error that the Table "testable" not found. jdbc:h2:mem://www.mywebsitehostedonamazon.com:8082/mem:test
Can anyone help out with this?
I have a basic Java application (with a GUI) that uses a linked list to add/remove/modify Customer objects and I want to store them in a database (Oracle DB express to be exact)?
As I understand it, I have to create a table with some tool, and the use that tool to auto-generate a Java class that would allow me to communicate with the DB. How far off am I with this?
Just to make your question clear, What tool have you used to generate your java code?
I recommend you to avoid using code generation tool in case you want to learn in and out of Java.Here is an example of how you can connect your SWING application with Oracle DB,MySQL,Derby and many more other databases.
Connection con;
Statement smt;
ResultSet rs;
String user="databaseuser";
String pass="password";
String path="jdbc:oracle:thin:#localhost:1521:Sampledb"; //put db url here
try{
con=DriverManager.getConnection(path, user, pass);
smt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
String SQL="SELECT *FROM Registered_users_tb "; //Your Query here
rs=smt.executeQuery(SQL);
rs.moveToInsertRow();
//First param is db column name,second param is variable name
rs.updateString("USERNAME", username);
rs.updateString("FNAME", fname);
rs.updateString("MNAME", mname);
rs.updateString("LNAME", lname);
rs.updateString("GENDER", gender);
rs.updateString("DEPARTMENT", dept);
rs.insertRow();
rs.close();
smt.close();
}
catch(SQLException err){
JOptionPane.showMessageDialog(Classname.this,err.getMessage());
}
For creating a complete new database, oracle provide a gui tool called DBCA. I found a couple of links to use this tool: Link 1 and Link 2
This tutorial teaches how to access an Oracle database. For accessing such an database you need additional drivers found here. Here an short example how to access such a database:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
class DatabaseAccess
{
public static void main(String [] args)
{
Connection connection = null;
try
{
Class.forName("oracle.jdbc.OracleDriver");
String dbPath = "jdbc:oracle:thin:#localhost:1521:myDatabase";
String username = "user";
String password = "password";
connection = DriverManager.getConnection(dbPath, username, password);
if(connection != null)
{
System.out.println("Connected with database");
Statement statement = connection.createStatement();
ResultSet results = statementt.executeQuery("SELECT * FROM myTable");
while(result.next())
{
System.out.println(result.getString("myString"));
}
}
catch(ClassNotFoundException | SQLException exc)
{
exc.printStackTrace();
}
finally
{
try
{
connection.close();
}
catch(SqlException exc)
{
exc.printStackTrace();
}
}
}
}
For an more advanced example visit the given link.
I have a site with a MySql Database, and I would like to retrieve the information via a Java Program. The problem is that I'm not sure about how to do it. I have tried a few methods, but none works.
Long story short, I need help with the following :
finding the IP of the server
connecting to the database via IP
creating a new connection with the details
I have tried the following : DriverManager.getConnection("jdbc:mysql://DOMAIN:3306/DB_NAME", "USER", "PASSWORD"); but doesn't work.
Thanks in advanced, and I apologize if the question is stupid, but I have no Java experience with DB's, and I can't understand how can a link between those 2 entities be established.
edit
The Class is the following
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class test {
/**
* #param args
*/
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://IP:3306/DB","USER", "PASS");
Statement statement = connection.createStatement();
ResultSet resultSet = statement .executeQuery("SELECT * FROM `categorii`");
System.out.println( resultSet.getNString(3));
}
catch (Exception M)
{
System.out.println(M.getMessage());
}
}
}
An Exception is thrown which says :
'Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.'
So it can't connect to the server, but I can't see why.
I've always had problems using this:
DriverManager.getConnection("jdbc:mysql://DOMAIN:3306/DB_NAME", "USER", "PASSWORD");
Try this instead
DriverManager.getConnection("jdbc:mysql://DOMAIN:3306/DB_NAME?user=USER&password=PASSWORD");
I have created a simple Java connection script in Java to connect to a database shown below.
import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class dbconn {
public static void main(String[] args) throws ClassNotFoundException
{
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:C:/Program Files (x86)/Spiceworks/db/spiceworks_prod.db");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
try
{
if(connection != null)
connection.close();
}
catch(SQLException e)
{
// connection close failed.
System.err.println(e);
}
}
}
}
Now I have tested this connection via some SQL queries inside the dbconn script and it works.
However my question is, how would Icall this instance of the database into another form in the same project to preform the same SQL queries which are:
ResultSet resultSet = null;
resultSet = statement.executeQuery("SELECT * FROM users");
while (resultSet.next())
{
System.out.println("EMPLOYEE Email: " + resultSet.getString("email"));
}
You can retain and reuse the Connection, saving it probably in some static field. If you access it from multiple threads, SQLite must work in the Serialized mode. You must have the code somewhere to re-establish the connection if it has been lost for some reason.
If the use of Connection is not heavy, you can also have some method that opens it and close when no longer needed, better inside the finally block.