Java methods to add and authenticate users in MySQLphp one-time prepared statement execution functionThoughts on organizing code for multiple mysql queries in php scriptsAvoid duplicate conditional checks in multiple boolean conditionsMySQL Java in JTableCode Golf challenge that plays MafiaQuerying Facebook for details of a user's OAuth tokenImplementation of stackJava MySQL handler for a Minecraft modJava JDBC: MySQL database-wrapperAuthenticate users in Django

Coupling two 15 Amp circuit breaker for 20 Amp

Why did Starhopper's exhaust plume become brighter just before landing?

What does it mean to move a single flight control to its full deflection?

Fantasy Macro Economics: What would Merfolk trade for?

How can I reply to people who accuse me of putting people out of work?

How do I portray irrational anger in first person?

Why is 3/4 a simple meter while 6/8 is a compound meter?

If the UK Gov. has authority to cancel article 50 notification, why do they have to agree an extension with the EU

Inspiration for failed idea?

Is the internet in Madagascar faster than in UK?

STM32 cannot reach individual registers and pins as PIC

Why did Lucius make a deal out of Buckbeak hurting Draco but not about Draco being turned into a ferret?

Board Chinese train at a different station (on-route)

Can a network vulnerability be exploited locally?

How to investigate an unknown 1.5GB file named "sudo" in my Linux home directory?

Did the Apollo Guidance Computer really use 60% of the world's ICs in 1963?

Was a six-engine 747 ever seriously considered by Boeing?

Principal payments

Are sweatpants frowned upon on flights?

Are there any to-scale diagrams of the TRAPPIST-1 system?

Drawing probabilities on a simplex in TikZ

Are spot colors limited and why CMYK mix is not treated same as spot color mix?

Do application leftovers have any impact on performance?

Term used to describe a person who predicts future outcomes



Java methods to add and authenticate users in MySQL


php one-time prepared statement execution functionThoughts on organizing code for multiple mysql queries in php scriptsAvoid duplicate conditional checks in multiple boolean conditionsMySQL Java in JTableCode Golf challenge that plays MafiaQuerying Facebook for details of a user's OAuth tokenImplementation of stackJava MySQL handler for a Minecraft modJava JDBC: MySQL database-wrapperAuthenticate users in Django






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








5












$begingroup$


I'm going through some code and trying to figure out how to get rid of duplicates from the following two methods. Both methods execute a simple login/register query to a local MySQL DB. I couldnt figure out a good design pattern to solve my problem, especially to get rid of the duplicate try-catch.



Any advice?



public class DatabaseHandler 

[...]

public static boolean checkLogin(String username, String password)
Connection connection = createConenction();
PreparedStatement statement = null;

String query = "select * from users where username = ? and password = ? ";

try
statement = connection.prepareStatement(query);
statement.setString(1, username);
statement.setString(2, password);
ResultSet result = statement.executeQuery();
return result.next(); //True if User exists
catch(SQLException e)
return false;
finally
try
statement.close();
catch (SQLException e)
e.printStackTrace();




public static boolean registerUser(String username, String password)
Connection connection = createConenction();
PreparedStatement statement = null;

String query = "insert into users (username, password) values (?, ?)";

try
statement = connection.prepareStatement(query);
statement.setString(1, username);
statement.setString(2, password);
statement.executeUpdate();
return true;
catch(SQLException e)
return false;
finally
try
statement.close();
catch (SQLException e)
e.printStackTrace();




```









share|improve this question











$endgroup$




















    5












    $begingroup$


    I'm going through some code and trying to figure out how to get rid of duplicates from the following two methods. Both methods execute a simple login/register query to a local MySQL DB. I couldnt figure out a good design pattern to solve my problem, especially to get rid of the duplicate try-catch.



    Any advice?



    public class DatabaseHandler 

    [...]

    public static boolean checkLogin(String username, String password)
    Connection connection = createConenction();
    PreparedStatement statement = null;

    String query = "select * from users where username = ? and password = ? ";

    try
    statement = connection.prepareStatement(query);
    statement.setString(1, username);
    statement.setString(2, password);
    ResultSet result = statement.executeQuery();
    return result.next(); //True if User exists
    catch(SQLException e)
    return false;
    finally
    try
    statement.close();
    catch (SQLException e)
    e.printStackTrace();




    public static boolean registerUser(String username, String password)
    Connection connection = createConenction();
    PreparedStatement statement = null;

    String query = "insert into users (username, password) values (?, ?)";

    try
    statement = connection.prepareStatement(query);
    statement.setString(1, username);
    statement.setString(2, password);
    statement.executeUpdate();
    return true;
    catch(SQLException e)
    return false;
    finally
    try
    statement.close();
    catch (SQLException e)
    e.printStackTrace();




    ```









    share|improve this question











    $endgroup$
















      5












      5








      5


      1



      $begingroup$


      I'm going through some code and trying to figure out how to get rid of duplicates from the following two methods. Both methods execute a simple login/register query to a local MySQL DB. I couldnt figure out a good design pattern to solve my problem, especially to get rid of the duplicate try-catch.



      Any advice?



      public class DatabaseHandler 

      [...]

      public static boolean checkLogin(String username, String password)
      Connection connection = createConenction();
      PreparedStatement statement = null;

      String query = "select * from users where username = ? and password = ? ";

      try
      statement = connection.prepareStatement(query);
      statement.setString(1, username);
      statement.setString(2, password);
      ResultSet result = statement.executeQuery();
      return result.next(); //True if User exists
      catch(SQLException e)
      return false;
      finally
      try
      statement.close();
      catch (SQLException e)
      e.printStackTrace();




      public static boolean registerUser(String username, String password)
      Connection connection = createConenction();
      PreparedStatement statement = null;

      String query = "insert into users (username, password) values (?, ?)";

      try
      statement = connection.prepareStatement(query);
      statement.setString(1, username);
      statement.setString(2, password);
      statement.executeUpdate();
      return true;
      catch(SQLException e)
      return false;
      finally
      try
      statement.close();
      catch (SQLException e)
      e.printStackTrace();




      ```









      share|improve this question











      $endgroup$




      I'm going through some code and trying to figure out how to get rid of duplicates from the following two methods. Both methods execute a simple login/register query to a local MySQL DB. I couldnt figure out a good design pattern to solve my problem, especially to get rid of the duplicate try-catch.



      Any advice?



      public class DatabaseHandler 

      [...]

      public static boolean checkLogin(String username, String password)
      Connection connection = createConenction();
      PreparedStatement statement = null;

      String query = "select * from users where username = ? and password = ? ";

      try
      statement = connection.prepareStatement(query);
      statement.setString(1, username);
      statement.setString(2, password);
      ResultSet result = statement.executeQuery();
      return result.next(); //True if User exists
      catch(SQLException e)
      return false;
      finally
      try
      statement.close();
      catch (SQLException e)
      e.printStackTrace();




      public static boolean registerUser(String username, String password)
      Connection connection = createConenction();
      PreparedStatement statement = null;

      String query = "insert into users (username, password) values (?, ?)";

      try
      statement = connection.prepareStatement(query);
      statement.setString(1, username);
      statement.setString(2, password);
      statement.executeUpdate();
      return true;
      catch(SQLException e)
      return false;
      finally
      try
      statement.close();
      catch (SQLException e)
      e.printStackTrace();




      ```






      java mysql authentication jdbc






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 16 at 20:44









      200_success

      136k21 gold badges173 silver badges443 bronze badges




      136k21 gold badges173 silver badges443 bronze badges










      asked Aug 16 at 18:41









      Clayy91Clayy91

      313 bronze badges




      313 bronze badges























          4 Answers
          4






          active

          oldest

          votes


















          1













          $begingroup$

          You can decide between to structural design patterns:



          • Template Method Pattern

          • Strategy Pattern

          I would go with the Template Method Pattern because you do not reuse the algorithm which is a benefit of the Strategy Pattern.



          In the first step we need to create an abstract class which has all the common code and a invocation of an abstract method where the algorithms distinguish.



          abstract class PersistentAction 

          private final Connection connection;
          private final String username;
          private final String password;

          PersistentAction(Connection connection, String username, String password) /* ... */

          final boolean execute(String query)
          try(PreparedStatement statement = connection.prepareStatement(query))
          statement.setString(1, credential.getUsername());
          statement.setString(2, credential.getPassword());
          ResultSet result = statement.executeQuery();
          return evaluate(result);
          catch(SQLException e)
          return false;



          abstract boolean evaluate(Result result);



          After that we can create our algorithms which extends from our abstract class and implement the abstract method.



          class HasNextEvaluation extends PersistentAction 

          @Override
          protected boolean evaluate(ResultSet result)
          return result.next();




          class ConstantTrue extends PersistentAction

          @Override
          protected boolean evaluate(ResultSet result)
          return true;





          After the two steps we can achieve the following:



          public class DatabaseHandler 

          private static final Connection connection = createConenction();

          public static boolean checkLogin(String username, String password)
          String query = "select * from users where username = ? and password = ? ";

          PersistentAction action = new HasNextEvaluation(connection, username, password);
          return action.execute(query);


          public static boolean registerUser(String username, String password)
          String query = "select * from users where username = ? and password = ? ";

          PersistentAction action = new ConstantTrue(connection, username, password);
          return action.execute(query);




          From here I would improve the parameter list checkLogin(String username, String password) by using an Paramter Object.



          public static boolean checkLogin(Credential credential) 
          /* ... */



          There are two benefits that are in my mind. The first is the short parameter list and the second one is that you could have multiple types of credentials:



          • username and password

          • email and password

          • mobile number

          • (even with biometrics 👀)





          share|improve this answer











          $endgroup$














          • $begingroup$
            Thank you, i was looking for a solution like this. But one thing i have noticed: What if i want to set an additional parameter for the PreparedStatement? Lets say i want to put an extra E-Mail textfield on the registration form, then i would have to add something like this statement.setString(3, credential.getEmail()); in the execute method. This would result in false queries for those who only accepts two parameters. I hope im wrong because this is a cool solution, but to me this only seems to work as long as query stays identical.
            $endgroup$
            – Clayy91
            Aug 17 at 19:52











          • $begingroup$
            Maybe you can create an abstract class Query and all your concrete query types that can interact with a Credential.
            $endgroup$
            – Roman
            Aug 18 at 20:46


















          5













          $begingroup$

          Funny coincidence, I just created the solution for your problem (but in PHP). The common thing here is the one-time use of a prepared statement, the difference is in the query string and arguments, so what you need is a function that accepts a query string, an argument determining what execution function to use (executeQuery() or executeUpdate()) and the parameters for the query:



          // note: QueryType is an enum you should define
          public static ResultSet query(String sql, QueryType queryType, Object... queryArgs)
          // ...



          Include the try-catch blocks in this function too of course, and return null when according to queryType there should be no results.



          Note: I have no experience with database interaction with Java, so if there are only 2 different statement execution functions then you can use a boolean argument instead of the enum QueryType.



          Then your code could look like this:



          public static boolean checkLogin(String username, String password) 
          String sql = "select * from users where username = ? and password = ? ";
          ResultSet result = query(sql, QueryType.RETURN_RESULT, username, password);
          return result.next(); // true if User exists



          A note about your query string: I find it more convenient to use CAPS for keywords and lowercase text for names, it highlights the structure of the query.






          share|improve this answer











          $endgroup$














          • $begingroup$
            thanks for your answer! Few things ive noticed when i tried to implement your solution: The executeUpdate() Method returns an Integer, so i cant have ResultSet as return type. I could however, use executeQuery() for all SQL-querys. Problem is, i would have to catch a SQLException in the checkLogin Method, because result.next() throws such. Kind of destroys the intend of the query Method. I thought about some kind of Interface/Abstract Class Pattern in the first place to solve this problem, but cant figure out. I will continue playing around with your suggestion tho!
            $endgroup$
            – Clayy91
            Aug 16 at 20:29










          • $begingroup$
            @Clayy91 You could implement a QueryResult class with a resultType property that based on it you'll know what other property of that class contains the result (int resultInt or ResultSet resultSet for example) - or look straight at the property you expect to contain the result according to the type of query you made.
            $endgroup$
            – potato
            Aug 16 at 22:28



















          4













          $begingroup$

          You must never store passwords as plain text in the database. Read an article about password hashing to avoid this mistake in the future.



          Make sure that you have a unique index on the username column. Otherwise it will be possible to create several users with the same username, and with equal or differing passwords.






          share|improve this answer









          $endgroup$






















            2













            $begingroup$

            You should really try to use a more modern approach to closeable resources. The try-with-resources statement has been introduced in Java 7 (2011).



            This gets rid of all the hocus-pocus around closing and nested exceptions for you. Trivial rewrite of the first function:



            public static boolean checkLogin(String username, String password) 
            Connection connection = createConenction();
            String query = "select * from users where username = ? and password = ? ";

            try (
            PreparedStatement statement = connection.prepareStatement(query)
            )
            statement.setString(1, username);
            statement.setString(2, password);
            ResultSet result = statement.executeQuery();
            return result.next(); //True if User exists
            catch(SQLException e)
            e.printStackTrace();
            return false;




            Furthermore, if the method name createConnection() is not a lie, you should also close the connection. (Otherwise rename it to getConnection()):



            public static boolean checkLogin(String username, String password) 
            String query = "select * from users where username = ? and password = ? ";

            try (
            Connection connection = createConenction();
            PreparedStatement statement = connection.prepareStatement(query)
            )
            statement.setString(1, username);
            statement.setString(2, password);
            ResultSet result = statement.executeQuery();
            return result.next(); //True if User exists
            catch(SQLException e)
            e.printStackTrace();
            return false;




            Apart from that little optimization in syntax, I do not think that the methods bear enough similarity to warrant a common abstraction. Writing and retrieving a line of data is a totally different business case and should be kept separate to be able to develop into different directions in the future.



            If you do not want to do all that basic handling of statements, result sets, rows, columns, rather look for a well established OR-mapping framework (e.g. JPA, Hibernate) instead of rolling your own.






            share|improve this answer









            $endgroup$

















              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "196"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226281%2fjava-methods-to-add-and-authenticate-users-in-mysql%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              1













              $begingroup$

              You can decide between to structural design patterns:



              • Template Method Pattern

              • Strategy Pattern

              I would go with the Template Method Pattern because you do not reuse the algorithm which is a benefit of the Strategy Pattern.



              In the first step we need to create an abstract class which has all the common code and a invocation of an abstract method where the algorithms distinguish.



              abstract class PersistentAction 

              private final Connection connection;
              private final String username;
              private final String password;

              PersistentAction(Connection connection, String username, String password) /* ... */

              final boolean execute(String query)
              try(PreparedStatement statement = connection.prepareStatement(query))
              statement.setString(1, credential.getUsername());
              statement.setString(2, credential.getPassword());
              ResultSet result = statement.executeQuery();
              return evaluate(result);
              catch(SQLException e)
              return false;



              abstract boolean evaluate(Result result);



              After that we can create our algorithms which extends from our abstract class and implement the abstract method.



              class HasNextEvaluation extends PersistentAction 

              @Override
              protected boolean evaluate(ResultSet result)
              return result.next();




              class ConstantTrue extends PersistentAction

              @Override
              protected boolean evaluate(ResultSet result)
              return true;





              After the two steps we can achieve the following:



              public class DatabaseHandler 

              private static final Connection connection = createConenction();

              public static boolean checkLogin(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new HasNextEvaluation(connection, username, password);
              return action.execute(query);


              public static boolean registerUser(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new ConstantTrue(connection, username, password);
              return action.execute(query);




              From here I would improve the parameter list checkLogin(String username, String password) by using an Paramter Object.



              public static boolean checkLogin(Credential credential) 
              /* ... */



              There are two benefits that are in my mind. The first is the short parameter list and the second one is that you could have multiple types of credentials:



              • username and password

              • email and password

              • mobile number

              • (even with biometrics 👀)





              share|improve this answer











              $endgroup$














              • $begingroup$
                Thank you, i was looking for a solution like this. But one thing i have noticed: What if i want to set an additional parameter for the PreparedStatement? Lets say i want to put an extra E-Mail textfield on the registration form, then i would have to add something like this statement.setString(3, credential.getEmail()); in the execute method. This would result in false queries for those who only accepts two parameters. I hope im wrong because this is a cool solution, but to me this only seems to work as long as query stays identical.
                $endgroup$
                – Clayy91
                Aug 17 at 19:52











              • $begingroup$
                Maybe you can create an abstract class Query and all your concrete query types that can interact with a Credential.
                $endgroup$
                – Roman
                Aug 18 at 20:46















              1













              $begingroup$

              You can decide between to structural design patterns:



              • Template Method Pattern

              • Strategy Pattern

              I would go with the Template Method Pattern because you do not reuse the algorithm which is a benefit of the Strategy Pattern.



              In the first step we need to create an abstract class which has all the common code and a invocation of an abstract method where the algorithms distinguish.



              abstract class PersistentAction 

              private final Connection connection;
              private final String username;
              private final String password;

              PersistentAction(Connection connection, String username, String password) /* ... */

              final boolean execute(String query)
              try(PreparedStatement statement = connection.prepareStatement(query))
              statement.setString(1, credential.getUsername());
              statement.setString(2, credential.getPassword());
              ResultSet result = statement.executeQuery();
              return evaluate(result);
              catch(SQLException e)
              return false;



              abstract boolean evaluate(Result result);



              After that we can create our algorithms which extends from our abstract class and implement the abstract method.



              class HasNextEvaluation extends PersistentAction 

              @Override
              protected boolean evaluate(ResultSet result)
              return result.next();




              class ConstantTrue extends PersistentAction

              @Override
              protected boolean evaluate(ResultSet result)
              return true;





              After the two steps we can achieve the following:



              public class DatabaseHandler 

              private static final Connection connection = createConenction();

              public static boolean checkLogin(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new HasNextEvaluation(connection, username, password);
              return action.execute(query);


              public static boolean registerUser(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new ConstantTrue(connection, username, password);
              return action.execute(query);




              From here I would improve the parameter list checkLogin(String username, String password) by using an Paramter Object.



              public static boolean checkLogin(Credential credential) 
              /* ... */



              There are two benefits that are in my mind. The first is the short parameter list and the second one is that you could have multiple types of credentials:



              • username and password

              • email and password

              • mobile number

              • (even with biometrics 👀)





              share|improve this answer











              $endgroup$














              • $begingroup$
                Thank you, i was looking for a solution like this. But one thing i have noticed: What if i want to set an additional parameter for the PreparedStatement? Lets say i want to put an extra E-Mail textfield on the registration form, then i would have to add something like this statement.setString(3, credential.getEmail()); in the execute method. This would result in false queries for those who only accepts two parameters. I hope im wrong because this is a cool solution, but to me this only seems to work as long as query stays identical.
                $endgroup$
                – Clayy91
                Aug 17 at 19:52











              • $begingroup$
                Maybe you can create an abstract class Query and all your concrete query types that can interact with a Credential.
                $endgroup$
                – Roman
                Aug 18 at 20:46













              1














              1










              1







              $begingroup$

              You can decide between to structural design patterns:



              • Template Method Pattern

              • Strategy Pattern

              I would go with the Template Method Pattern because you do not reuse the algorithm which is a benefit of the Strategy Pattern.



              In the first step we need to create an abstract class which has all the common code and a invocation of an abstract method where the algorithms distinguish.



              abstract class PersistentAction 

              private final Connection connection;
              private final String username;
              private final String password;

              PersistentAction(Connection connection, String username, String password) /* ... */

              final boolean execute(String query)
              try(PreparedStatement statement = connection.prepareStatement(query))
              statement.setString(1, credential.getUsername());
              statement.setString(2, credential.getPassword());
              ResultSet result = statement.executeQuery();
              return evaluate(result);
              catch(SQLException e)
              return false;



              abstract boolean evaluate(Result result);



              After that we can create our algorithms which extends from our abstract class and implement the abstract method.



              class HasNextEvaluation extends PersistentAction 

              @Override
              protected boolean evaluate(ResultSet result)
              return result.next();




              class ConstantTrue extends PersistentAction

              @Override
              protected boolean evaluate(ResultSet result)
              return true;





              After the two steps we can achieve the following:



              public class DatabaseHandler 

              private static final Connection connection = createConenction();

              public static boolean checkLogin(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new HasNextEvaluation(connection, username, password);
              return action.execute(query);


              public static boolean registerUser(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new ConstantTrue(connection, username, password);
              return action.execute(query);




              From here I would improve the parameter list checkLogin(String username, String password) by using an Paramter Object.



              public static boolean checkLogin(Credential credential) 
              /* ... */



              There are two benefits that are in my mind. The first is the short parameter list and the second one is that you could have multiple types of credentials:



              • username and password

              • email and password

              • mobile number

              • (even with biometrics 👀)





              share|improve this answer











              $endgroup$



              You can decide between to structural design patterns:



              • Template Method Pattern

              • Strategy Pattern

              I would go with the Template Method Pattern because you do not reuse the algorithm which is a benefit of the Strategy Pattern.



              In the first step we need to create an abstract class which has all the common code and a invocation of an abstract method where the algorithms distinguish.



              abstract class PersistentAction 

              private final Connection connection;
              private final String username;
              private final String password;

              PersistentAction(Connection connection, String username, String password) /* ... */

              final boolean execute(String query)
              try(PreparedStatement statement = connection.prepareStatement(query))
              statement.setString(1, credential.getUsername());
              statement.setString(2, credential.getPassword());
              ResultSet result = statement.executeQuery();
              return evaluate(result);
              catch(SQLException e)
              return false;



              abstract boolean evaluate(Result result);



              After that we can create our algorithms which extends from our abstract class and implement the abstract method.



              class HasNextEvaluation extends PersistentAction 

              @Override
              protected boolean evaluate(ResultSet result)
              return result.next();




              class ConstantTrue extends PersistentAction

              @Override
              protected boolean evaluate(ResultSet result)
              return true;





              After the two steps we can achieve the following:



              public class DatabaseHandler 

              private static final Connection connection = createConenction();

              public static boolean checkLogin(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new HasNextEvaluation(connection, username, password);
              return action.execute(query);


              public static boolean registerUser(String username, String password)
              String query = "select * from users where username = ? and password = ? ";

              PersistentAction action = new ConstantTrue(connection, username, password);
              return action.execute(query);




              From here I would improve the parameter list checkLogin(String username, String password) by using an Paramter Object.



              public static boolean checkLogin(Credential credential) 
              /* ... */



              There are two benefits that are in my mind. The first is the short parameter list and the second one is that you could have multiple types of credentials:



              • username and password

              • email and password

              • mobile number

              • (even with biometrics 👀)






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Aug 17 at 17:16

























              answered Aug 17 at 15:03









              RomanRoman

              1,3483 silver badges15 bronze badges




              1,3483 silver badges15 bronze badges














              • $begingroup$
                Thank you, i was looking for a solution like this. But one thing i have noticed: What if i want to set an additional parameter for the PreparedStatement? Lets say i want to put an extra E-Mail textfield on the registration form, then i would have to add something like this statement.setString(3, credential.getEmail()); in the execute method. This would result in false queries for those who only accepts two parameters. I hope im wrong because this is a cool solution, but to me this only seems to work as long as query stays identical.
                $endgroup$
                – Clayy91
                Aug 17 at 19:52











              • $begingroup$
                Maybe you can create an abstract class Query and all your concrete query types that can interact with a Credential.
                $endgroup$
                – Roman
                Aug 18 at 20:46
















              • $begingroup$
                Thank you, i was looking for a solution like this. But one thing i have noticed: What if i want to set an additional parameter for the PreparedStatement? Lets say i want to put an extra E-Mail textfield on the registration form, then i would have to add something like this statement.setString(3, credential.getEmail()); in the execute method. This would result in false queries for those who only accepts two parameters. I hope im wrong because this is a cool solution, but to me this only seems to work as long as query stays identical.
                $endgroup$
                – Clayy91
                Aug 17 at 19:52











              • $begingroup$
                Maybe you can create an abstract class Query and all your concrete query types that can interact with a Credential.
                $endgroup$
                – Roman
                Aug 18 at 20:46















              $begingroup$
              Thank you, i was looking for a solution like this. But one thing i have noticed: What if i want to set an additional parameter for the PreparedStatement? Lets say i want to put an extra E-Mail textfield on the registration form, then i would have to add something like this statement.setString(3, credential.getEmail()); in the execute method. This would result in false queries for those who only accepts two parameters. I hope im wrong because this is a cool solution, but to me this only seems to work as long as query stays identical.
              $endgroup$
              – Clayy91
              Aug 17 at 19:52





              $begingroup$
              Thank you, i was looking for a solution like this. But one thing i have noticed: What if i want to set an additional parameter for the PreparedStatement? Lets say i want to put an extra E-Mail textfield on the registration form, then i would have to add something like this statement.setString(3, credential.getEmail()); in the execute method. This would result in false queries for those who only accepts two parameters. I hope im wrong because this is a cool solution, but to me this only seems to work as long as query stays identical.
              $endgroup$
              – Clayy91
              Aug 17 at 19:52













              $begingroup$
              Maybe you can create an abstract class Query and all your concrete query types that can interact with a Credential.
              $endgroup$
              – Roman
              Aug 18 at 20:46




              $begingroup$
              Maybe you can create an abstract class Query and all your concrete query types that can interact with a Credential.
              $endgroup$
              – Roman
              Aug 18 at 20:46













              5













              $begingroup$

              Funny coincidence, I just created the solution for your problem (but in PHP). The common thing here is the one-time use of a prepared statement, the difference is in the query string and arguments, so what you need is a function that accepts a query string, an argument determining what execution function to use (executeQuery() or executeUpdate()) and the parameters for the query:



              // note: QueryType is an enum you should define
              public static ResultSet query(String sql, QueryType queryType, Object... queryArgs)
              // ...



              Include the try-catch blocks in this function too of course, and return null when according to queryType there should be no results.



              Note: I have no experience with database interaction with Java, so if there are only 2 different statement execution functions then you can use a boolean argument instead of the enum QueryType.



              Then your code could look like this:



              public static boolean checkLogin(String username, String password) 
              String sql = "select * from users where username = ? and password = ? ";
              ResultSet result = query(sql, QueryType.RETURN_RESULT, username, password);
              return result.next(); // true if User exists



              A note about your query string: I find it more convenient to use CAPS for keywords and lowercase text for names, it highlights the structure of the query.






              share|improve this answer











              $endgroup$














              • $begingroup$
                thanks for your answer! Few things ive noticed when i tried to implement your solution: The executeUpdate() Method returns an Integer, so i cant have ResultSet as return type. I could however, use executeQuery() for all SQL-querys. Problem is, i would have to catch a SQLException in the checkLogin Method, because result.next() throws such. Kind of destroys the intend of the query Method. I thought about some kind of Interface/Abstract Class Pattern in the first place to solve this problem, but cant figure out. I will continue playing around with your suggestion tho!
                $endgroup$
                – Clayy91
                Aug 16 at 20:29










              • $begingroup$
                @Clayy91 You could implement a QueryResult class with a resultType property that based on it you'll know what other property of that class contains the result (int resultInt or ResultSet resultSet for example) - or look straight at the property you expect to contain the result according to the type of query you made.
                $endgroup$
                – potato
                Aug 16 at 22:28
















              5













              $begingroup$

              Funny coincidence, I just created the solution for your problem (but in PHP). The common thing here is the one-time use of a prepared statement, the difference is in the query string and arguments, so what you need is a function that accepts a query string, an argument determining what execution function to use (executeQuery() or executeUpdate()) and the parameters for the query:



              // note: QueryType is an enum you should define
              public static ResultSet query(String sql, QueryType queryType, Object... queryArgs)
              // ...



              Include the try-catch blocks in this function too of course, and return null when according to queryType there should be no results.



              Note: I have no experience with database interaction with Java, so if there are only 2 different statement execution functions then you can use a boolean argument instead of the enum QueryType.



              Then your code could look like this:



              public static boolean checkLogin(String username, String password) 
              String sql = "select * from users where username = ? and password = ? ";
              ResultSet result = query(sql, QueryType.RETURN_RESULT, username, password);
              return result.next(); // true if User exists



              A note about your query string: I find it more convenient to use CAPS for keywords and lowercase text for names, it highlights the structure of the query.






              share|improve this answer











              $endgroup$














              • $begingroup$
                thanks for your answer! Few things ive noticed when i tried to implement your solution: The executeUpdate() Method returns an Integer, so i cant have ResultSet as return type. I could however, use executeQuery() for all SQL-querys. Problem is, i would have to catch a SQLException in the checkLogin Method, because result.next() throws such. Kind of destroys the intend of the query Method. I thought about some kind of Interface/Abstract Class Pattern in the first place to solve this problem, but cant figure out. I will continue playing around with your suggestion tho!
                $endgroup$
                – Clayy91
                Aug 16 at 20:29










              • $begingroup$
                @Clayy91 You could implement a QueryResult class with a resultType property that based on it you'll know what other property of that class contains the result (int resultInt or ResultSet resultSet for example) - or look straight at the property you expect to contain the result according to the type of query you made.
                $endgroup$
                – potato
                Aug 16 at 22:28














              5














              5










              5







              $begingroup$

              Funny coincidence, I just created the solution for your problem (but in PHP). The common thing here is the one-time use of a prepared statement, the difference is in the query string and arguments, so what you need is a function that accepts a query string, an argument determining what execution function to use (executeQuery() or executeUpdate()) and the parameters for the query:



              // note: QueryType is an enum you should define
              public static ResultSet query(String sql, QueryType queryType, Object... queryArgs)
              // ...



              Include the try-catch blocks in this function too of course, and return null when according to queryType there should be no results.



              Note: I have no experience with database interaction with Java, so if there are only 2 different statement execution functions then you can use a boolean argument instead of the enum QueryType.



              Then your code could look like this:



              public static boolean checkLogin(String username, String password) 
              String sql = "select * from users where username = ? and password = ? ";
              ResultSet result = query(sql, QueryType.RETURN_RESULT, username, password);
              return result.next(); // true if User exists



              A note about your query string: I find it more convenient to use CAPS for keywords and lowercase text for names, it highlights the structure of the query.






              share|improve this answer











              $endgroup$



              Funny coincidence, I just created the solution for your problem (but in PHP). The common thing here is the one-time use of a prepared statement, the difference is in the query string and arguments, so what you need is a function that accepts a query string, an argument determining what execution function to use (executeQuery() or executeUpdate()) and the parameters for the query:



              // note: QueryType is an enum you should define
              public static ResultSet query(String sql, QueryType queryType, Object... queryArgs)
              // ...



              Include the try-catch blocks in this function too of course, and return null when according to queryType there should be no results.



              Note: I have no experience with database interaction with Java, so if there are only 2 different statement execution functions then you can use a boolean argument instead of the enum QueryType.



              Then your code could look like this:



              public static boolean checkLogin(String username, String password) 
              String sql = "select * from users where username = ? and password = ? ";
              ResultSet result = query(sql, QueryType.RETURN_RESULT, username, password);
              return result.next(); // true if User exists



              A note about your query string: I find it more convenient to use CAPS for keywords and lowercase text for names, it highlights the structure of the query.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Aug 16 at 22:40

























              answered Aug 16 at 19:10









              potatopotato

              51814 bronze badges




              51814 bronze badges














              • $begingroup$
                thanks for your answer! Few things ive noticed when i tried to implement your solution: The executeUpdate() Method returns an Integer, so i cant have ResultSet as return type. I could however, use executeQuery() for all SQL-querys. Problem is, i would have to catch a SQLException in the checkLogin Method, because result.next() throws such. Kind of destroys the intend of the query Method. I thought about some kind of Interface/Abstract Class Pattern in the first place to solve this problem, but cant figure out. I will continue playing around with your suggestion tho!
                $endgroup$
                – Clayy91
                Aug 16 at 20:29










              • $begingroup$
                @Clayy91 You could implement a QueryResult class with a resultType property that based on it you'll know what other property of that class contains the result (int resultInt or ResultSet resultSet for example) - or look straight at the property you expect to contain the result according to the type of query you made.
                $endgroup$
                – potato
                Aug 16 at 22:28

















              • $begingroup$
                thanks for your answer! Few things ive noticed when i tried to implement your solution: The executeUpdate() Method returns an Integer, so i cant have ResultSet as return type. I could however, use executeQuery() for all SQL-querys. Problem is, i would have to catch a SQLException in the checkLogin Method, because result.next() throws such. Kind of destroys the intend of the query Method. I thought about some kind of Interface/Abstract Class Pattern in the first place to solve this problem, but cant figure out. I will continue playing around with your suggestion tho!
                $endgroup$
                – Clayy91
                Aug 16 at 20:29










              • $begingroup$
                @Clayy91 You could implement a QueryResult class with a resultType property that based on it you'll know what other property of that class contains the result (int resultInt or ResultSet resultSet for example) - or look straight at the property you expect to contain the result according to the type of query you made.
                $endgroup$
                – potato
                Aug 16 at 22:28
















              $begingroup$
              thanks for your answer! Few things ive noticed when i tried to implement your solution: The executeUpdate() Method returns an Integer, so i cant have ResultSet as return type. I could however, use executeQuery() for all SQL-querys. Problem is, i would have to catch a SQLException in the checkLogin Method, because result.next() throws such. Kind of destroys the intend of the query Method. I thought about some kind of Interface/Abstract Class Pattern in the first place to solve this problem, but cant figure out. I will continue playing around with your suggestion tho!
              $endgroup$
              – Clayy91
              Aug 16 at 20:29




              $begingroup$
              thanks for your answer! Few things ive noticed when i tried to implement your solution: The executeUpdate() Method returns an Integer, so i cant have ResultSet as return type. I could however, use executeQuery() for all SQL-querys. Problem is, i would have to catch a SQLException in the checkLogin Method, because result.next() throws such. Kind of destroys the intend of the query Method. I thought about some kind of Interface/Abstract Class Pattern in the first place to solve this problem, but cant figure out. I will continue playing around with your suggestion tho!
              $endgroup$
              – Clayy91
              Aug 16 at 20:29












              $begingroup$
              @Clayy91 You could implement a QueryResult class with a resultType property that based on it you'll know what other property of that class contains the result (int resultInt or ResultSet resultSet for example) - or look straight at the property you expect to contain the result according to the type of query you made.
              $endgroup$
              – potato
              Aug 16 at 22:28





              $begingroup$
              @Clayy91 You could implement a QueryResult class with a resultType property that based on it you'll know what other property of that class contains the result (int resultInt or ResultSet resultSet for example) - or look straight at the property you expect to contain the result according to the type of query you made.
              $endgroup$
              – potato
              Aug 16 at 22:28












              4













              $begingroup$

              You must never store passwords as plain text in the database. Read an article about password hashing to avoid this mistake in the future.



              Make sure that you have a unique index on the username column. Otherwise it will be possible to create several users with the same username, and with equal or differing passwords.






              share|improve this answer









              $endgroup$



















                4













                $begingroup$

                You must never store passwords as plain text in the database. Read an article about password hashing to avoid this mistake in the future.



                Make sure that you have a unique index on the username column. Otherwise it will be possible to create several users with the same username, and with equal or differing passwords.






                share|improve this answer









                $endgroup$

















                  4














                  4










                  4







                  $begingroup$

                  You must never store passwords as plain text in the database. Read an article about password hashing to avoid this mistake in the future.



                  Make sure that you have a unique index on the username column. Otherwise it will be possible to create several users with the same username, and with equal or differing passwords.






                  share|improve this answer









                  $endgroup$



                  You must never store passwords as plain text in the database. Read an article about password hashing to avoid this mistake in the future.



                  Make sure that you have a unique index on the username column. Otherwise it will be possible to create several users with the same username, and with equal or differing passwords.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 17 at 6:50









                  Roland IlligRoland Illig

                  15k2 gold badges24 silver badges57 bronze badges




                  15k2 gold badges24 silver badges57 bronze badges
























                      2













                      $begingroup$

                      You should really try to use a more modern approach to closeable resources. The try-with-resources statement has been introduced in Java 7 (2011).



                      This gets rid of all the hocus-pocus around closing and nested exceptions for you. Trivial rewrite of the first function:



                      public static boolean checkLogin(String username, String password) 
                      Connection connection = createConenction();
                      String query = "select * from users where username = ? and password = ? ";

                      try (
                      PreparedStatement statement = connection.prepareStatement(query)
                      )
                      statement.setString(1, username);
                      statement.setString(2, password);
                      ResultSet result = statement.executeQuery();
                      return result.next(); //True if User exists
                      catch(SQLException e)
                      e.printStackTrace();
                      return false;




                      Furthermore, if the method name createConnection() is not a lie, you should also close the connection. (Otherwise rename it to getConnection()):



                      public static boolean checkLogin(String username, String password) 
                      String query = "select * from users where username = ? and password = ? ";

                      try (
                      Connection connection = createConenction();
                      PreparedStatement statement = connection.prepareStatement(query)
                      )
                      statement.setString(1, username);
                      statement.setString(2, password);
                      ResultSet result = statement.executeQuery();
                      return result.next(); //True if User exists
                      catch(SQLException e)
                      e.printStackTrace();
                      return false;




                      Apart from that little optimization in syntax, I do not think that the methods bear enough similarity to warrant a common abstraction. Writing and retrieving a line of data is a totally different business case and should be kept separate to be able to develop into different directions in the future.



                      If you do not want to do all that basic handling of statements, result sets, rows, columns, rather look for a well established OR-mapping framework (e.g. JPA, Hibernate) instead of rolling your own.






                      share|improve this answer









                      $endgroup$



















                        2













                        $begingroup$

                        You should really try to use a more modern approach to closeable resources. The try-with-resources statement has been introduced in Java 7 (2011).



                        This gets rid of all the hocus-pocus around closing and nested exceptions for you. Trivial rewrite of the first function:



                        public static boolean checkLogin(String username, String password) 
                        Connection connection = createConenction();
                        String query = "select * from users where username = ? and password = ? ";

                        try (
                        PreparedStatement statement = connection.prepareStatement(query)
                        )
                        statement.setString(1, username);
                        statement.setString(2, password);
                        ResultSet result = statement.executeQuery();
                        return result.next(); //True if User exists
                        catch(SQLException e)
                        e.printStackTrace();
                        return false;




                        Furthermore, if the method name createConnection() is not a lie, you should also close the connection. (Otherwise rename it to getConnection()):



                        public static boolean checkLogin(String username, String password) 
                        String query = "select * from users where username = ? and password = ? ";

                        try (
                        Connection connection = createConenction();
                        PreparedStatement statement = connection.prepareStatement(query)
                        )
                        statement.setString(1, username);
                        statement.setString(2, password);
                        ResultSet result = statement.executeQuery();
                        return result.next(); //True if User exists
                        catch(SQLException e)
                        e.printStackTrace();
                        return false;




                        Apart from that little optimization in syntax, I do not think that the methods bear enough similarity to warrant a common abstraction. Writing and retrieving a line of data is a totally different business case and should be kept separate to be able to develop into different directions in the future.



                        If you do not want to do all that basic handling of statements, result sets, rows, columns, rather look for a well established OR-mapping framework (e.g. JPA, Hibernate) instead of rolling your own.






                        share|improve this answer









                        $endgroup$

















                          2














                          2










                          2







                          $begingroup$

                          You should really try to use a more modern approach to closeable resources. The try-with-resources statement has been introduced in Java 7 (2011).



                          This gets rid of all the hocus-pocus around closing and nested exceptions for you. Trivial rewrite of the first function:



                          public static boolean checkLogin(String username, String password) 
                          Connection connection = createConenction();
                          String query = "select * from users where username = ? and password = ? ";

                          try (
                          PreparedStatement statement = connection.prepareStatement(query)
                          )
                          statement.setString(1, username);
                          statement.setString(2, password);
                          ResultSet result = statement.executeQuery();
                          return result.next(); //True if User exists
                          catch(SQLException e)
                          e.printStackTrace();
                          return false;




                          Furthermore, if the method name createConnection() is not a lie, you should also close the connection. (Otherwise rename it to getConnection()):



                          public static boolean checkLogin(String username, String password) 
                          String query = "select * from users where username = ? and password = ? ";

                          try (
                          Connection connection = createConenction();
                          PreparedStatement statement = connection.prepareStatement(query)
                          )
                          statement.setString(1, username);
                          statement.setString(2, password);
                          ResultSet result = statement.executeQuery();
                          return result.next(); //True if User exists
                          catch(SQLException e)
                          e.printStackTrace();
                          return false;




                          Apart from that little optimization in syntax, I do not think that the methods bear enough similarity to warrant a common abstraction. Writing and retrieving a line of data is a totally different business case and should be kept separate to be able to develop into different directions in the future.



                          If you do not want to do all that basic handling of statements, result sets, rows, columns, rather look for a well established OR-mapping framework (e.g. JPA, Hibernate) instead of rolling your own.






                          share|improve this answer









                          $endgroup$



                          You should really try to use a more modern approach to closeable resources. The try-with-resources statement has been introduced in Java 7 (2011).



                          This gets rid of all the hocus-pocus around closing and nested exceptions for you. Trivial rewrite of the first function:



                          public static boolean checkLogin(String username, String password) 
                          Connection connection = createConenction();
                          String query = "select * from users where username = ? and password = ? ";

                          try (
                          PreparedStatement statement = connection.prepareStatement(query)
                          )
                          statement.setString(1, username);
                          statement.setString(2, password);
                          ResultSet result = statement.executeQuery();
                          return result.next(); //True if User exists
                          catch(SQLException e)
                          e.printStackTrace();
                          return false;




                          Furthermore, if the method name createConnection() is not a lie, you should also close the connection. (Otherwise rename it to getConnection()):



                          public static boolean checkLogin(String username, String password) 
                          String query = "select * from users where username = ? and password = ? ";

                          try (
                          Connection connection = createConenction();
                          PreparedStatement statement = connection.prepareStatement(query)
                          )
                          statement.setString(1, username);
                          statement.setString(2, password);
                          ResultSet result = statement.executeQuery();
                          return result.next(); //True if User exists
                          catch(SQLException e)
                          e.printStackTrace();
                          return false;




                          Apart from that little optimization in syntax, I do not think that the methods bear enough similarity to warrant a common abstraction. Writing and retrieving a line of data is a totally different business case and should be kept separate to be able to develop into different directions in the future.



                          If you do not want to do all that basic handling of statements, result sets, rows, columns, rather look for a well established OR-mapping framework (e.g. JPA, Hibernate) instead of rolling your own.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Aug 17 at 4:12









                          mtjmtj

                          3,0293 silver badges14 bronze badges




                          3,0293 silver badges14 bronze badges






























                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Code Review Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              Use MathJax to format equations. MathJax reference.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f226281%2fjava-methods-to-add-and-authenticate-users-in-mysql%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Get product attribute by attribute group code in magento 2get product attribute by product attribute group in magento 2Magento 2 Log Bundle Product Data in List Page?How to get all product attribute of a attribute group of Default attribute set?Magento 2.1 Create a filter in the product grid by new attributeMagento 2 : Get Product Attribute values By GroupMagento 2 How to get all existing values for one attributeMagento 2 get custom attribute of a single product inside a pluginMagento 2.3 How to get all the Multi Source Inventory (MSI) locations collection in custom module?Magento2: how to develop rest API to get new productsGet product attribute by attribute group code ( [attribute_group_code] ) in magento 2

                              Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

                              Magento 2.3: How do i solve this, Not registered handle, on custom form?How can i rewrite TierPrice Block in Magento2magento 2 captcha not rendering if I override layout xmlmain.CRITICAL: Plugin class doesn't existMagento 2 : Problem while adding custom button order view page?Magento 2.2.5: Overriding Admin Controller sales/orderMagento 2.2.5: Add, Update and Delete existing products Custom OptionsMagento 2.3 : File Upload issue in UI Component FormMagento2 Not registered handleHow to configured Form Builder Js in my custom magento 2.3.0 module?Magento 2.3. How to create image upload field in an admin form