Lab 8: SQL and JDBC
Goals
After completing this lab, you should be able to
- use the JDBC API effectively
 - load a database driver
 - make connections to a database
 - execute queries, updates to the database in SQL using Statements and PreparedStatements
 - iterate through a ResultSet and display it in a meaningful way in several forms
 
--- JDBC Lab FAQ ---
Objective: Set Up
ssh into a lab machine and then run labhelp so that I can keep track of the help queue.
Objective: Learning and Using PostgreSQL
For these exercises and for development, we'll use the PostgreSQL database management system (DBMS). For more information about using PostgreSQL, see the PostgreSQL page on the Wiki.
Using PostgreSQL at W&L
- See 
      the instructions for connecting to our course database.
    
    
Here is a dump from the (original) cs335 database so that you can see the definitions of the tables and initial data values. Focus on the
CREATE TABLEstatements.Alternatively, you can use the
\d tablenamecommand to view a table's columns and types,
e.g.,\d Users - List all the tables in the database using the
  command 
\dt - Write and execute the SQL statement to select all the columns
    and rows from the Users table
    
Later, as the results get longer, use the spacebar to page through results and use
qto exit out of the pages. - Write and execute the SQL statement to select the id from the
    Users table where the 
username='username'and thepassword=md5('passw0rd'). - Modify the previous command so that the password is 'password' and execute the command. How are the results different from the previous query?
 - Use 
\qto quit out of PostgreSQL 
Objective: Set Up for JDBC
Getting the PostgreSQL JDBC Driver
Download the PostgreSQL JDBC Driver from PostgreSQL. You should get the current version, for Java 8 or newer.
Eclipse Set Up
- Make a tagged version for your Lab 6 submission in the Servlet Lab repository.
 - Copy the PostgreSQL JDBC driver you downloaded earlier into
  your 
WEB-INF/libdirectory. Refresh to see the jar file. 
Objective: Learning JDBC (45 pts)
For the rest of the lab, you should try out your SQL statements on the command-line before putting them into JDBC code.
If you find yourself thinking "I'll just fix this query in Java code," STOP! Let the database do the work. It likely can do what you want faster.
- Create a new Java
class (not a servlet)
called 
JDBCPracticethat has amainmethod. What is an appropriate package for this class? - Follow the instructions from class about how you connect to a 
database using JDBC and apply those in the 
mainmethod. You'll need to update the url, username, password, etc., based on the instructions linked above. What classes/packages do you need? What steps do you need to take?You may want to look at the example. You may also want to look at the Javadocs.
Run this class as a Java application.
 - In the command-line, execute the statement that finds out the 
    names of the groups that each user belongs to.  (As in, for each 
    user, we want to see all the groups that user is in.)  Then, update 
    your Java code to execute that statement.  Iterate through the 
    
ResultSetand display the results in a nice way. (Be careful with this query. Even if you do the query right, you may get duplicates. But, if you do the query wrong, you'll get even more--and incorrect--duplicates. I used to have theusers2groupstable set up such that theuserid-groupidwere unique, but then students would get errors if they ran the program multiple times and get confused, so I took that out. So, now the confusion is pushed to here.)How can you test that your query is correct?
How can you handle if there are duplicate groups?
Test your program.
 - Create and execute a 
PreparedStatementthat inserts a new group into theGroupstable, providing the group's name and description as parameters. (The database is set up so that the id is automatically filled in.) - Create and execute a 
PreparedStatementthat updates a user's group membership so that they are now also a member of your newly created group. (A user of your choice.) Note that you'll need to look up (programmatically) the newly created group's id. - Create and execute a 
PreparedStatementthat finds out the names of the groups that a user belongs to, providing the username as a parameter. Display the results of the query. - Don't forget to close the DB connection when you're done with it.
 - Run and test your program. (During this process, you'll add rows to the table that the rest of the class can also see.)
 
Objective: Using JDBC in a Servlet (55 pts)
- Modify your 
LoginServletorweb.xmlso that it has the following init parameters for the database connection:db_hostnamedb_databasedb_usernamedb_password
 - Modify your 
LoginServletso that it does the JDBC setup (e.g., DriverManager, Connection) in theinitmethod. (Why is this the appropriate place for this code?) Review our process from Lab 5 if needed. You'll needConnectionto be an instance variable of your servlet so that you can use it in thedoPostmethod. Use the init parameters in your setup. -  Close the connection in the servlet's 
destroymethod. - Modify your 
LoginServletso that it checks if the username and password match an entry in the database. Note the password was given when you were writing your practice queries above. (Keep your original error messages/attributes that check if the username or password wasn't entered.) - After that is working, make your 
PreparedStatementan instance variable and instantiate it in theinitmethod. (Why should it be a PreparedStatement?) In the class's Javadoc comments, discuss why the instantiation of the prepared statement should be in the init method. - Get the user's "real" name from the database and save it as a session attribute because you'll want to use the user's real name for more than just this request. (Stick with the best design principles.)
 - Modify the congratulations JSP so that it says "Welcome Back, <name>!" with the name (that was stored in the session) plugged in.
 - If you haven't already, copy the 
AuthenticatedTestservlet and the authenticated test HTML page and JSPs and add them to this project. - Modify 
authenticated.jspso that it displays the user's name (from the session attribute you set up previously) in the welcome. - Test that everything works, i.e., after a successful login, if
  the user does the authenticated test, they will see the promised
  land page, with their name in the welcome.  This showed how
  session state can be maintained across multiple requests and
  displayed in the JSPs.
   
  
Now, back to databases...
 - Modify the 
LoginServletso that it creates an ArrayList of Strings of the logged-in user's groups (sorted by name, ascending) and passes the ArrayList as an attribute (whose attribute is most fitting for this case?) to the congratulations JSP to display.Practice your SQL statement in the terminal before attempting to put it into Java code. Label the groups and display them as an unordered list.
In the end, the response may look something like:
Welcome Back, Test McUser
Your Group Membership:
- Coin Collecting
 - Gardening
 
 - Test your code several times.
 - Finally, test that everything works, end to end/start to finish; correct and incorrect passwords; group names, authenticated test.
 
Submission
Export the project as a .war file, including the source code, and save in your GitHub repository (still from Lab 4).
Grading (100 pts)
This lab is due tonight at 11:59 p.m.
- JDBC Practice (45 pts)
 - LoginServlet and Congratulations.jsp (55 pts)