Unable to retrieve data from database through JDBC query - java

I trying to make a connection to my DDBB in order to print all the columns from a table but I keep getting Null.
I have checked the connection parameters and everything seems correct.
I'm thinking that maybe there is something wrong with my query statement:
public List<Palabra> getTodos() throws SQLException {
SQLConexion con = new SQLConexion();
listaPalabras = new ListaPalabras();
if(con.ConectarBasedeDatos()) {
try{
Statement stmt = con.getConnection().createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM PALABRA");
while(rs.next()) {
Palabra pal = new Palabra(rs.getInt("idPalabra"), rs.getString("palabra"), rs.getInt("dificultad")); //These are the columns that I need to print.
listaPalabras.addPalabra(pal); //adding the results to the list
}
}
catch(Exception e)
{
System.out.println(e);
}
}
else {
return null;
}
con.DesconectarBasedeDatos();
return listaPalabras.getListaPalabras();
}

I managed to solve the problem by adding the MySQL Connector to the libraries so indeed there was no connection with the database because of this.
Novice error.
Thanks a lot for your time.

Related

Can’t print tables from a database with JDBC

I'm trying to figure out how to get this piece of code, initially made for MySQL, to work with (Microsoft) SQL Server.
When it's called, it's supposed to print out the flight destinations stored as tables in the database, (dbo.) London, (dbo.) NewYork etc. But right now, it won't print anything, no errors either.. I’m using the default MSSQL schema name, dbo.
public void viewFlights(Connection conn) throws SQLException {
String SCHEMA_NAME="${dbo}";
try {
DatabaseMetaData metaData = conn.getMetaData();
String[] tableType = {"TABLE"};
ResultSet rs = metaData.getTables(null, SCHEMA_NAME, null, tableType);
while (rs.next()) {
String tableName = rs.getString(3);
System.out.println(tableName);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
Any idea what I've missed here?
Either set a default scheme for you database or
Use Schema name as
String SCHEMA_NAME="{schema.dbo}";
Solved by David Browne's comment!

How to save the results of a query on variables for each field on Java?

I need to accomplish the following:
1.- Save on different variables each field of a query result (Oracle DB).
The query result could be 1 o more rows (5 average).
2.- Invoke a WebService for each row.
4.- Wait for the WebService answer and then repeat the process.
I think that saving the result of 1 row and then invoke the WebService it easy but the problem is when the query result throws more than 1 row.
How can I do this? Is Arraylist the answer?
EDIT: I am using the following code. How can I print the arraylist to see if the connection is working?
If I run this i get:
com.packagename.SomeBean#1d251891
com.packagename.SomeBean#48140564
com.packagename.SomeBean#58ceff1
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
List<SomeBean> v = new ArrayList<SomeBean>();
String query = "select * from table where ROWNUM BETWEEN 1 and 3";
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:user/pass#localhost:port:SID");
stmt = con.createStatement();
rs = stmt.executeQuery(query);
while( rs.next() ){
SomeBean n = new SomeBean();
n.setColumn1(rs.getInt("column1"));
n.setColumn2(rs.getString("column2"));
n.setColumn3(rs.getString("column3"));
n.setColumn4(rs.getInt("column4"));
n.setColumn5(rs.getString("column5"));
n.setColumn6(rs.getString("column6"));
n.setColumn7(rs.getString("column7"));
...
v.add(n);
}
for(SomeBean s : v){
System.out.println(s);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Answering to your question is quite difficoult.
But I can give you some hints.
Your startpoint is JDBC.
The Java Database Connectivity (JDBC)
The Java Database Connectivity (JDBC) API is the industry standard for database-independent connectivity between the Java programming language and a wide range of databases SQL databases and other tabular data sources, such as spreadsheets or flat files. The JDBC API provides a call-level API for SQL-based database access.
The Java Database Connectivity (JDBC)
Once you are able to establish a connection to the DB, this snippet can help you answering to your question.
// start connection
List<SomeBean> v = new ArrayList<SomeBean>();
Statement st;
try
{
st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
while( rs.next() ){
SomeBean n = new SomeBean();
n.setFirstField(rs.getInt("firstfield"));
n.setSecondField(rs.getString("secondfield"));
...
...
v.add(n);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
// close connection
Once you have your collection of beans, just write a for loop that calls the webservice one time for each bean.
for(SomeBean s : v){
callToYouWS(s);
}

JDBC optimize MySql request on Multithread

I'm building a webcrawler and I'm looking for the best way to handle my requests and connection between my threads and the database (MySql).
I've 2 types of threads :
Fetchers : They crawl websites. They produce url and add they into 2 tables : table_url and table_file. They select from table_url
to continue the crawl. And update table_url to set visited=1 when they
have read a url. Or visited=-1 when they are reading it. They can
delete row.
Downloaders : They download files. They select from table_file. They update table_file to change the Downloaded column. They never
insert anything.
Right now I'm working with this :
I've a pool of connection based on c3p0.
Every target (website) have thoses variables :
private Connection connection_downloader;
private Connection connection_fetcher;
I create both connection only once when I instanciate a website. Then every thread will use thoses connections based on their target.
Every thread have thoses variables :
private Statement statement;
private ResultSet resultSet;
Before every Query I open a SqlStatement :
public static Statement openSqlStatement(Connection connection){
try {
return connection.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
And after every Query I close sql statement and resultSet with :
public static void closeSqlStatement(ResultSet resultSet, Statement statement){
if (resultSet != null) try { resultSet.close(); } catch (SQLException e) {e.printStackTrace();}
if (statement != null) try { statement.close(); } catch (SQLException e) {e.printStackTrace();}
}
Right now my Select queries only work with one select (I never have to select more than one for now but this will change soon) and is defined like this :
public static String sqlSelect(String Query, Connection connection, Statement statement, ResultSet resultSet){
String result = null;
try {
resultSet = statement.executeQuery(Query);
resultSet.next();
result = resultSet.toString();
} catch (SQLException e) {
e.printStackTrace();
}
closeSqlStatement(resultSet, statement);
return result;
}
And Insert, Delete and Update queries use this function :
public static int sqlExec(String Query, Connection connection, Statement statement){
int ResultSet = -1;
try {
ResultSet = statement.executeUpdate(Query);
} catch (SQLException e) {
e.printStackTrace();
}
closeSqlStatement(resultSet, statement);
return ResultSet;
}
My question is simple : can this be improved to be faster ? And I'm concerned about mutual exclusion to prevent a thread to update a link while another is doing it.
I believe your design is flawed. Having one connection assigned full-time for one website will severly limit your overall workload.
As you already have setup a connection pool, it's perfectly okay to fetch before you use (and return afterwards).
Just the same, try-with-catch for closing all your ResultSets and Statements after will make code more readable - and using PreparedStatement instead of Statement would not hurt as well.
One Example (using a static dataSource() call to access your pool):
public static String sqlSelect(String id) throws SQLException {
try(Connection con = dataSource().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT row FROM table WHERE key = ?")) {
ps.setString(1, id);
try(ResultSet resultSet = ps.executeQuery()) {
if(rs.next()) {
return rs.getString(1);
} else {
throw new SQLException("Nothing found");
}
}
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}
Following the same pattern I suggest you create methods for all the different Insert/Update/Selects your application uses as well - all using the connection only for the short time inside the DB logic.
I can not see a real advantage to have all the Database stuff in your webcrawler threads.
Why don't you use a static class with the sqlSelect and sqlExec method, but without the Connection and ResultSet parameters. Both connection objects are static as well. Make sure the connection objects are valid befor using them.

jdbc performance

There are thee tables inside my database. One is employee, the second is employee_Project, and the third is employee_Reporting. Each table has a common employee_Number as its primary key, and there is a one to many relationship among them such that an employee has many projects and reporting dates.
I have run select * from employee, select * from employee_project, select * from employee_reporting in three data holder classes which have methods fillResultSet(Result set) and List<T> getData(). This is based on a SqlDbEngine class with a runQuery(PreparedStatement,DataHolder) method, and the implementation has been completed.
Now I have to design a getAllEmployee() method along with project and reporting detail with optimal code in java using JDBC. I have used an iterator but this solution is not acceptable; now I have to use a foreach loop.
This is what I have done:
public List<Employee> getAllEmployees() {
EmployeeDataHolderImpl empdataholder = new EmployeeDataHolderImpl();
List<Employee> list_Employee_Add = null;
try {
Connection connection = mySqlDbConnection.getConnection();
PreparedStatement preparedStatement = connection
.prepareStatement(GET_ALL_EMPLOYEE_DETAILS);
mySqlDBEngineImpl.runQuery(preparedStatement, empdataholder);
} catch (SQLException e) {
e.printStackTrace();
}
for (Employee employee : empdataholder.getData()) {
new EmployeeDAOImpl().getProject(employee);
new EmployeeDAOImpl.getReport(employee);
}
list_Employee_Add = empdataholder.getData();
return list_Employee_Add;
}
and make another method
public void getProject(Employee emp) {
EmployeeProjectDataHolderImpl employeeProjectHolder = new EmployeeProjectDataHolderImpl();
try {
Connection connection = mySqlDbConnection.getConnection();
PreparedStatement preparedStatement = connection
.prepareStatement(GET_ALL_PROJECT_DETAILS);
mySqlDBEngineImpl
.runQuery(preparedStatement, employeeProjectHolder);
} catch (SQLException e) {
e.printStackTrace();
}
for (EmployeeProject employee_Project : employeeProjectHolder.getData()) {
if (employee_Project.getEmployeeNumber() == emp.getEmpNumber()) {
emp.getProjects().add(employee_Project);
}
}
}
public void getReport(Employee emp) {
EmployeeReportDataHolderImpl employeeReportHolder = new EmployeeReportDataHolderImpl();
try {
Connection connection = mySqlDbConnection.getConnection();
PreparedStatement preparedStatement = connection
.prepareStatement(GET_ALL_REPORT_DETAILS);
mySqlDBEngineImpl
.runQuery(preparedStatement, employeeReportHolder);
} catch (SQLException e) {
e.printStackTrace();
}
for (EmployeeReport employee_Report : employeeReportHolder.getData()) {
if (employee_Report.getEmployeeNumber() == emp.getEmpNumber()) {
emp.getProjects().add(employee_Project);
}
}
}
}
and same for Employee Reporting but doing, this performance is going to decrease.no body worry about closing connection i will do it
Please tell me how I could improve my solution..
There are some issue with your code.
1.you are initializing EmployeeDAOImpl everytime, rather you can just keep one instance and call the operations over it.
new EmployeeDAOImpl().getProject(employee); new
EmployeeDAOImpl.getReport(employee);
2.I don't see where you close your connection after performing an SQL operation.
You should be having
try {
--code statements
}
catch(SQLException e){
e.printStackTrace();
}
finally{
-- close your connection and preparedStatement
}
Closing database connections is very vital.
If you use your actual code, you will have 3 impacts in your code:
You're opening a connection to get the employee's data.
For every employee, you open (and close) a new connection to get his projects.
For every employee, you open (and close) a new connection to get his reports.
Note that opening a new connection is a performance hit on your application. It doesn't matter if you use an enhanced for-loop or an Iterator, there would be many hits that can slow down your application.
Two ways to solve this problem:
Open a single connection where you run all your select statements. This will be better than opening/closing lot of connections.
Create a single SQL statement to retrieve the employees and the data you need for every employee. It will have better performance for different reasons:
A single connection to the database.
A single query instead of lot of queries to the database (a single I/O operation).
If your rdbms allows it, the query will be optimized for future requests (a single query instead of multiple queries).
I would prefer to go with the second option. For this, I tend to use a method that executes any SQL select statement and return a ResultSet. I'll post a basic example (note, the provided code can be improved depending on your needs), this method could be in your SqlDbEngine class:
public ResultSet executeSQL(Connection con, String sql, List<Object> arguments) {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = con.prepareStatement(sql);
if (arguments != null) {
int i = 1;
for(Object o : arguments) {
pstmt.setObject(i++, o);
}
}
//method to execute insert, update, delete statements...
rs = pstmt.execute();
} catch(SQLException e) {
//handle the error...
}
return rs;
}
And this other method to handle all the query operation
public List<Employee> getAllEmployee() {
Connection con = null;
ResultSet rs = null;
List<Employee> lstEmployee = new ArrayList<Employee>();
try {
con = mySqlDbConnection.getConnection();
//write the sql to retrieve all the data
//I'm assuming these can be your columns, it's up to you
//this can be written using JOINs...
String sql = "SELECT E.EMPLOYEE_ID, E.EMPLOYEE_NAME, P.PROJECT_NAME, R.REPORT_NAME FROM EMPLOYEE E, PROJECT P, REPORT R WHERE E.EMPLOYEE_ID = P.EMPLOYEE_ID AND E.EMPLOYEE_ID = R.EMPLOYEE_ID";
//I guess you don't need parameters for this...
rs = SqlDbEngine.executeSQL(con, sql, null);
if (rs != null) {
Employee e;
int employeeId = -1, lastEmployeeId = -1;
while (rs.next()) {
//you need to make sure to create a new employee only when
//reading a new employee id
employeeId = rs.getInt("EMPLOYEE_ID");
if (lastEmployeeId != employeeId) {
e = new Employee();
lastEmployeeId = employeeId;
lstEmployee.add(e);
}
Project p = new Project();
Report r = new Report();
//fill values of p...
//fill values of r...
//you can fill the values taking advantage of the column name in the resultset
//at last, link the project and report to the employee
e.getProjects().add(p);
e.getReports().add(r);
}
}
} catch (Exception e) {
//handle the error...
} finally {
try {
if (rs != null) {
Statement stmt = rs.getStatement();
rs.close();
stmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
//handle the error...
}
}
return lstEmployee;
}
Note that the second way can be harder to code but it will give you the best performance. It's up to you to improve the provided methods, some advices:
Create a class that receives a ResultSet and builds a Project instance using the columns name of the ResultSet (similar for Report and Employee).
Create a method that handles the ResultSet and its Statement close.
As a best practice, never use select * from mytable, it's preferable to write the needed columns.
If I understand correctly, your code first loads all EmployeeReport rows and then filters them according to getEmployeeNumber(). You can let your database do this by modifying your SQL query.
Since you didn't show your SQL queries (I assume they're in GET_ALL_REPORT_DETAILS), I'll just make a guess... Try executing SQL like:
select *
from employee_reporting
where employeeNumber = ?
If you put this in a PreparedStatement, and then set the parameter value, your database will only return the data you need. For example:
PreparedStatement pstmt = con.prepareStatement(GET_ALL_REPORT_DETAILS);
pstmt.setInt(1, employee.getEmployeeNumber());
That should return only the EmployeeReport records having the desired employeeNumber. In case performance is still an issue, you could consider adding an index to your EmployeeReport table, but that's a different story...

How to check if a particular database in MySQL already exists using Java

I am new to JDBC, and I wanted to find out if there is a way to check if a particular database already exists in MySQL.
Let's say I wanted to create a database named students. If the students database is already created in MySQL an error message in Eclipse would state that this students database already exists. However, I wanted to create a Boolean method to check if students database already exists. If it exists then the Boolean method would return false, otherwise if it’s true, then I can create the students database.
How do I do these in Java? Are there any methods in JDBC that does this or do I need to code it from scratch?
I followed mguymons suggestion and this is what I came up:
public boolean checkDBExists(String dbName) {
try {
Class.forName(JDBCDriver); // Register JDBC driver
System.out.println("Creating a connection...");
conn = DriverManager.getConnection(DBURL, USER, PASS); // Open a connection
ResultSet resultSet = conn.getMetaData().getCatalogs();
while (resultSet.next()) {
String databaseName = resultSet.getString(1);
if(databaseName.equals(dbName)) {
return true;
}
}
resultSet.close();
}
catch(Exception e) {
e.printStackTrace();
}
return false;
}
You can get that information from a JDBC Connection using getCatalogs. Here is an example of getting the Catalogs, aka Database names
// Connection connection = <your java.sql.Connection>
ResultSet resultSet = connection.getMetaData().getCatalogs();
// Iterate each catalog in the ResultSet
while (resultSet.next()) {
// Get the database name, which is at position 1
String databaseName = resultSet.getString(1);
}
resultSet.close();
show databases like 'students'
If you get a row back, it exists.
In newer versions of MySQL (5 and above) run this query:
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '[database name]'
AND table_name = '[table name]';
If the result is 1 it exists.
In Java JDBC that would look something like this:
// Create connection and statement
String query = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema'[database name]' AND table_name = '[table name]'";
ResultSet rs = stmt.executeQuery(query);
rs.next();
boolean exists = rs.getInt("COUNT(*)") > 0;
// Close connection, statement, and result set.
return exists;
You're doing it back to front. The correct technique is to try to create it and catch the exception. The way you want to do it is subject to timing-window problems: it wasn't there when you tested, but it was there when you tried to create it. And you still have to catch the exception anyway.
You should break out of the loop once the target database is found. Otherwise, it's only sensible if your target search is the last in the result set.
public boolean checkDBExists(String dbName) {
try {
Class.forName(JDBCDriver); // Register JDBC Driver
System.out.println("Creating a connection...");
conn = DriverManager.getConnection(DBURL, USER, PASS); // Open a connection
ResultSet resultSet = conn.getMetaData().getCatalogs();
while (resultSet.next()) {
String databaseName = resultSet.getString(1);
if(databaseName.equals(dbName)) {
return true;
break;
}
}
resultSet.close();
}
catch(Exception e) {
e.printStackTrace();
}
return false;
}

Categories

Resources