shortening the code JDBC - java

I needed to help shorten this code. My project contains this section 32x. So I want to ask if someone does not know how to simplify and generalize it.
conn[1] = DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD);
{
PreparedStatement stmt = conn[1].prepareStatement("SELECT * FROM nfl.minnesota");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
teamA = rs.getInt("MinnvsAt");
teamB = rs.getInt("AtvsMinn");
ID = rs.getBoolean("MinnvsAtP");
placement();
place();
}
PreparedStatement stmt1 = conn[1].prepareStatement("SELECT SUM(MinnvsAt) FROM nfl.minnesota WHERE MinnvsAtP = TRUE");
ResultSet rs1 = stmt1.executeQuery();
rs1.next();
int SUMPointsAH = rs1.getInt(1);
PreparedStatement stmt2 = conn[1].prepareStatement("SELECT SUM(MinnvsAt) FROM nfl.minnesota WHERE MinnvsAtP = FALSE");
ResultSet rs2 = stmt2.executeQuery();
rs2.next();
int SUMPointsAA = rs2.getInt(1);
PreparedStatement stmt3 = conn[1].prepareStatement("SELECT SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = TRUE");
ResultSet rs3 = stmt3.executeQuery();
rs3.next();
int SUMPointsBH = rs3.getInt(1);
PreparedStatement stmt4 = conn[1].prepareStatement("SELECT SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = FALSE");
ResultSet rs4 = stmt4.executeQuery();
rs4.next();
int SUMPointsBA = rs4.getInt(1);
pointsH.add(SUMPointsAA);
}

You could make your 4 queries, 2 queries with some parameters and extract two helper methods to be more DRY but overall to make your code more robust and readable because your declare too many variables that besides have a too broad scope.
You could write something like :
public int executeMinnvsAtPQuery(String MinnvsAtP){
String query = "SELECT SUM(MinnvsAt) FROM nfl.minnesota WHERE MinnvsAtP = ?";
PreparedStatement stmt = conn[1].prepareStatement(minnvsAtPQuery);
stmt.setString(1, MinnvsAtP);
ResultSet rs = stmt.executeQuery();
rs.next();
return rs.getInt(1);
}
public int executeAtvsMinnQuery(String AtvsMinn){
String query = "SELECT SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = ?";
PreparedStatement stmt = conn[1].prepareStatement(minnvsAtPQuery);
stmt.setString(1, AtvsMinn);
ResultSet rs = stmt.executeQuery();
rs.next();
return rs.getInt(1);
}
And use them in this way :
int SUMPointsAH = executeMinnvsAtPQuery("TRUE");
int SUMPointsAA = executeMinnvsAtPQuery("FALSE");
int SUMPointsBH = executeAtvsMinnQuery("TRUE");
int SUMPointsBA = executeAtvsMinnQuery("FALSE");
Note that the even if the two queries are very close, I don't think that you can make the sum(...) aggregate a parameter valuable by PreparedStatement.
And I would not recommend concatenation of SQL parts that is both error prone and not safe.
My project contains this section 32x.
To reduce this one to 1X, you could follow the same logic and extract the set of these queries in a method with some parameters that you may invoke anywhere then.
Note also that queries execution may have a cost in terms of execution time. So you should also ensure that your queries are optimized and required.

You can cut the actual number of queries executed in half by retrieving both columns at the same time.
You can supply TRUE or FALSE via a parameter.
So the only PreparedStatement you need is SELECT SUM(MinnvsAt), SUM(AtvsMinn) FROM nfl.minnesota WHERE MinnvsAtP = ?.
So you can cut the whole thing in more than half.
As noted by #GriffeyDog, you can do the whole thing in one query, via GROUP BY:
SELECT SUM(MinnvsAt), SUM(AtvsMinn) FROM nfl.minnesota GROUP BY MinnvsAtP ORDER BY MinnvsAtP
So the first row will be the FALSE results and the second row will be the TRUE results, and the first column of each will be SUM(MinnvsAt) and the second SUM(AtvsMinn).
So only one PreparedStatement.executeQuery() needs to be executed.

Related

Most speed way to count rows of a join query

I want to execute the following query in java, through mysql jdbc: SELECT COUNT (*) FROM ORDERS, CUSTOMER WHERE O_ORDEYKEY = O_CUSTKEY
I have this code:
Connection conn = new DatabaseConnection().createMySQLConnection();
int totalRows=0;
for(int j=0;j<tables.size();j++)
{
Statement stmt = null;
ResultSet rs = null;
int rowCount = -1;
try {
conn.setAutoCommit(false);
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tables.get(j)
+ " WHERE O_ORDERKEY = O_CUSTKEY;");
rs.next();
rowCount = rs.getInt(1);
totalRows= totalRows+rowCount;
} finally {
rs.close();
stmt.close();
}
}
But I wanted to run it faster. How can I do this ?
For easier reading you should avoid the old implicit join syntax based on where and use the SQL standard (since 1992) explicit join syntax:
SELECT COUNT (*)
FROM ORDERS
INNER JOIN CUSTOMER ON ORDERS.O_ORDEYKEY = CUSTOMER.O_CUSTKEY
For better performance be sure you have an index on:
table ORDERS column O_ORDEYKEY
table CUSTOMER column O_CUSTKEY

Can have two database connection in one function?

When I debug, I get this error :
Column 'place1' not found.
I was able to verify that it has column place1 in sql.
Is it because I can not have two database connection in one function? I am unsure on how to further debug the problem.
Case.java
System.out.println("The highest value is "+highest+"");
System.out.println("It is found at index "+highestIndex+""); // until now it works fine
String sql ="Select Day from menu where ID =?";
DatabaseConnection db = new DatabaseConnection();
Connection conn =db.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, highestIndex);
ResultSet rs = ps.executeQuery();
if (rs.next())
{
int kb=rs.getInt("Day");
System.out.println(kb);
if(kb==k) // k is a value getting from comboBox
{
String sql1 ="Select * from placeseen where ID =?";
DatabaseConnection db1 = new DatabaseConnection();
Connection conn1 =db1.getConnection();
PreparedStatement ps1 = conn.prepareStatement(sql);
ps.setInt(1, highestIndex);
ResultSet rs1 = ps.executeQuery();
if (rs1.next())
{
String aaa=rs1.getString("place1");
String bbb=rs1.getString("place2");
Tourism to =new Tourism();
to.setPlace1(aaa);
to.setPlace2(bbb);
DispDay dc=new DispDay();
}
ps1.close();
rs1.close();
conn1.close();
}
else
{
System.out.print("N");
System.out.println("Sorry!!!");
}
}
ps.close();
rs.close();
conn.close();
Trace your code to see where you're getting the data. The error is on this line:
String aaa=rs1.getString("place1");
Where does rs1 come from?:
ResultSet rs1 = ps.executeQuery();
Where does ps come from?:
PreparedStatement ps = conn.prepareStatement(sql);
Where does sql come from?:
String sql ="Select Day from menu where ID =?";
There's no column being selected called place1. This query is only selecting a single column called Day.
Maybe you meant to get the result from the second prepared statement?:
ResultSet rs1 = ps1.executeQuery();
There are probably more such errors. Perhaps several (or many) more. Because...
Hint: Using meaningful variable names will make your code a lot easier to follow. ps, ps1, rs1, etc. are very easy to confuse. Name variables by the things they conceptually represent and your code starts to read like a story which can be followed. Variable names like daysQuery and daysResults and placesResults make it more obvious that something is wrong when you try to find a "place" in a variable which represents "days".
In your second query:
PreparedStatement ps1 = conn.prepareStatement(sql);
you are accidentally using the variable sql instead of your previously defined sql1. Replace it and it will be ok.

How to compare Two Resultset Columns values in Java?

Can anyone tell me how I can compare two resultset values? Only getting error in if statement, but the rest is working.
Statement s = con.createStatement();
Statement stmnt = con.createStatement();
String query = "select * from tbl_product";
s.execute(query);
ResultSet rs = s.getResultSet();
while(rs.next())
{
String strOuter=rs.getString(2);
System.out.println(strOuter);
String query1 = "select * from PRODUCTS_AJ";
stmnt.execute(query1);
ResultSet rs1 = stmnt.getResultSet();
while(rs1.next())
{
System.out.println("-------"+rs1.getString(2));
if(rs.getString(2).equals(rs1.getString(2)))// Getting Error here for this line
{
System.out.println("Found");
}
}
}
java.sql.Exception data not found
This types of error occurs when you try to read same column of the same cursor multiple times. And what you encountered is a typical scenario. Just store the string temporarily like bellow:
String col3 = rs1.getString(2);
and use col3 instead of rs1.getString(2), whenever needed.
System.out.println("-------"+ col3);
if(col3.equals(rs1.getString(2)))
{
...
You cannot re-read a column value again. So, copy it in a local variable for logging.
String val = rs1.getString(2);
System.out.println("-------" + val);
if (rs.getString(2).equals(val)) {
What you could possibly do is
use SQL where clause
String query1 = "select * from PRODUCTS_AJ where fieldNmae = 'something'";
ResultSetMetaData rsm = rs.getMetaData();
int colCount = rsm.getColumnCount();
if (colCount > 1)
{
// found
}
For ResultSetMetaData
or possibly do
ResultSet rsOLD = null;
ResultSet rs = s.getResultSet();
// rs will be new ResultSet
while(condition)
{
// check from second row (maintain if case)
.
.
.
// end of loop
rsOLD = rs;
}
Ok ! This is a typical error while using JDBC-ODBC bridge driver with MS Access. I have experienced.I solved it in following way. Retrieving the same data more than once from the result set.
Please try like this
ResultSet rs = s.getResultSet();
String str=rs.getString(2);
Use this string to compare
str.equals(rs2.getString(2)
Thanks!
rs.getSting(2) is executed the number of row times of rs1 in the while loop of rs1. You may not have the that many number of rows in rs as rs1.

java ResultSet overwrite

I seem to be having some issues with my result sets I have named them differently but they both seem to have the same data in but I can't figure it out why.
String query = "SELECT * FROM blog_comments;";
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
int colNum = rsmd.getColumnCount();
boolean more = rs.next();
String query2 = "SELECT * FROM blog_entries;";
ResultSet rs2 = stmt.executeQuery(query2);
ResultSetMetaData rsmd2 = rs2.getMetaData();
int colNum2 = rsmd2.getColumnCount();
boolean more2 = rs2.next();
I have looked in debugging and they both have the same columns but i don't think they should have any suggestions.
you need a new Statement to instantiate your new ResultSet.
Statement st1 = Conn.CreateStatement();
Statement st2 = Conn.CreateStatement();
ResultSet rs1 = st1.executeQuery();
ResultSet rs2 = st2.executeQuery();
From Statement API.
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects. All execution methods in the Statement
interface implicitly close a statment's current ResultSet object if an
open one exists.

Java JDBC Query with variables?

String poster = "user";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM `prices` WHERE `poster`="+poster);
This does not work.Any tips or tricks would be appreciated.
Try surrounding the poster variable with single quotes, like this:
ResultSet rs = stmt.executeQuery("SELECT * FROM `prices` WHERE `poster`='"+poster+"'");
That's because SQL expects strings to be surrounded by single quotes. An even better alternative would be to use prepared statements:
PreparedStatement stmt = con.prepareStatement("SELECT * FROM `prices` WHERE `poster` = ?");
stmt.setString(1, poster);
ResultSet rs = stmt.executeQuery();
It's recommended using PreparedStatement since the way you are currently building the query (by concatenating strings) makes it easy for an attacker to inject arbitrary SQL code in a query, a security threat known as a SQL injection.
1) In general, to "parameterize" your query (or update), you'd use JDBC "prepared statements":
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
2) In your case, however, I think all you need to do is add quotes (and lose the back-quotes):
// This is fine: no back-quotes needed
ResultSet rs = stmt.executeQuery("SELECT * FROM prices");
// Since the value for "poster" is a string, you need to quote it:
String poster = "user";
Statement stmt = con.createStatement();
ResultSet rs =
stmt.executeQuery("SELECT * FROM prices WHERE poster='" + poster + "'");
The Statement interface only lets you execute a simple SQL statement with no parameters. You need to use a PreparedStatement instead.
PreparedStatement pstmt = con.prepareStatement("
select * from
prices where
poster = ?");
pstmt.setString(1, poster);
ResultSet results = ps.executeQuery();

Categories