In this example, the servlet is eliminated. An applet uses the JDataConnect type 3 driver to query a database running on a different host from the machine where the Web server is running. Variables within the applet are bound to specific database objects and interact with those objects directly through the driver.
The components involved in this three-tier example are shown in the figure, below.
Three- tier architecture. Shows browser communicating initially with WWW sever to load applet. Applet forms separate connection with type 3 JDBC driver (i.e., JDataConnect) which contacts its local ODBC registry for reference to particular database. Thereafter, applet interacts with the database through the driver using variables bound to particular database objects.
The code for the program is generated almost entirely by the Java development environment, VisualCafeDBE in this case. The only "manual code" in this example are the URL and driver statements, shown in bold, below.
Three classes are generated. An applet class includes the user interface and fields for representing and inputting data. A connection class sets up the interaction with the database through the driver. A database object class includes functions for querying and updating the database.
Once the applet is developed in the environment, it must be deployed. This means creating a jar file with the applet classes, writing or generating the html file that includes references to the applet jar file and other necessary jar files, and placing these files in a location where they can be accessed through a web server running on the same machine as the driver. However, there is one very awkward limitation in the current version of VisualCafeDBE: the client machine where the applet is run may not include it its classpath references to the VisualCafe jar files. If it does, the applet produces errors when it references the database.
Applet
An applet class includes the user interface and fields for representing and inputting data.
/* A basic extension of the com.sun.java.swing.JApplet class */ import com.sun.java.swing.*; import java.awt.*; import symantec.itools.db.beans.binding.BindingModel; import symantec.itools.db.swing.JDBStatusBar; import symantec.itools.db.beans.jdbc.QueryNavigator; import symantec.itools.db.swing.JDBToolBar; import symantec.itools.db.swing.models.ThreeDButtonsModel; public class JApplet1 extends JApplet { public void init() { // Take out this line if you don't use symantec.itools.net.RelativeURL or symantec.itools.awt.util.StatusScroller symantec.itools.lang.Context.setApplet(this); // This line prevents the "Swing: checked access to system event queue" message seen in some browsers. getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); // This code is automatically generated by Visual Cafe when you add // components to the visual environment. It instantiates and initializes // the components. To modify the code, only use code syntax that matches // what Visual Cafe can generate, or Visual Cafe may be unable to back // parse your Java file into its visual environment. //{{INIT_CONTROLS getContentPane().setLayout(null); setSize(506,266); plantsSQL_dbo_PlantsNavigator.setAutoStart(true); plantsSQL_dbo_PlantsNavigator.setSaveChangesWindowClass("symantec.itools.db.beans.binding.JSaveChangesWindow"); plantsSQL_dbo_PlantsNavigator.setClassName("plantsSQL_dbo_PlantsRecord"); //$$ plantsSQL_dbo_PlantsNavigator.move(25,0); plantsSQL_dbo_PlantsNavigator.setAliasName("plantsSQL_dbo_Plants_JApplet1_QNAlias"); //$$ threeDButtonsModel1.move(461,23); JDBToolBar1.setStyle(threeDButtonsModel1); JDBToolBar1.setQueryNavigatorObject(plantsSQL_dbo_PlantsNavigator); getContentPane().add(JDBToolBar1); JDBToolBar1.setBounds(0,23,456,55); JDBStatusBar1.setQueryNavigatorObject(plantsSQL_dbo_PlantsNavigator); getContentPane().add(JDBStatusBar1); JDBStatusBar1.setBounds(0,190,486,22); getContentPane().add(PlantID); PlantID.setBackground(java.awt.Color.white); PlantID.setBounds(110,81,100,20); PlantIDLabel.setText("PlantID"); getContentPane().add(PlantIDLabel); PlantIDLabel.setBounds(10,81,80,20); getContentPane().add(CommonName); CommonName.setBackground(java.awt.Color.white); CommonName.setBounds(110,104,200,20); CommonNameLabel.setText("CommonName"); getContentPane().add(CommonNameLabel); CommonNameLabel.setBounds(10,104,80,20); getContentPane().add(Genus); Genus.setBackground(java.awt.Color.white); Genus.setBounds(110,127,200,20); GenusLabel.setText("Genus"); getContentPane().add(GenusLabel); GenusLabel.setBounds(10,127,80,20); getContentPane().add(Location); Location.setBackground(java.awt.Color.white); Location.setBounds(110,150,200,20); LocationLabel.setText("Location"); getContentPane().add(LocationLabel); LocationLabel.setBounds(10,150,80,20); PlantIDBindingModel.setTriggeringEvent(symantec.itools.db.beans.binding.BindingModel.focusLost); PlantIDBindingModel.setDataBinding("plantsSQL_dbo_Plants_JApplet1_QNAlias@PlantID"); PlantIDBindingModel.setComponent(PlantID); //$$ PlantIDBindingModel.move(215,81); CommonNameBindingModel.setTriggeringEvent(symantec.itools.db.beans.binding.BindingModel.focusLost); CommonNameBindingModel.setDataBinding("plantsSQL_dbo_Plants_JApplet1_QNAlias@CommonName"); CommonNameBindingModel.setComponent(CommonName); //$$ CommonNameBindingModel.move(315,104); GenusBindingModel.setTriggeringEvent(symantec.itools.db.beans.binding.BindingModel.focusLost); GenusBindingModel.setDataBinding("plantsSQL_dbo_Plants_JApplet1_QNAlias@Genus"); GenusBindingModel.setComponent(Genus); //$$ GenusBindingModel.move(315,127); LocationBindingModel.setTriggeringEvent(symantec.itools.db.beans.binding.BindingModel.focusLost); LocationBindingModel.setDataBinding("plantsSQL_dbo_Plants_JApplet1_QNAlias@Location"); LocationBindingModel.setComponent(Location); //$$ LocationBindingModel.move(315,150); //}} } //{{DECLARE_CONTROLS symantec.itools.db.beans.jdbc.QueryNavigator plantsSQL_dbo_PlantsNavigator = new symantec.itools.db.beans.jdbc.QueryNavigator(); symantec.itools.db.swing.models.ThreeDButtonsModel threeDButtonsModel1 = new symantec.itools.db.swing.models.ThreeDButtonsModel(); symantec.itools.db.swing.JDBToolBar JDBToolBar1 = new symantec.itools.db.swing.JDBToolBar(); symantec.itools.db.swing.JDBStatusBar JDBStatusBar1 = new symantec.itools.db.swing.JDBStatusBar(); com.sun.java.swing.JTextField PlantID = new com.sun.java.swing.JTextField(); com.sun.java.swing.JLabel PlantIDLabel = new com.sun.java.swing.JLabel(); com.sun.java.swing.JTextField CommonName = new com.sun.java.swing.JTextField(); com.sun.java.swing.JLabel CommonNameLabel = new com.sun.java.swing.JLabel(); com.sun.java.swing.JTextField Genus = new com.sun.java.swing.JTextField(); com.sun.java.swing.JLabel GenusLabel = new com.sun.java.swing.JLabel(); com.sun.java.swing.JTextField Location = new com.sun.java.swing.JTextField(); com.sun.java.swing.JLabel LocationLabel = new com.sun.java.swing.JLabel(); symantec.itools.db.beans.binding.BindingModel PlantIDBindingModel = new symantec.itools.db.beans.binding.BindingModel(); symantec.itools.db.beans.binding.BindingModel CommonNameBindingModel = new symantec.itools.db.beans.binding.BindingModel(); symantec.itools.db.beans.binding.BindingModel GenusBindingModel = new symantec.itools.db.beans.binding.BindingModel(); symantec.itools.db.beans.binding.BindingModel LocationBindingModel = new symantec.itools.db.beans.binding.BindingModel(); //}} public void destroy() { //{{CLEANUP plantsSQL_dbo_PlantsNavigator.close(); //}} super.destroy(); } }Connection Manager
A connection class sets up the interaction with the database through the driver.
import symantec.itools.db.beans.jdbc.*; import java.sql.*; public class ConnectionMgr4 extends ConnectionManager { public ConnectionMgr4() { super(); init(); } public void init() { //{{INIT_CONTROLS jdbcConnection1 = new symantec.itools.db.beans.jdbc.JdbcConnection(); jdbcConnection1.setIdentifier("jdbcConnection1"); jdbcConnection1.setURL("jdbc:JDataConnect://jbspc-cs.cs.unc.edu/jbsPlantsSQL"); jdbcConnection1.setDriverName("JData1_2.sql.$Driver"); try { jdbcConnection1.setReadOnly(false); } catch (java.sql.SQLException e) { System.out.println(e.getMessage()); return; } add(jdbcConnection1); //$$ jdbcConnection1.move(0,0); //}} } //{{DECLARE_CONTROLS static symantec.itools.db.beans.jdbc.JdbcConnection jdbcConnection1; //}} }Database Object Class
A database object class includes functions for querying and updating the database.
import symantec.itools.db.beans.jdbc.*; import symantec.itools.db.beans.binding.*; import java.util.*; import java.sql.*; public class plantsSQL_dbo_PlantsRecord extends RecordDefinition { public static Statement m_InsertStatement=null; public Statement m_UpdateStatement=null; public Statement m_DeleteStatement=null; static DataModel m_DataModel = null; private static int counter = 0; public plantsSQL_dbo_PlantsRecord() { synchronized (getClass()) { if (counter == 0) { init(); } counter++; } } public void init() { //{{INIT_CONTROLS setConnectionManagerClassName("ConnectionMgr4"); setConnectionName("jdbcConnection1"); setTableName("PlantsSQL.dbo.plants"); addColumn("PlantID"); addColumn("CommonName"); addColumn("Genus"); addColumn("Location"); //}} } public synchronized void setDataModel(PersistentObjectModel model) { m_DataModel = (DataModel)model; } // getDataModel // Returns the data model for this class. // If the data model has not been generated call generateDataModel // generateDataModel executes a query and builds the data model from the result // If you want to customize the data model create it here instead of calling generate data model public synchronized PersistentObjectModel getDataModel() { if (m_DataModel == null) { try { m_DataModel = generateDataModel(); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } return m_DataModel; } // getInsertStatement // Returns a Statement object used to perform an INSERT operation. // If you want to customize the INSERT operation write your own code in this method. // If you bypass getStatement, you should also bypass setParameterValues, // since the parameters must be set in accordance with the Statement. protected synchronized Statement getInsertStatement() throws SQLException { PreparedStatement psmd = (PreparedStatement)m_InsertStatement; if (psmd==null) { psmd = getStatement(psmd,INSERT_SQL); } setParameterValues(psmd); return psmd; } // getUpdateStatement // Returns a Statement object used to perform an UPDATE operation. // If you want to customize the UPDATE operation write your own code in this method. // If you bypass getStatement, you should also bypass setParameterValues, // since the parameters must be set in accordance with the Statement. protected synchronized Statement getUpdateStatement() throws SQLException { PreparedStatement psmd=(PreparedStatement)m_UpdateStatement; psmd = getStatement(psmd,UPDATE_SQL); setParameterValues(psmd); setParameters(psmd,ORIGINAL_VALUE,getColModif(),false); return psmd; } // getDeleteStatement // Returns a Statement object used to perform an DELETE operation. // If you want to customize the DELETE operation write your own code in this method. // If you bypass getStatement, you should also bypass setParameterValues, // since the parameters must be set in accordance with the Statement. protected synchronized Statement getDeleteStatement() throws SQLException { PreparedStatement psmd=(PreparedStatement)m_DeleteStatement; if (psmd==null) { psmd = getStatement(psmd,DELETE_SQL); } setParameters(psmd,ORIGINAL_VALUE,0,false); return psmd; } // save // This is the top level method for performing a save. // If you want to customize DML you should write code in one of the above methods. // You should modify the code of this method if you want to add additional functionality. // For instance you may want to fire an event which indicates success or failure. public synchronized int save() { return super.save(); } protected void finalize() throws Throwable { synchronized( getClass()) { counter--; if (counter == 0) { releaseConnection(); } } super.finalize(); } //{{DECLARE_CONTROLS //}} }Applet HTML
Notice the three jar files inlcuded in the applet tag. They reference the applet, itself, the JDataConnect driver, and several Java Swing classes taht are required.
<HTML> <HEAD> <TITLE>Autogenerated HTML</TITLE> </HEAD> <BODY> <APPLET CODE="JApplet1.class" ARCHIVE="jbsVCJDCApplet.jar, swingall.jar, JData1_2.jar" WIDTH=506 HEIGHT=266></APPLET> </BODY> </HTML>