Thursday 8 December 2016

Chapter 14.5 : Connecting to a Database Table


Now that you have connected to the database, the next step is to access the table in your database. For this, you need to execute a SQL Statement, and then manipulate all the rows and columns that were returned.
To execute a SQL statement on your table, you set up a Statement object. So add this import line to the top of your code:
import java.sql.Statement;
In the try part of the try … catch block add the following line (add it just below your Connection line):
Statement stmt = con.createStatement( );
Here, we're creating a Statement object called stmt. The Statement object needs a Connection object, with the createStatment method.
We also need a SQL Statement for the Statement object to execute. So add this line to your code:
String SQL = "SELECT * FROM Workers";
The above statement selects all the records from the database table called Workers.
We can pass this SQL query to a method of the Statement object called executeQuery. The Statement object will then go to work gathering all the records that match our query.
However, the executeQuery method returns all the records in something called a ResultSet. Before we explain what these are, add the following import line to the top of your code:
import java.sql.ResultSet;
Now add this line just below your SQL String line:
ResultSet rs = stmt.executeQuery( SQL );
So our ResultSet object is called rs. This will hold all the records from the database table. Before we go any further, though, here's an explanation of what ResultSets are.

ResultSets in Java

A ResultSet is a way to store and manipulate the records returned from a SQL query. ResultSets come in three different types. The type you use depends on what you want to do with the data:
  1. Do you just want to move forward through the records, from beginning to end?
  2. Do you want to move forward AND backward through the records, as well as detecting any changes made to the records?
  3. Do you want to move forward AND backward through the records, but are not bothered about any changes made to the records?
Type number 1 on the list above is called a TYPE_FORWARD_ONLY ResultSet. Number 2 on the list is a TYPE_SCROLL_SENSITIVE ResultSet. The third ResultSet option is called TYPE_SCROLL_INSENSITIVE.




The ResultSet type goes between the round brackets of createStement:
Statement stmt = con.createStatement( );
Because we've left the round brackets empty, we'll get the default RecordSet, which is TYPE_FORWARD_ONLY. In the next section, we'll use one of the other types. But you use them like this:
Statement stmt = con.createStatement( RecordSet.TYPE_SCROLL_SENSITIVE );
So you first type the word RecordSet. After a dot, you add the RecordSet type you want to use.
However, it doesn't end there. If you want to use TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE you also need to specify whether the ResultSet is Read Only or whether it is Updatable. You do this with two built-in constants: CONCUR_READ_ONLY and CONCUR_UPDATABLE. Again, these come after the word RecordSet:
ResultSet.CONCUR_READ_ONLY
ResultSet.CONCUR_UPDATABLE
This leads to a rather long line of code:
Statement stmt = con.createStatement( RecordSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
One more thing to get used to with ResultSets is something called a Cursor. A Cursor is really just a pointer to a table row. When you first load the records into a ResultSet, the Cursor is pointing to just before the first row in the table. You then use methods to manipulate the Cursor. But the idea is to identify a particular row in your table.

Using a ResultSet

Once you have all the records in a Results set, there are methods you can use to manipulate your records. Here are the methods you'll use most often:
The ResultSet also has methods you can use to identify a particular column (field) in a row. You can do so either by using the name of the column, or by using its index number. For our Workers table we set up four columns. They had the following names: ID, First_Name, Last_Name, and Job_Title. The index numbers are therefore 1, 2, 3, 4.
We set up the ID column to hold Integer values. The method you use to get at integer values in a column is getInt:
int id_col = rs.getInt("ID");
Here, we've set up an integer variable called id_col. We then use the getInt method of our ResultSet object, which is called rs. In between the round brackets, we have the name of the column. We could use the Index number instead:
int id_col = rs.getInt(1);
Notice that the Index number doesn't have quote marks, but the name does.
For the other three columns in our database table, we set them up to hold Strings. We, therefore, need the getString method:
String first_name = rs.getString("First_Name");
Or we could use the Index number:
String first_name = rs.getString(2);
Because the ResultSet Cursor is pointing to just before the first record when the data is loaded, we need to use the next method to move to the first row. The following code will get the first record from the table:
rs.next( );
int id_col = rs.getInt("ID");
String first_name = rs.getString("First_Name");
String last_name = rs.getString("Last_Name");
String job = rs.getString("Job_Title");
Notice that rs.next comes first in this code. This will move the Cursor to the first record in the table.
You can add a print line to your code to display the record in the Output window:
System.out.println( id_col + " " + first_name + " " + last_name + " " + job );
Here's what your code should look like now (we've adapted the print line because it's a bit too long):




If you want to go through all the records in the table, you can use a loop. Because the next method returns true or false, you can use it as the condition for a while loop:
while ( rs.next( ) ) {
}
In between the round brackets of while we have rs.next. This will be true as long as the Cursor hasn't gone past the last record in the table. If it has, rs.next will return a value of false, and the while loop will end. Using rs.next like this will also move the Cursor along one record at a time. Here's the same code as above, but using a while loop instead. Change your code to match:



When you run the above code, the Output window should display the following:
                               


Now that you have an idea of how to connect to a database table and display records we'll move on and write a more complex programme using forms and buttons to scroll through the records.

Chapter 14.4 : Connect to a Database Using Java Cod

The form will have Next and Previous to scroll through the data. Individual records will then be displayed in text fields. We'll also add button to Update a record, Delete a record, and create a new record in the database.

To get started, and for simplicity's sake, we'll use a terminal/console window to output the results from a database.
So start a new project for this by clicking File > New Project from the NetBeans menu. Create a Java Application. Call the package database_console, and the Main class DBConnect:


                     
When you click Finish, your code should look like this:
                                 


Connecting to the Database

To connect to a database you need a Connection object. The Connection object uses a DriverManager. The DriverManager passes in your database username, your password, and the location of the database.
Add these three import statements to the top of your code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
To set up a connection to a database, the code is this:
Connection con = DriverManager.getConnection( host, username, password );
So the DriverManager has a method called getConnection. This needs a host name (which is the location of your database), a username, and a password. If a connection is successful, a Connection object is created, which we've called con.
You can get the host address by looking at the Services tab on the left of NetBeans:
                         

The address of the highlighted database above is:
jdbc:derby://localhost:1527/Employees
The first part, jdbc:derby://localhost, is the database type and server that you're using. The 1527 is the port number. The database is Employees. This can all go in a String variable:
String host = "jdbc:derby://localhost:1527/Employees";
Two more strings can be added for the username and password:
String uName = "Your_Username_Here";
String uPass= " Your_Password_Here ";
Add these three string before the connection object and your code would look like this:
                       


As you can see in the image above, there is a wavy underline for the Connection code. The reason for this is because we haven't trapped a specific error that will be thrown up when connecting to a database - the SQLException error.
It's the DriverManager that attempts to connect to the database. If it fails (incorrect host address, for example) then it will hand you back a SQLException error. You need to write code to deal with this potential error. In the code below, we're trapping the error in catch part of the try … catch statement:
try {
}
catch ( SQLException err ) {
System.out.println( err.getMessage( ) );
}
In between the round brackets of catch, we've set up a SQLException object called err. We can then use the getMessage method of this err object.

Add the above try …catch block to your own code, and move your four connection lines of code to the try part. Your code will then look like this:
                       


Try running your code and see what happens.
You may get this error message in the console window:
"java.net.ConnectException : Error connecting to server localhost on port 1527 with message Connection refused: connect."
If you do, it means you haven't connected to your database server. In which case, right click on Java DB in the Services window. From the menu that appears, click Start Server:
                   

You need to make sure that any firewall you may have is not blocking the connection to the server. A good firewall will immediately display a message alerting you that something is trying to get through, and asking if you want to allow or deny it. When you allow the connection, your NetBeans output window should print the following message:
"Apache Derby Network Server - 10.4.1.3 - (648739) started and ready to accept connections on port 1527 at DATE_AND_TIME_HERE"
Once your server is started, run the programme again. There's a very good chance you'll get another error message:
"No suitable driver found for jdbc:derby://localhost:1527/Employees"
The reason for this error is that the DriverManager needs a Driver in order to connect to the database. Examples of drivers are Client Drivers and Embedded Drivers. You can import one of these so that the DriverManager can do its job.
Click on the Projects tab to the left of the Services window in NetBeans. (If you can't see a Projects tab, click Window > Projects from the menu bar at the top of NetBeans.)
Locate your project and expand the entry. Right-click Libraries. From the menu that appears, select Add Jar/Folder:
                 

When you click on Add Jar/Folder a dialogue box appears. What you're doing here is adding a Java Archive file to your project. But the JAR file you're adding is for the derby Client Drivers. So you need to locate this folder. On a computer running Windows this will be in the following location:
C:\Program Files\Sun\JavaDB\lib
The file you're looking for is called derbyclient.jar. If you can't find it, or are using an operating system other than Windows, then do a search for this file. Note the location of the file.
In the dialogue box, select the derbyclient.jar file:
                         

Click Open and the file will be added to your project library:
                       


Now that you have a Client driver added to your project, run your programme again. You should now be error free. (The Output window will just say Run, and Build Successful.)

Chapter 14.3 : SQL Command



SQL stands for Structured Query Language, and is a way to query databases. You can select records, insert, delete, and update records, create tables, drop tables, and more besides. It's quite a powerful tool.
SQL uses simple keywords to do the work. If you want to select all the records from a table, the words SELECT and FROM are used, along with the "all records" symbol, which is *:
SELECT * FROM table_name
If you look at the top half of the NetBeans window, you'll see that a SELECT statement has already been set up: (NOTE: SQL is not case sensitive)
select * from ADMIN.WORKERS
This says "Select all the records from the table called Workers". (The ADMIN part, before the dot of Workers, is something called a Schema. This describes the structure of the database, but also identifies things like users and the privileges they have. Don't worry about schemas, as we won't be going into them.)





In NetBeans, you run a SQL statement by clicking the Run button on the toolbar:
The results from the SQL statements are then displayed in the bottom half of the window:
               


The WHERE Clause

To narrow down your search results, you can use a WHERE clause with the SELECT statement:
SELECT * FROM table_name WHERE column_name=value
After the keyword WHERE you need the name of a column from your table. You then type an equals sign, followed by a value. As an example, here's a SQL statement that returns all the programmers in our table:
SELECT * FROM ADMIN.WORKERS WHERE JOB_TITLE='Programmer'
To try this SQL Statement out, right-click your table name in the Services area. From the menu that appears, select Execute Command:
                              

When you click on Execute Command, a new window appears. Type the above SQL Statement, and then click the Run icon:
                         

The results will be displayed in the bottom half of the window:
              

As you can see, two rows are returned from the query.
You can also use the keyword LIKE with the WHERE clause. This then replaces the equals sign. LIKE is usually used with a wildcard character. The wildcard character % means "any characters", for example, while an underscore is used for just a single character.
Instead of the equals sign or the keyword LIKE, you can also use the conditional operators (Greater Than, Less Than, etc.). If we had a salary column, we could search for all workers who are getting paid more than 1000 a week:
SELECT * FROM ADMIN.WORKERS WHERE SALARY > 1000

Exercise
Try running the following SQL Statement:
SELECT * FROM ADMIN.WORKERS WHERE JOB_TITLE LIKE '%er'
How many results are displayed?

We'll leave SQL Statements there, as we now have enough to start programming. Before doing so, however, close down the connection to your table by right clicking it in the Services are. From the menu, select Disconnect:
                     


We'll connect to this database and table again, using Java code this time

Chapter 14.2 : Adding Records to a Java Database Table



A database table is like a spreadsheet, in that it has rows and columns. Each row in our table has cells (fields) for an ID value, a First Name, a Last Name, and a Job Title. Shortly, you'll learn how to write code to add new rows of information to the table. But you can use the NetBeans IDE to add rows as well.
To add a new row to your table, right click on your table name. From the menu that appears, select View Data:







When you click on View Data, you'll see a new window appear in the main NetBeans window

You use the bottom half of window to enter new table rows. The top half is for SQL Commands. (You'll learn more about them soon, when we've finished adding rows.)
To add a new row, click the icon with the green plus symbol, in the bottom half of the window:

When your click the new row icon, a dialogue box appears:

As you can see, there are text boxes for each column in our table. For the ID column, we'll use sequential numbering, starting with 1. The second row in the table will then have an ID of 2, the third row 3, etc. The numbers are not the row numbers: they are just unique values for each ID field. We could have easily started with a value of 100 as the first ID number. The second number would then be 101, the third 102, etc.
Enter the following data as the first row of your table:
ID: 1
First Name: Helen
Last Name: James
Job Title: IT Manager
Your dialogue box will then look like this:


Click OK when you're done and you'll be returned to the NetBeans window. The first row should then be displayed:

Add three more rows with the following data:
ID: 2
First Name: Eric
Last Name: Khan
Job Title: Programmer
ID: 3
First Name: Tommy
Last Name: Lee
Job Title: Systems Analyst

ID: 4
First Name: Priyanka
Last Name: Collins
Job Title: Programmer

When you've finished adding the new rows, your NetBeans window should look like this one:



Wednesday 7 December 2016

Chapter 14.1 : Creating a Database with Java


Now that your server has been started, you can go ahead and create a database.
To create a new database, right click on Java DB again. From the menu that appears, select Create Database:
                                   

When you click on Create Database, you'll see a dialogue box appear:
                                           

Type a name for your database in the first box. Call it Employees. Type any User Name and Password (something a bit harder to crack than ours below!):
                   

Click OK to create your database. It should then appear on the list:
             


Creating a Table in the Database

Now that the database has been created, you need to create a table in the database. To do so, right click on your database. From the menu that appears select Connect:
                 

When a connection is made, you'll see some default folders for Tables, Views, and Procedures (see further down if your screen is not like this):
             

To create a new table in your database, right click the Tables folder. From the menu that appears, select Create Table:
                   

If you don't see just the three folders above, but have something like this instead:
                               

Click the APP entry, and then right-click on Tables.
When you click on Create Table, a dialogue box appears. Either this one:
                     

Or this one:
                       

From here, you not only type a name for your table, but you also set up the columns for the table.
In the Table Name at the top, delete the default name of Untitled. Type a new name for your table. Call it Workers. You'll then have a table called Workers, which is in the Employees database.
But you can't click OK just yet as the table has no columns in it. We want to create columns with the following names:
ID
First_Name
Last_Name
Job_Title
The ID column will hold a unique identifying number. This will identify a row in the table. A column with unique data in it is known as a Primary Key. Because it's the Primary Key, the column has to hold data: It can't hold a null value. (A null value just means there's no information there.)
If your Create Table dialogue box is like the first one, then put a tick in the box for Key. When you tick the Key box, check marks will also appear for Index and Unique. Now enter a title in the Column Name area. Type ID:
                     

You now need to specify what kind of data is going in to the column. For our ID column, we'll have Integers. So scroll along until you come to Data Type. Click on Data Type and a drop down list will appear. From the drop down list, select Integers:
                       

If your dialogue box is like the second one, then you need to click the Add Column button to add your first table column. You'll see another dialogue box appear. This one:
                     

The NAME is the name of the column in the table, like ID, First_Name, etc. The TYPE is the DATA TYPE, Integer, VARCHAR, etc. Click the dropdown list to see more. Then check or uncheck the CONSTRAINTS boxes as indicated below:
                       

Click OK and you should be returned to the Create Table dialogue box:
                             

We now have enough for the ID column in the table. Click the Add Column button on the right to add a new column to the table. Enter the following values for this column (VARCHAR means a variable number of characters):
Key: Unchecked
Index: Unchecked
Null: Unchecked
Unique: Unchecked
Column Name: First_Name
Data Type: VARCHAR
Size: 20
For the third column in your table, enter the following values:
Key: Unchecked
Index: Unchecked
Null: Unchecked
Unique: Unchecked
Column Name: Last_Name
Data Type: VARCHAR
Size: 20
For the final column, here are the values to enter:
Key: Unchecked
Index: Unchecked
Null: Unchecked
Unique: Unchecked
Column Name: Job_Title
Data Type: VARCHAR
Size: 40
When you're finished, your Table dialogue box should look like this:
                   

Click OK when you've entered all the information. Your table and table columns will then be created:

               

Chapter 13.0 : Java and Databases


About Java and Databases

Java uses something called JDBC (Java Database Connectivity) to connect to databases. There's a JDBC API, which is the programming part, and a JDBC Driver Manager, which your programmes use to connect to the database.
JDBC allows you to connect to a wide-range of databases (Oracle, MySQL, etc), but we're going to use the in-built database you get with the Java/NetBeans software. The database is called Java DB, a version of Apache Derby. It runs on a virtual server, which you can stop and start from within NetBeans.
To check that have everything you need, have a look at the Services tab in NetBeans. If you can't see the Services tab, click Window from the NetBeans menu. From the Window menu, select Services. You should see something like this:

Expand the Databases item to see a Java DB item, and a Drivers section:


The idea is that you start the Java DB virtual server, and then create and manipulate databases on the server. There should be a database called sample already set up: (But don't worry if it's not there as we'll create our own database.)
In the image above, there are three databases: one is called sample, one is called test1, and the other is called exams.
For the project in this section, we're going to set up a new database. You'll then learn how to connect to this database using Java code. The database we'll create will be a simple one-table affair, rather than multiple tables connected together. You can indeed create multiple tables with Java DB, but we don't want to complicate things unnecessarily.

Starting the Virtual Server

The first thing to do is to start the server. So right click on Java DB. You'll see a menu appear. Select Start Server:
                               

Have a look at the Output window and you'll see a few messages appear: (If you have a firewall running, you'll need to let the Java DB server through.)
                      


Once the server is up and running you can create databases. 

Chapter 12.3 : Creating Thread Objects: Implementing the run() Method in Runnable interface



import java.io.IOException;

class TryThread implements Runnable {
  public TryThread(String firstName, String secondName, long delay) {
    this.firstName = firstName;
    this.secondName = secondName;
    aWhile = delay;
  }
  public void run() {
    try {
      while (true) {
        System.out.print(firstName);
        Thread.sleep(aWhile);
        System.out.print(secondName + "\n");
      }
    catch (InterruptedException e) {
      System.out.println(firstName + secondName + e);
    }
  }
  private String firstName;
  private String secondName;
  private long aWhile;
}
public class MainClass {
  public static void main(String[] args) {
    Thread first = new Thread(new TryThread("A ""a "200L));
    Thread second = new Thread(new TryThread("B ""b "300L));
    Thread third = new Thread(new TryThread("C ""c "500L));
    System.out.println("Press Enter when you have had enough...\n");
    first.start();
    second.start();
    third.start();
    try {
      System.in.read();
      System.out.println("Enter pressed...\n");
    catch (IOException e) {
      System.out.println(e);
    }
    System.out.println("Ending main()");
    return;
  }
}
Create a second thread
class NewThread implements Runnable {
  Thread t;

  NewThread() {
    t = new Thread(this, "Demo Thread");
    System.out.println("Child thread: " + t);
    t.start(); // Start the thread
  }

  public void run() {
    try {
      for (int i = 5; i > 0; i--) {
        System.out.println("Child Thread: " + i);
        Thread.sleep(500);
      }
    catch (InterruptedException e) {
      System.out.println("Child interrupted.");
    }
    System.out.println("Exiting child thread.");
  }
}

class ThreadDemo {
  public static void main(String args[]) {
    new NewThread();
    try {
      for (int i = 5; i > 0; i--) {
        System.out.println("Main Thread: " + i);
        Thread.sleep(1000);
      }
    catch (InterruptedException e) {
      System.out.println("Main thread interrupted.");
    }
    System.out.println("Main thread exiting.");
  }
}
Create a second thread by extending Thread
class NewThread extends Thread {

  NewThread() {
    super("Demo Thread");
    System.out.println("Child thread: " this);
    start(); // Start the thread
  }

  public void run() {
    try {
      for (int i = 5; i > 0; i--) {
        System.out.println("Child Thread: " + i);
        Thread.sleep(500);
      }
    catch (InterruptedException e) {
      System.out.println("Child interrupted.");
    }
    System.out.println("Exiting child thread.");
  }
}

class ExtendThread {
  public static void main(String args[]) {
    new NewThread(); // create a new thread

    try {
      for (int i = 5; i > 0; i--) {
        System.out.println("Main Thread: " + i);
        Thread.sleep(1000);
      }
    catch (InterruptedException e) {
      System.out.println("Main thread interrupted.");
    }
    System.out.println("Main thread exiting.");
  }
}
Create multiple threads
class NewThread implements Runnable {
  String name; // name of thread

  Thread t;

  NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("New thread: " + t);
    t.start(); // Start the thread
  }

  public void run() {
    try {
      for (int i = 5; i > 0; i--) {
        System.out.println(name + ": " + i);
        Thread.sleep(1000);
      }
    catch (InterruptedException e) {
      System.out.println(name + "Interrupted");
    }
    System.out.println(name + " exiting.");
  }
}

class MultiThreadDemo {
  public static void main(String args[]) {
    new NewThread("One"); // start threads
    new NewThread("Two");
    new NewThread("Three");

    try {
      Thread.sleep(10000);
    catch (InterruptedException e) {
      System.out.println("Main thread Interrupted");
    }

    System.out.println("Main thread exiting.");
  }
}