This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I am new so bear with me. But I am getting a NullPointerException somewhere in here. Any ideas? Thanks!
private void loadInstructors()
{
// get all account numbers from database
try
{
//myResultSet = myStatement.executeQuery( "SELECT DISTINCT lastname FROM InstEval" );
myResultSet = myStatement.executeQuery( "SELECT DISTINCT TEAMNAME FROM APP.TEAMEVAL" );
// add account numbers to accountNumberJComboBox
while ( myResultSet.next() )
{
//instructorComboBox.addItem( myResultSet.getString( "lastname" ) );
TeamsComboBox.addItem( myResultSet.getString( "TEAMNAME" ) );
}
myResultSet.close(); // close myResultSet
} // end try
catch ( SQLException exception )
{
exception.printStackTrace();
}
}
Here is one way to do what you seem to want; note, I've attempted to generalize a few things here. Firstly, you should use descriptive method names (if you want team names, mention team names). Secondly, you should return appropriate types (and you're doing a distinct query) so we should return a Set - I picked a sorted set, but that's not in anyway mandatory. Next, I chose to pass the Connection object into the method. It's a good idea to close resources in the block that opens them, and thusly I only close the PreparedStatement and ResultSet objects. Finally, if you don't keep your comments updated with your code they are worse then useless.
// I think sorting the team names is good idea, and they're distinct...
private SortedSet<String> getTeamNames(Connection conn) {
// Let's use a Set!
SortedSet<String> teamNames = new TreeSet<String>();
// get all team names from database, at least store the query in a local
// String variable. You should probably extract it to a properties file.
final String query = "SELECT DISTINCT TEAMNAME FROM APP.TEAMEVAL";
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(query);
rs = ps.executeQuery();
// add team names to teamNames
while (rs.next()) {
teamNames.add(rs.getString("TEAMNAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return teamNames;
}
Related
I have tried this so many times but I never did it, this is my code
public static Boolean checkhaveguild(String name) {
try {
Statement statement = connection.createStatement();
PreparedStatement ps = connection.prepareStatement("SELECT * FROM guild");
System.out.println(statement.execute("SELECT * FROM guild WHERE name = "+name+""));
System.out.println("----------");
} catch (SQLException e) {
throw new RuntimeException(e);
}
return false;
}
I am doing a guild plugin on BungeeCord and getting data from MySQL
The code is about checking if the row does not exist and output to boolean
I'd suggest you to learn more about the basics of programming in Java! Minecraft is a great way to start into programming, but you should be interested in doing things properly.
public static boolean hasGuild(String name) {
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
statement = connection.prepareStatement("SELECT COUNT(name) FROM guild WHERE name = ?");
statement.setString(1, name);
resultSet = statement.executeQuery();
if (resultSet.next()) return resultSet.getInt(1) > 0;
} catch (SQLException e) {
// TODO properly handle exception
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
// TODO properly handle exception
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
// TODO properly handle exception
}
}
}
return false;
}
Some thoughts on what this code is doing:
Asking the database for the number of rows whose name column matches the given string. Always make sure that you only request the data that's necessary for your purpose. Requesting all columns with their data is overkill if you only want to answer if there are any rows or not.
If the number of rows is greater than zero, it'll return true, because there are rows with a matching name column.
Some thoughts you should make yourself:
What is contained in the name column? If it's the guild's name, then that's fine, but if that's the player's name you should consider re-thinking your code. Player's in Minecraft can change their name and hence would lose their guild on your server. Players in Minecraft are uniquely identified by their UUID, which will never change. Maybe consider using the UUID then!
In order for the query to be as fast a possible you should set an INDEX on the name column. That will speed up the lookup proccess even if there are plenty of rows!
Nevertheless: Welcome to StackOverflow! I hope that I could help you and I wish lot's of fun with programming.
in the try, i try sout resultSet and statement before close and it send this to me
resultSet :
com.mysql.cj.jdbc.ClientPreparedStatement: SELECT COUNT(name) FROM guild WHERE name = 'a'
statement :
com.mysql.cj.jdbc.ClientPreparedStatement: SELECT COUNT(name) FROM guild WHERE name = ** NOT SPECIFIED **
and return false is my test at last it will return true if it have if not it will return false
I'm new in database and sql, and just trying to figure it all out in Java, but I got stuck with some minor problem, I'm trying to remove one record in db, with id that is given as method parameter, like this, but it's not working
#Override
public void removeCustomer(int number) {
Statement statement = null;
try {
statement = connection.createStatement();
statement.executeUpdate("DELETE FROM Customers WHERE id='number'");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try{
if(statement != null) statement.close();
} catch (SQLException e ) {
e.printStackTrace();
}
}
}
It does work, when I write in SQL query " ... WHERE id='2'";
But I want to be able to pass the number from method parameter.
Anyone could help?
You can use PreparedStatement like so :
try(PreparedStatement stm = connection.createStatement("DELETE FROM Customers WHERE id=?")){
stm.setInt(1, number);
stm.executeUpdate();
}
//.. catch and finally
Note
It does work, when I write in SQL query " ... WHERE id='2'";
If in case your id is a varchar you can pass a string to the statement by using setString instead of setInt, but I don't suggest to use string for id
This question already has an answer here:
Closing ResultSet in Java 7 [duplicate]
(1 answer)
Closed 5 years ago.
This question should be simple and it may annoy , but still I got this doubt about closing of Result Set using Java. It should be done for each statement or result set should be closed only in final?
try {
Class.forName(<driver class>);
con = DriverManager.getConnection(
"IP",
"username",
"password");
for(String dealId : items) {
String sql= "SQL Query";
preparedStatement = con.prepareStatement(sql);
rs = preparedStatement.executeQuery();
while(rs.next()) {
count += rs.getInt("total");
}
// Result should be closed here as the statement got executed?
}
System.out.println(count);
if(items.size() == count) {
dealsBelongToTheParty = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
rs.close(); // Or this is right?
preparedStatement.close();
if(!con.isClosed())
con.close();
}
I suggest to use Java 7 try-with-resources
(the code below assumes that the loop var dealId is used in the query)
Class.forName(<driver class>);
try (Connection con = DriverManager.getConnection(
"IP", "username", "password")) {
for(String dealId : items) {
String sql= "SQL Query with " + dealId;
// resources are opened by order
try (PreparedStatement preparedStatement = con.prepareStatement(sql);
ResultSet rs = preparedStatement.executeQuery()) {
while(rs.next()) {
count += rs.getInt("total");
}
} // resources are implicitly closed in reverse order of open
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(count);
if(items.size() == count) {
dealsBelongToTheParty = true;
}
https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
"A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results."
So, you shouldn't worry about closing ResultSet.
I have a code that reads from an SQL Database and saves each column of information into an ArrayList. I need to pass each ArrayList into a separate class where I can store the lists as single pieces of information (IE: Information in the first part of ArrayList1 goes with information in the first part of ArrayList2 etc...) and then sort them. I don't know how to pass that information to another class though. This is a section of my main method that stores the information into a list. I need this information passed to a separate class called List.java:
String SelectStatement1 = "SELECT InvoiceID FROM Invoice;";
ps = conn.prepareStatement(SelectStatement1);
rs = ps.executeQuery();
int count = 0;
while (rs.next()){
count++;
}
ps.close();
ps = conn.prepareStatement(SelectStatement1);
rs = ps.executeQuery();
ArrayList<String> InvoiceIDList = new ArrayList<String>();
String InvoiceID = null;
int p = 0;
while (p < count){
rs.next();
InvoiceID = rs.getString("InvoiceID");
InvoiceIDList.add(InvoiceID);
p++;
}
ps.close();
p = 0;
Edit: This is only a section of my code, I already have the code open and close the connections, I only need information on how to pass the ArrayList to another class for sorting.
Create a method in your other class like this:
public void receiveList (ArrayList<String> invoiceIDList) {
// Do something with invoiceIDList data
}
It may not be a bad idea to create a constructor in your "List" class, that accepts the ArrayList and creates the class instance with the required data
Also, please change the name of that class!! It will be confusing to others who read your code, as you are passing an ArrayList already!
EDIT:
You could also have your class implement the List interface, which would make things a lot easier for you, because you can insert data into your class based on the position of the data in the ArrayList.
public class yourClass implements List<String> {
// Your class methods and variables...
}
If you wanted to expand on this to allow more than just Strings, you can change to: List<T>, this would give you a more generic approach.
First, I suggest you perform a SELECT COUNT() instead of iterating your rows in your first query. Then remember to close() both the PreparedStatement and ResultSet. Finally, I would suggest you program to the List<String> interface. Putting it all together like,
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
Connect to your database and initialize conn.
int count = 0;
try {
String query1 = "SELECT COUNT(InvoiceID) FROM Invoice;";
ps = conn.prepareStatement(query1);
rs = ps.executeQuery();
if (rs.next()) {
count = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (Exception ignored) {
}
try {
ps.close();
} catch (Exception ignored) {
}
}
The above block of code is necessary to close() both rs and ps in the correct order with the finally Block.
List<String> invoiceIdList = new ArrayList<>();
try {
String query2 = "SELECT InvoiceID FROM Invoice;";
ps = conn.prepareStatement(query2);
rs = ps.executeQuery();
while (rs.next()) {
invoiceIdList.add(rs.getString("InvoiceID"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally { // <-- it's identical to the finally block above.
try {
rs.close();
} catch (Exception ignored) {
}
try {
ps.close();
} catch (Exception ignored) {
}
}
// now you can pass invoiceIdList elsewhere...
if (!invoiceIdList.isEmpty()) {
doSomething(invoiceIdList);
}
Here is my problem, I need to select data, but the data may be a lot so need to select the total results as well, so i need to call PreparedStatement twice for the same fields. I don't want to repeatedly write the same code twice, so I want put PreparedStatement into a different method. See ex:
public Order getOrders(){
Connection myCon = null;
PreparedStatement preparedStmt=null;
try{
myCon =getUnusedConnection();
String sql="select * from order where name=? ....... limit 0,3";
preparedStmt=myCon.prepareStatement(sql);
getOrderPreparedStatement(name,....);
ResultSet results=preparedStmt.executeQuery();
int rowCount=0;
while(results.next()){
......
rowCount++;
}
if(rowCount==3){
String sql2="select count(*) from Order where name=?....";
preparedStmt=myCon.prepareStatement(sql);
getOrderPreparedStatement(name,....);
ResultSet results2=preparedStmt.executeQuery();
if(results2){
int totalRow=....;
}
}
}
catch (SQLException ex) {
while (ex != null) {
System.out.println ("SQL Exception: " +
ex.getMessage ());
ex = ex.getNextException ();
}
}catch (java.lang.Exception e) {
System.out.println("***ERROR-->" + e.toString());
}
finally {
closeStatement(preparedStmt);
releaseConnection(myCon);
}
return null;
}
public void getOrderPreparedStatement(PreparedStatement preparedStmt, String name....)
{
try{
preparedStmt.setString(name);
... a lot of set field here....
}
catch (SQLException ex) {
while (ex != null) {
System.out.println ("SQL Exception: " +
ex.getMessage ());
ex = ex.getNextException ();
}
}catch (java.lang.Exception e) {
System.out.println("***ERROR-->" + e.toString());
}
finally {
closeStatement(preparedStmt); // do i need to close Statement in finally here
}
}
Is it a good practice to put Connection in 1 method & PreparedStatement in a seperated method. If it is ok to do that then "do i need to closeStatement in finally in getOrderPreparedStatement method?"
Or can u suggest a better solution?
Although it is definitely a good idea to move the code for repeated tasks into a method, you need to be very careful when deciding how much code to reuse.
Specifically, in your example you should not attempt to close the statement in the finally clause, because the statement that you prepare would be unusable outside the getOrderPreparedStatement.
One thing that you could do differently is dropping the exception-handling code from the method. This would keep the logic inside the method cleaner, so your readers would have easier time understanding your intentions. This would also reduce code duplication, because currently the code inside the catch (SQLException ex) block is identical.