I have a register dialog that implements an action listener. If a user enters a name and it already exists, I want to print a message on the console. If the username does not exist, MySQL should add it into the database. Unfortunately this code won't work:
private void regButtonActionPerformed(java.awt.event.ActionEvent evt) {
if(!userBox.getText().equals(""))
{
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/genx", "root", "Warlock1989");
Statement stmt = con.createStatement();
String query = "SELECT name FROM accounts";
ResultSet rs = stmt.executeQuery(query);
while(rs.next())
{
String uname = rs.getString("name");
if(!uname.equals(userBox.getText()))
{
PreparedStatement pstmt = con.prepareStatement("INSERT INTO accounts(name) VALUES(?)");
pstmt.setString(1, userBox.getText());
pstmt.executeUpdate();
System.out.println("Username " + userBox.getText() + " has been registered.");
}
else
{
System.out.println("Username " + userBox.getText() + " already exists.");
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
Your current approach loads all records from database and tries to find the user which will cause memory exceptions if the database consists of huge records. So,
Do not fetch all records from database rather simply run the query using where name=? to check user already exists in the database as shown below:
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
ResultSet rs = null;
try {
String userInput = userBox.getText();
String query = "SELECT name FROM accounts where name=?";
pstmt1 = con.preparedStatement(query);
pstmt1.setString(1, userInput);
rs = pstmt1.executeQuery();
if(rs.next()) {
pstmt2 = con.prepareStatement("INSERT INTO accounts(name) VALUES(?)");
pstmt2.setString(1, userInput);
pstmt2.executeUpdate();
System.out.println("Username " + userInput + " has been registered.");
} else {
System.out.println("Username " + userInput + " already exists.");
}
} catch(SQLException sqlexe) {
//add logging
} finally {
if(pstmt1 != null)
pstmt1.close();
if(pstmt2 != null)
pstmt2.close();
if(rs != null)
rs.close();
}
Your current code does not release the resultsset & preparedstatement objects, so ensure that you are releasing the resources in the finally block.
Related
I have just started with ucanaccess and I am attempting to work out how it works. I wanted to update my Access database's username from "Sutaciba" to "Evan" but it shows the following error:
"Exception occured:
UCAExc:::4.0.4 C:\Users\evanc\AppData\Roaming\IT PAT DataBase (Access is denied)".
Seems like Ucanaccess doesn't have permission to gain access to my database for some reason.
Thank you for any help!
public static void main(String args[])
{
int ID = 1;
String username = "Sutachiba";
String password = "Evanchui123";
String email = "evanchui34#gmail.com";
try
{
Connection conn = DriverManager.getConnection("jdbc:ucanaccess://C:\\Users\\evanc\\AppData\\Roaming\\IT PAT DataBase");
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery("SELECT [username], [password] FROM [tblUser] WHERE ID =" + ID);
while(rs.next())
{
username = rs.getString(1);
password = rs.getString(2);
email = rs.getString(3);
System.out.println("Username: " + username + '\n' + "Password: " + '\n' + "Email:" + email);
}
String newN = "Evan";
String updateQuery = "UPDATE userDB SET (username) = (?) WHERE ID =" + ID;
PreparedStatement st = conn.prepareStatement(updateQuery);
st.setString(1, newN);
st.executeUpdate();
System.out.println("Successfully updated userdata!");
conn.close();
}
catch(Exception ex)
{
System.err.println("Exception occured: ");
System.err.println(ex.getMessage());
}
I have the following function and I am trying to compare the number of students enrolled in a class with the class max. If the number enrolled is greater than the class max, I want to return a message that says, "The Class if Full".
public static void classFullCheck() {
try {
String currentNumberInClassAsString = ("SELECT class_id, COUNT(*) FROM ClassSelector.student_x_class WHERE class_id = " + selectedClass);
rs = myStmt.executeQuery(currentNumberInClassAsString);
int currentNumberInClassAsInt = 0;
if(rs.next()){
currentNumberInClassAsInt = rs.getInt(1);
}
String classSizeAsString = ("SELECT class_size FROM ClassSelector.classes WHERE class_id = " + selectedClass);
rs = myStmt.executeQuery(classSizeAsString);
int classSizeAsInt = 0;
if(rs.next()){
classSizeAsInt = rs.getInt("class_size");
}
if (currentNumberInClassAsInt > classSizeAsInt){
System.out.println("Sorry, this class is Full!");
}
} catch (java.sql.SQLException SQL) {
SQL.printStackTrace();
}
}
I am inserting the classFullcheck() function into the addClass() function like this:
public static void addClass() {
try {
rs = myStmt.executeQuery("SELECT * FROM ClassSelector.classes");
while (rs.next()) {
String availableClasses = rs.getString("class_id") + "\t" + rs.getString("class_name") + "\t" + rs.getString("description");
System.out.println(availableClasses);
}
System.out.println("Enter Class ID from Classes Listed Above to Join: ");
selectedClass = sc.nextLine();
rs = myStmt.executeQuery("SELECT * FROM ClassSelector.classes WHERE class_id = " + selectedClass);
while (rs.next()) {
classFullCheck();
String innerJoin = (userEnterIdAsName + " has been added to " + rs.getString("class_name") + " " + rs.getString("class_id"));
System.out.println(innerJoin);
String student_x_classJoin = "INSERT INTO student_x_class" + "(student_id, student_name, class_id, class_name)" + "VALUES (?, ?, ?, ?)";
PreparedStatement pStmt = con.prepareStatement(student_x_classJoin);
pStmt.setString(1, user_entered_student_id);
pStmt.setString(2, userEnterIdAsName);
pStmt.setString(3, rs.getString("class_id"));
pStmt.setString(4, rs.getString("class_name"));
pStmt.executeUpdate();
System.out.println("Would you like to enroll " + userEnterIdAsName + " into another class? (Y/N)");
String addAdditionalClass = sc.nextLine();
if (addAdditionalClass.equalsIgnoreCase("Y")) {
addClass();
} else if (addAdditionalClass.equalsIgnoreCase("N")) {
return;
}
}
}
catch (java.sql.SQLException SQL) {
System.out.println("Wait, This Student is already enrolled in this class!");
}
}
I am currently just getting both messages printed out, even if a class is not full. Any suggestions would help a lot.
if (currentNumberInClassAsInt >= classSizeAsInt) {
String updateStatus = "Update ClassSelector.classes SET status = ? WHERE class_id = " + selectedClass;
PreparedStatement pStmt = con.prepareStatement(updateStatus);
pStmt.setString(1, "Closed");
pStmt.executeUpdate();
System.out.println("Sorry, this class is Full! Select a different Class:");
System.out.println("\nSign Up For a Class\n");
addClass();
}
I think you want this:
currentNumberInClassAsInt = rs.getInt(2);
instead of:
currentNumberInClassAsInt = rs.getInt(**1**);
I don't think the ResultSet is 0 based...
Also is rs a global variable because it looks like you are changing your ResultSet rs when you call classFullCheck(). You may not have what you think you do in the ResultSet...
rs = myStmt.executeQuery("SELECT * FROM ClassSelector.classes WHERE class_id = " + selectedClass);
while (rs.next()) {
classFullCheck();//****************result set changed here******************
String innerJoin = (userEnterIdAsName + " has been added to " + rs.getString("class_name") + " " + rs.getString("class_id"));
You may think you have this: rs = myStmt.executeQuery("SELECT * FROM ClassSelector.classes WHERE class_id = " + selectedClass); in your result set but you change rs in classFullCheck(). You may want to store the data in a different object that way when you run another query you can still access the data.
I am trying to create a generic method that can add an entry into a SQLite database, using Eclipse and Java.
When the table name is hardcoded it works fine, but when I try to pass in the table name as a string it is giving me a nullPointerException.
below is the method that creates that table:
public static void Table()
{
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:test.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "CREATE TABLE IF NOT EXISTS COMPANY " +
"(ID INT PRIMARY KEY NOT NULL," +
" NAME TEXT NOT NULL, " +
" AGE INT NOT NULL, " +
" ADDRESS TEXT, " +
" SALARY REAL)";
stmt.executeUpdate(sql);
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Table created successfully");
}
and here is the method that inserts an entry into the created table. I want to pass in the table name through the method rather than hard coding it:
public static void Insert(String table, int id, String name, int age, String address, String salary)
{
Connection c = null;
PreparedStatement pstmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:test.db");
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query="INSERT INTO "+table+" (ID,NAME,AGE,ADDRESS,SALARY) VALUES (?,?,?,?,?)";
PreparedStatement stmt = c.prepareStatement(query);
pstmt.setInt(1,id);
pstmt.setString(2,name);
pstmt.setInt(3, age);
pstmt.setString(4, address);
pstmt.setString(5, salary);
pstmt.executeUpdate();
pstmt.close();
c.commit();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Records created successfully");
}
You have small mistake
just you have created two different PreparedStatement object
So change
PreparedStatement stmt = c.prepareStatement(query);
to
pstmt = c.prepareStatement(query);
I have a test JDBC program that tries to alter the Scrollability and Updatability features of a ResultSet. Unfortunately, all the combinations of TYPE_ and CONCUR_ seem to produce the same result (TYPE_SCROLL_INSENSITIVE and CONCUR_READ_ONLY).
Even with the default (TYPE_FORWARD_ONLY) it's possible to scroll through the ResultSet. Can anyone explain why this is?
I am using MySQL 5.6 and JDK7. Here is the code:
public class ResultSetTest3 {
public static void main(String[] args)
{
Connection conn;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/bd", "user", "password");
Statement sta = conn.createStatement();
sta.execute("DELETE FROM test");
sta.close();
PreparedStatement ps = conn.prepareStatement("INSERT INTO test VALUES(?, ?)");
for(int i=1; i<=100; i++)
{
ps.setInt(1, i);
ps.setString(2, "Teste " + i);
ps.addBatch();
}
ps.executeBatch();
ps.close();
System.out.println("TYPE_FORWARD_ONLY CONCUR_READ_ONLY");
result(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
System.out.println("===================================");
System.out.println("TYPE_SCROLL_INSENSITIVE CONCUR_READ_ONLY");
result(conn, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
System.out.println("===================================");
System.out.println("TYPE_SCROLL_SENSITIVE CONCUR_READ_ONLY");
result(conn, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
System.out.println("===================================");
System.out.println("TYPE_FORWARD_ONLY CONCUR_UPDATABLE");
result(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
System.out.println("===================================");
System.out.println("TYPE_SCROLL_INSENSITIVE CONCUR_UPDATABLE");
result(conn, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
System.out.println("===================================");
System.out.println("TYPE_SCROLL_SENSITIVE CONCUR_UPDATABLE");
result(conn, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
System.out.println("===================================");
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void result(Connection conn, int type, int update) throws SQLException
{
Statement sta = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = sta.executeQuery("SELECT * FROM test");
System.out.println(rs.getConcurrency() + " " + update);
System.out.println(rs.getType() + " " + type);
try
{
rs.absolute(10);
System.out.println(rs.getInt(1) + " - " + rs.getString(2));
rs.relative(20);
System.out.println(rs.getInt(1) + " - " + rs.getString(2));
rs.previous();
System.out.println(rs.getInt(1) + " - " + rs.getString(2));
rs.first();
System.out.println(rs.getInt(1) + " - " + rs.getString(2));
try {
System.out.println("AGORA!!!");
Thread.sleep(20000);
} catch (Exception e) {
System.out.println(e);
}
rs.absolute(3);
System.out.println(rs.getInt(1) + " - " + rs.getString(2));
}
catch(SQLException e)
{
System.out.println("Not Scrollable");
}
try
{
rs.next();
rs.next();
rs.next();
rs.next();
rs.deleteRow();
rs.next();
rs.updateString(2, "TesteUpdate");
rs.insertRow();
}
catch(SQLException e)
{
System.out.println("Not Updatable");
}
rs.close();
sta.close();
}
}
As Mark Rotteveel mentions in a comment to the question, MySQL caches ResultSet data by default (also discussed in a blog article by
Ben J. Christensen here). An apparent side-effect of this caching is that MySQL Connector/J will "upgrade" a TYPE_FORWARD_ONLY ResultSet to actually be scrollable:
Statement s = dbConnection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = s.executeQuery("SELECT * FROM testdata");
rs.last();
System.out.println(String.format("Current row number: %d", rs.getRow()));
rs.previous();
System.out.println(String.format("Current row number: %d", rs.getRow()));
displays
Current row number: 3
Current row number: 2
According to the blog article cited above, the way to prevent caching and "stream" the ResultSet data is to use Statement.setFetchSize:
Statement s = dbConnection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
ResultSet rs = s.executeQuery("SELECT * FROM testdata");
rs.next();
System.out.println("Data from first row: " + rs.getString(2));
System.out.println("now let's try rs.last() ...");
try {
rs.last();
System.out.println("... Okay, done.");
} catch (Exception e) {
System.out.println("... Exception: " + e.getMessage());
}
resulting in
Data from first row: Gord
now let's try rs.last() ...
... Exception: Operation not supported for streaming result sets
Try in this way to create a Scroll-Insensitive, read only ResultSet object statement object.
Statement sta = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
instead of
Statement sta = conn.createStatement();
Do the same for PreparedStatement as well.
Through this ResultSet type the cursor can move in any direction. It is insensitive which means result set that does not reflect changes made while it is still open. It is default resultset type for MySql.
Must read Retrieving and Modifying Values from Result Sets
I got problem with this on IFELSE statement
what i should i do? for equals of my position to database ACCESS
. I want to do is if the Admin is correct they show the CP and Staff is correct they show the AS for getting on position to my database.
addStudents AS = new addStudents();
ControlPanel CP = new ControlPanel();
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager
.getConnection("jdbc:odbc:slcvJavaEnrollment");
Statement st = con.createStatement();
ResultSet rs = st
.executeQuery("SELECT * FROM loginUsers where Username='"
+ userTxt.getText() + "' and Password='"
+ passTxt.getText() + "'");
if (rs.getString("Position").contentEquals("Admin")) {
JOptionPane.showMessageDialog(null, "WELCOME ADMIN");
CP.show();
dispose();
con.close();
st.close();
} else if (rs.getString("Postion").contentEquals("Staff")) {
JOptionPane.showMessageDialog(null, "WELCOME STAFF");
AS.show();
dispose();
con.close();
st.close();
}
} catch (Exception e) {
System.out.println(e);
}
Your missing the while (rs.next()) to move the result set to the next result. Try this out. Also as #Learing pointed out, you spelled "Position" wrong in your else if.
while (rs.next()) {
if (rs.getString("Position").contentEquals("Admin")) {
JOptionPane.showMessageDialog(null, "WELCOME ADMIN");
CP.show();
dispose();
con.close();
st.close();
} else if (rs.getString("Position").contentEquals("Staff")) {
JOptionPane.showMessageDialog(null, "WELCOME STAFF");
AS.show();
dispose();
con.close();
st.close();
}
}
EDIT
To prevent SQL injection, you should use a PreparedStatment.
Try this instead of what you have
PreparedStatment pstmt = conn.prepareStatement("SELECT * from loginUsers WHERE Username=? and Password=?");
pstmt.setString(1, userTxt.getText());
pstmt.setString(2, passTxt.getText());
ResultSet rs = pstmt.executeQuery();