* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Data Aware Components - Java Notes
Survey
Document related concepts
Microsoft SQL Server wikipedia , lookup
Serializability wikipedia , lookup
Oracle Database wikipedia , lookup
Open Database Connectivity wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Functional Database Model wikipedia , lookup
Ingres (database) wikipedia , lookup
Extensible Storage Engine wikipedia , lookup
Concurrency control wikipedia , lookup
Microsoft Jet Database Engine wikipedia , lookup
Relational model wikipedia , lookup
Versant Object Database wikipedia , lookup
Clusterpoint wikipedia , lookup
Transcript
1|Page 10.4 Java Persistence This section is written with the help of Mike Scordilis and Shamiel Dramat who has spent considerable effort developing notes and programs on Java Persistence. The previous method of accessing and updating a database with the DB class provided a way of working with the database using SQL statements. All the SELECT and UPDATES to the database had to be written by the programmer and displayed in the GUI in components such as a text area. None of the GUI components were data aware meaning that the components are linked to data in the database. We can achieve this by means of persistence, which is an adjective that describes data that outlives the process that created it. In this context, this means that the data entered by the user in a GUI component is stored temporarily in an object in primary memory and then permanently in a database. There are many ways to access a relational database from Java. JPA (Java Persistence Application Program Interface) is just the latest of many different specifications. The Java Persistence API, sometimes referred to as JPA, is a Java programming language specification which describes the management of relational data in applications using the Java Platform. 10.4.1 Creating a Database in Java DB Java persistence can be achieved using the Java DB database which is provided in Netbeans. We need to find a way of converting our UniStudents database in MS Access into a Java DB database. We will do so by converting each table in the database into a spread sheet file and then saving the spread sheet in Comma Separated Values (CSV) format. A CSV file is a text file that has all the fields separated by a comma. This CSV file can then be imported into the Java DB database. ACTIVITY 10 Load the Unistudents database in MS Access. Right click on tblStudents in the left hand window and select Export and then select Excel. Browse to the place you can store the file and select Save then Close. Leave the file name as tblStudents. The table will be converted to a file in Excel. Note that Java DB has the following date formats: yyyy-mm-dd mm/dd/yyyy dd.mm.yyyy Change the date column into the format yyyy-mm-dd by selecting all the cells with dates (there are many), right clicking, selecting Format Cells.., the Number Tab and the choosing Date in the left window and then Type yyyy-mm-dd. 2|Page Open the Excel file called tblStudents and the convert it to CSV format by using File | Save As and selecting CSV as a file type in the drop down box. Excel will inform you there will be features that are not compatible, which is fine, so click on Yes effectively saving the file. Now we need to create a UniStudents database in Java DB. Open Netbeans and select the Services tab. Expand the Databases node and right click on the Java DB node. Select Start Server to start the service of the database Java DB. Right click on the Java DB node again and select Create Database…. Enter the name UniStudents as a name, root as the user name and nbuser as a password. Confirm the password as nbuser. Choose the path where the database will be stored. Click OK. The database UniStudents will be displayed in the Services window. 3|Page Connect to the database by right clicking on the database Unistudents and selecting Connect... The connection icon will be whole to show the database is connected. Expand the node of the tables and then the node of ROOT to view the tables. Right click on the table and select Execute Command… We need to create the table for the tblStudents using a SQL statement. 4|Page Type the following code in the Command Window. CREATE TABLE tblStudents( SCode VARCHAR (9) NOT NULL, SSName VARCHAR (40) NOT NULL, SFName VARCHAR (40) NOT NULL, BDate DATE, AcYear INTEGER NOT NULL, DP BOOLEAN, PRIMARY KEY (Scode) ); The above code declares each field in the table and selects a type for that field. Note that text data is VARCHAR followed by the maximum number of characters needed, a date is a DATE type, INTEGER for integers and BOOLEAN for boolean. Lastly the field that is to be the primary key is defined. Run the code by clicking on the play button on top of a database icon. Make sure you are running this SQL command against the UniStudents database as shown in the Connection drop down box. A new table should be defined under the ROOT node with fields shown. Now we can import that data from the CSV file into the table tblStudents. First open the CSV file in NOTEPAD and ensure that there are no headers and that the data is separated by commas and NOT semicolons. If it is separated by semicolons, use find and replace all semicolons by commas. 5|Page Type in the following command. The path in the fourth line must be the pat where the table is stored. Note that the name of the table in the second line must be in capitals. The command uses SYSCS_UTIL.SYSCS_IMPORT_TABLE to import the table. CALL SYSCS_UTIL.SYSCS_IMPORT_TABLE ( null, 'TBLSTUDENTS', 'C:\Data\CSV Files\tblStudents.csv', ',', null, null, 0 ); Click the database run button to execute the command. Once the command has executed successfully, right click on the table and select View Data... to generate the SELECT statement in a new window to view the table. 6|Page EXERCISE 5 1. Using the database UniStudents, create tables and import the data for the following tables: 1.1. tblFaculties 1.2. tblStudentSubjectMarks 1.3. tblSubjectDescriptors 10.4.2 Creating a Netbeans Project with Data Aware Controls We need to create a project in Netbeans that can view the tables in the database as well as be able to scroll through each record in a database. We will need to link or bind the components on the GUI to the database tables we created in Java DB. When a component such as a text field is linked to a field in a database the component is said to be data aware. ACTIVITY 11 Create a new Java Application project in Netbeans project called UniStudentsJavaDB. Uncheck Create Main Class. Right click on the project and set it as the main project. (This may be located in the Run menu). Right click on the project and create a new package using your surname. In the Services tab, right click on the Java DB node and start the server if it is not already started. Create a JFrame called UniStudentsGUI by right clicking on the project. Remember to put the JFrame in the package. 10.4.2.1 Creating a Tabbed Pane and a Table Drag a Tabbed Pane component from the Swing Containers on the JFrame form. Drag a Panel onto the Tabbed Pane. Change the text on the Panel to be Students Table. Change the name of the Panel to pnlStudentsTable. Drag a Table onto the form and rename it jTblStudents to differentiate from the TBLSTUDENTS in the database. 7|Page To bind the records in the TBLSTUDENTS in the database, right click on the table and select Bind and then elements. Click on the button Import Data to Form… Select the database UniStudents for the Database Connection and the TBLSTUDENTS Database Table using the drop down boxes. Click OK and then use the up and down arrows to reverse the order of the fields in the Selected Window. 8|Page Click OK and you should see the fields listed as the headers in the table. 10.4.2.2 Creating a Persistence Unit to Synchronise Data Later on we are going to create text fields and populate the fields with data from a database. Previously the programmer had to write all to code to perform these functions. With the beans binding library these tasks are simplified and standardised. You can merely write a few lines of code to establish which properties of which components need to be synchronised, and the beans binding library handles the rest. The Java Persistence API (JPA) is used to perform object-relational mapping between the database and User Interface. A JPA entity class is a POJO (Plain Old Java Object) class, i.e. an ordinary Java class that is marked as having the ability to represent objects in the database. We will now create a persistence unit and the entity classes. ACTIVITY 12 Right click on the project UniStudentsJavaDB and select New Persistence Unit. If you cannot find the Persistence Unit click Other and select Persistence in the Categories window. Select the database in the drop down box listing the Database Connections and select None for Table Generation Strategy. A new package will be created called META-INF which stores the information about the project. The persistence unit file is created to store the details of the connection between the database and the project. Note that a TblStudents class has been created for you when we bound the table jTblStudents to the table TBLSTUDENTS in the database. 9|Page 10.4.2.3 Generating Entity Classes from the Database We need to create a class to store each record in the database tables. The structure of the class is the same as the fields of the table in the database. These classes represent a row in the table stored in secondary memory as an object in primary memory. Fortunately Netbeans can do this for us. ACTIVITY 13 Right click on the project and select Entity Classes from Database. Using the Persistence Unit, Netbeans is able to list all the tables that are available in the database. Click Add All to move all the tables into the Selected Tables Window then click next. Uncheck the check box Generate JAXB Annotations. 10 | P a g e Use the drop down box to choose java.util.List as a Collection Type. Instead of using an array of object to store all the records in the table, Java will use a List. A List type is similar to an array, but is more flexible as we don’t need to remember how many items are in the array. The List can expand and contract in size as need be and is considered to be dynamic as it can alter its number of elements while the program is running, while an array is static since once it is declared to be of a certain number of elements, it cannot change. Click Finish to complete the process. You should see all the classes listed in the package. 11 | P a g e 10.4.2.4 Dealing with Boolean Types The type boolean is represented as Serializable when the class TblStudents was created. We need to alter the dp field to be of type boolean. ACTIVITY 14 Open the TblStudents class and scroll down until you find the declaration for the dp field. private Serializable dp; Change the type to be boolean. private boolean dp; Scroll down to find the accessor and mutator methods. Change Serializable to boolean. You will need to do this in three places. public boolean getDp() { return dp; } public void setDp(boolean dp) { boolean oldDp = this.dp; this.dp = dp; changeSupport.firePropertyChange("dp", oldDp, dp); } 10.4.2.5 Viewing One Record We are going to create a new tab in the tabbed pane to display each record of the table TBLSTUDENTS. We will add buttons to allow the user to move forward and backwards through each record. ACTIVITY 15 Add a new tab to the tabbed pan by dragging a new Panel component onto the tabbed pane. Make sure it docks to the existing tabbed pane. Change the text to Student Records. Add in text fields and labels to store the fields SCODE, SSAME, SFNAME and ACYEAR of a record in the table TBLSTUDENTS. Rename each field appropriately. Drag a Formatted Field from the Swing Controls window to store the date value. Rename this field txffBirthDate. Drag Radio Button from the Swing Controls window for the DP field. Rename the Radio Button radDP. 12 | P a g e Scode, Surname, First Name and Academic Year are all text fields. Birth Date is a Formatted Text Field. A Radio Button is used to store a boolean value for the DP field. Add four buttons to scroll through the records in the table TblStudents. Edit the text on each button so that they display First, Previous, Next and Last. Rename each button btnFirst, btnPrevious, btnNext, btnLast. 10.4.2.6 Adding Code to the GUI to Enable Components to be Bound to Fields in a Database Before we can bind a component to a field in the database, we need to add code to the GUI. We need to declare an object of the table in the GUI class that will represent the fields in the database and a List which will store ALL the records of the table in primary memory. ACTIVITY 16 Switch to the source code for the UniStudentsGUI class and add in two fields. One to represent a row of the table and one to store all the rows of the table. import java.util.ListIterator; /** * * @author Delia */ public class UniStudentsGUI extends javax.swing.JFrame { Tblstudents student; ListIterator<Tblstudents> iterator; Declare an object student of type TblStudents and a ListIterator that will be used to traverse the ordered collection of Tblstudents objects. Netbeans should ask you to import the ListIterator class. Add in an accessor and mutator methods to access student object. public Tblstudents getStudent() { //get-method return student; } 13 | P a g e public void setStudent(Tblstudents student) { //set-method Tblstudents oldStudent = this.student; this.student = student; firePropertyChange("student", oldStudent, student); } The mutator method is designed to update the student object using a new student object that is passed as a parameter. The old student needs to be saved as the firePropertyChange method needs both the old and new objects to be sent as parameters. Add two lines of code to the constructor method to set the iterator to just before the first element in the list. The second line moves the pointer to the first element in the list and sends the student record to the mutator method which fires the change in records to the current record in the list. public UniStudentsGUI() { initComponents(); iterator = tblstudentsList.listIterator(0); setStudent(iterator.next()); } 10.4.2.7 Binding Components to Fields of a Table in a Database We need to bind each text field, formatted field and Radio Button in the Student Record tab to a field in the database. Since we have created a student object in the form to store a record of table TBLSTUDENTS, this object will allow us to select the fields of the object when binding GUI components to the fields in the database. ACTIVITY 17 Right click on the text field we named txfScode. You would have named it something similar. Select Bind and then text. Select the binding source to be the Form, scroll down to the student object and expand it to select the scode field. Repeat the process for Surname, First Name and Academic Year fields. Right click on the Formatted Field for the Birth Date and select Bind then value. Choose the bdate field in the student node after selecting Form for the Binding Source. 14 | P a g e Repeat the process for the DP field but choose Bind then selected after right clicking on the Radio Button radDP. Compile and run the project. Select the Student Record tab. You should see the first record of the table Tblstudents displayed in the fields. 10.4.2.8 Adding Code for the First, Previous, Next and Last Buttons Add code for the Previous and Next buttons to scroll through the records in the table. ACTIVITY 18 Right click on both the Previous and Next buttons and create event handlers for each button. Add code the following code for the Next and Previous button’s event handlers. private void btnPreviousActionPerformed (java.awt.event.ActionEvent evt) { if (iterator.hasPrevious()) { setStudent(iterator.previous()); } } private void btnNextActionPerformed(java.awt.event.ActionEvent evt) { if (iterator.hasNext()) { setStudent(iterator.next()); } } Add the code for the First and Last buttons. private void btnLastActionPerformed(java.awt.event.ActionEvent evt) { iterator = tblstudentsList.listIterator(tblstudentsList.size()); setStudent(iterator.previous()); } private void btnFirstActionPerformed(java.awt.event.ActionEvent evt) { iterator = tblstudentsList.listIterator(0); setStudent(iterator.next()); } Compile and run this project. You should be able to scroll through each record and move to the first and last record using the buttons. EXERCISE 6 15 | P a g e 1. Add three more tabs to the UniStudentsJavaDB Project to view each table in the UniStudents database. Use a jTable component for each table in the database. Each tab must show a record of one table. 10.4.2.9 Adding Code to Search, Delete, Insert and Update Records in the Database The following code and text is provided courtesy of Mike Scordilis. Search The Search button will input a student’s surname and display the entire record in the fields of the Student Record panel. ACTIVITY 19 Add the following code for the Search button's event handler. private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) { iterator = tblstudentsList.listIterator(0); String person = (JOptionPane.showInputDialog (null, "Enter surname")); boolean found = false; // Return a message if item not found int i = 0; while (i < tblstudentsList.size()&& found == false) { setStudent(iterator.next()); if (student.getSsname().equalsIgnoreCase(person)) found = true; i++; } //end for if (found == false) JOptionPane.showMessageDialog(null, "Not found"); } Compile and run the project to check that you can Search for a record given the surname of a student. The above code initialises the iterator pointer to point before the first element. The surname of the person to be searched for is entered and the while loop is used to sequentially process the List in a similar we did for an array. If the record is found it will be shown in the field components as a result of the setStudent method calling the firePropertyChange method to update the field components. Insert We need to input the data for the record to be added using the GUI. This data must be written to the object in primary memory and then the object is saved to the database using the EntityManager class of the database. Secondary Storage Primary Memory 16 | P a g e Object containing data. Object exists in memory. No object exists in the database. Object created outside of DB. Begin a transaction. Empty object exits in database. Make the object persistent. Object and its data stored in the database. Commit the transaction. Object stored in database. EntityManager.getTransaction().begin(); EntityManager.persist(object); EntityManager.getTransaction().commit(); ACTIVITY 20 Add the following code for the Insert button's event handler. private void btnInsertActionPerformed(java.awt.event.ActionEvent evt) { Tblstudents stud = new Tblstudents(); //tblstudent object stud.setScode(txfSCode.getText()); Use the values in the GUI components to assign the values of the fields of the stud.setSsname(txfSurname.getText()); stud.setSfname(txfFirstName.getText()); stud object. stud.setAcyear(Integer.parseInt(txfAcYear.getText())); stud.setDp(radDP.isSelected()); String startDate = txffBirthDate.getText(); // "201301-02" SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); try { Date date = null; date = sdf1.parse(startDate); stud.setBdate(date); System.out.println(date); } catch (ParseException ex) { } Convert the format of the date. Write the object stud in primary memory to the database in secondary memory. UniStudentsPUEntityManager.getTransaction().begin(); UniStudentsPUEntityManager.persist(stud); UniStudentsPUEntityManager.getTransaction().commit(); iterator = tblstudentsList.listIterator(0); Display the first record in the GUI components 17 | P a g e setStudent(iterator.next()); tblstudentsList.clear(); tblstudentsList.addAll(tblstudentsQuery.getResultList()); Clear the list in primary memory and update with new inserted record. } Compile and run the project to check that you can Insert a record. If you encounter a run time error, check how the fields of the table were created. Delete The following code will Delete a record given a student’s unique code as input. ACTIVITY 21 Add the following code for the Delete button's event handler. private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) { Input the student’s code. try { String idStr = JOptionPane.showInputDialog (null, "Enter Student Code"); Tblstudents stud = UniStudentsPUEntityManager. find(Tblstudents.class, idStr); Use the find method to locate the record to be deleted and assign to the object stud. Remove the record from the database. UniStudentsPUEntityManager.getTransaction().begin(); UniStudentsPUEntityManager.remove(stud); UniStudentsPUEntityManager.getTransaction().commit(); UniStudentsPUEntityManager.clear(); tblstudentsList.addAll(tblstudentsQuery.getResultList()); iterator = tblstudentsList.listIterator(0); setStudent(iterator.next()); tblstudentsList.clear(); tblstudentsList.addAll(tblstudentsQuery.getResultList()); JOptionPane.showMessageDialog(null, "Delete Completed"); } catch (Exception e) { System.out.println(e); } } 18 | P a g e Compile and run the project to check that you can Delete a record given the student code. Update If a user wishes to change or edit the fields of a record, they can use the Update button. Since the Scode is a primary key it cannot be changed. ACTIVITY 22 Add the following code for the Update button's event handler. private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) { int option = JOptionPane.showConfirmDialog(null, "Update Field(s) ?"); //0 = yes, 1 = no 2 = cancel if (option == 0) { Tblstudents stud = new Tblstudents(); //tblstudent object stud.setSsname(txfSurname.getText()); stud.setSfname(txfFirstName.getText()); stud.setAcyear(Integer.parseInt(txfAcYear.getText())); stud.setDp(radDP.isSelected()); String startDate = txffBirthDate.getText(); // "201301-02" SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); try { Date date = null; date = sdf1.parse(startDate); stud.setBdate(date); System.out.println(date); } catch (ParseException ex) { } UniStudentsPUEntityManager.getTransaction().begin(); UniStudentsPUEntityManager.getTransaction().commit(); UniStudentsPUEntityManager.clear(); tblstudentsList.addAll(tblstudentsQuery.getResultList()); } } Compile and run the project to check that you can Update the fields of a record except for the primary key. EXERCISE 7 19 | P a g e 1. Add another tab to view the TBLSTUDENTSUBJECTMARKS. 1.1. Use labels and text fields to display each field of a record of the database. 1.2. Include buttons First, Previous, Next and Last. 1.3. Include buttons to Search, Delete, Insert and Update the fields of the records.