Using data modules to simplify data access

Database application development is a feature of JBuilder Professional and Enterprise. Distributed application development is a feature of JBuilder Enterprise.

A data module is a specialized container for data access components. Data modules simplify data access development in your applications. Data modules offer you a centralized container for all your data access components. This enables you to modularize your code and separate the database access logic and business rules in your applications from the user interface logic in the application. You can also maintain control over the use of the data module by delivering only the .class files to application developers.

Once you define your DataSet components and their corresponding Column components in a data module, all applications that use the module have consistent access to the data sets and columns without requiring you to recreate them in every application each time you need them. Data modules do not need to reside in the same directory or package as your project. They can be stored in a location for shared use among developers and applications.

DataModule is an interface which declares the basic behavior of a data module. To work with this interface programmatically, implement it in your data module class and add your data components.

When you create a data module and add any component that would automatically appear under the Data Access section of the content pane (Database, DataSet, DataStore), a getter() method is generated. This means that any of these components will be available in a choice list for the project that references the data module. This means, for example, that you can

This chapter discusses two ways to create a data module:


Creating a data module using the design tools

Create the data module with the wizard

To create a data module,

  1. Create a new project.
  2. Select File|New and double-click the Data Module icon.

  3. Specify the package and class name for your data module class. JBuilder automatically fills in the Java file name and path based on your input. To create the data module using the JBuilder designer, deselect Invoke Data Modeler.

  4. Click the OK button to close the dialog. The data module class is created and added to the project.

  5. Double-click the data module file in the project pane to open it in the content pane.

  6. View the source code.

    You'll notice that the code generated by the wizard for the data module class is slightly different than the code generated by other wizards. The getDataModule() method is defined as public static. The purpose of this method is to allow a single instance of this data module to be shared by multiple frames. The code generated for this method is:

    
    public static DataModule1 getDataModule() {
        if (myDM == null){
          myDM = new DataModule1();}
        return myDM;
      }
    
    The code for this method

    The data module class now contains all the necessary methods for your custom data module class, and a method stub for the jbInit() to which you add your data components and custom business logic.

Add data components to the data module

To customize your data module using the UI designer,
  1. Double-click the data module file in the project pane to open it in the content pane.
  2. Select the Design tab of the content pane to activate the UI designer.
  3. Add your data components to your data module class. For example,
    1. Select a Database component from the Data Express tab of the component palette.
    2. Click in the component tree or the UI designer to add the Database component to the DataModule.
    3. Set the connection property using the database connectionDescriptor. Setting the connection property in the Inspector is discussed in "Connecting to a database".
The data components are added to a data module just as they are added to a Frame file. For more information on adding data components, see "Retrieving data from a data source".

Note: JBuilder automatically creates the code for a public method that "gets" each DataSet component you place in the data module. This allows the DataSet components to appear as (read-only) properties of the DataModule. This also allows DataSet components to be visible to the dataSet property of data-aware components in the Inspector when data-aware component and data modules are used in the same container.

After you have completed this section, your data module file will look similar to this:


package datamoduleexample;

import com.borland.dx.dataset.*;
import com.borland.dx.sql.dataset.*;

public class DataModule1 implements DataModule{
  private static DataModule1 myDM;
  Database database1 = new Database();
  public DataModule1() {
    try {
      jbInit();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
  private void jbInit() throws Exception{
    database1.setConnection(new
		com.borland.dx.sql.dataset.ConnectionDescriptor("
		jdbc:borland:dslocal:/usr/local/jbuilder/samples/JDataStore/
		datastores/employee.jds", "your name", "", false,
		"com.borland.datastore.jdbc.DataStoreDriver"));
   }
  public static DataModule1 getDataModule() {
    if (myDM == null)
      myDM = new DataModule1();
    return myDM;
  }
  public com.borland.dx.sql.dataset.Database getDatabase1() {
    return database1;
  }
}

Adding business logic to the data module

Once the data components are added to the data module and corresponding properties set, you can add your custom business logic to the data model. For example, you may want to give some users the rights to delete records and not give these rights to others. To enforce this logic, you add code to various events of the DataSet components in the data module.

Note: The property settings and business logic code you add to the components in the data model cannot be overridden in the application that uses the data model. If you have behavior that you do not want to enforce across all applications that use this data model, consider creating multiple data models that are appropriate for groups of applications or users.

To add code to the events of a component,

  1. Double-click the data module file in the project pane to open it in the content pane.
  2. Select the Design tab of the content pane to activate the UI designer.
  3. Select the component to which you want to add business logic, then click the Events tab in the Inspector.
  4. Double-click the event where you want the business logic to reside. JBuilder creates a stub in the .java source file for you to add your custom business logic code.

Using a data module

To use a data module in your application, it must first be saved and compiled. In your data module,

  1. Select File|Save All. Note the name of the project, the package, and the data module.
  2. Compile the data module class by selecting Run|Make Project. This creates the data module class files in the directory specified in Project|Project Properties, Output Path.
  3. Select File|Close.

To reference the data module in your application, you must first add it to your project as a required library.

Adding a required library to a project

These general instructions for adding a required library use a data module as a specific example, but the same steps can be used to add any required library. A library could be a class file, such as a data module, or an archive, such as a .jar file.

Select Project|Project Properties. Select Required Libraries from the Paths tab, and add the class or archive file for the new library. In the specific case of adding a data module, this will be the data module .class file you just compiled. To do this,

  1. Click Add.
  2. Click New.
  3. Enter the name for the library (like Employee Data Module).
  4. Select the location where you want your <library name>.library file to go. You have a choice between JBuilder, Project, and User Home. If you are running JBuilder from a network, and you want your library to be accessible to everyone, you should select JBuilder. This will put your <library name>.library file in your /lib folder within your JBuilder installation. If you are the only developer that needs access to your library, you may want to choose one of the other options, so the .library file will be stored locally.
  5. Click Add.
  6. Browse to the folder which contains the path to the class file or archive you wish to add. JBuilder automatically determines the paths to class files, source files, and documentation within this folder.
  7. Click OK.
  8. Click OK.
  9. Click OK.
  10. At this point you should see your new library added to the list of required libraries.

Referencing a data module in your application

Now that you have added the data module as a required library, here are the remaining steps for referencing a data module in your application:
  1. Select File|New. Select Application. Enter the appropriate package and class information. (Optionally, open an existing project using File|Open).
  2. Select the application's Frame file in the content pane.
  3. Make sure Data Express is specified as one of the Required Libraries. If Data Express is not listed under Required Libraries in the Project Properties,
    1. Click Add.
    2. Select Data Express.
    3. Click OK until the Project Properties dialog is closed.
  4. Import the package that the data module class belongs to (if it is outside your package) by selecting Wizards|Use Data Module.
  5. Click the ellipsis to open the Select Data Module dialog. A tree of all known packages and classes is displayed. Browse to the location of the class files generated when the data module was saved and compiled (this should be under a node of the tree with the same name as your package, if the data module is part of a package). Select the data module class. If you do not see the data module class here, check to make sure the the project compiled without errors and that it was properly added to the required libraries for the project.
  6. Click OK. If you get an error message at this point, double check the required libraries in the project properties, and the location of the class file for your data module.

Click the Design tab to open the UI designer; the instance of the data module appears in the content pane. Clicking the entry for the data module does not display its DataSet components nor its Column components. This is intentional to avoid modification of the business logic contained in the data module from outside.

When designing your application, you'll notice that the dataSet property of a UI component includes all the DataSetView and StorageDataSet components that are included in your data module. You have access to them even though they are not listed separately in the content pane.

If you have a complex data model and/or business logic that you don't want another developer or user to manipulate, encapsulating it in a reusable component is an ideal way to provide access to the data but still enforce and control the business logic.

Understanding the Use Data Module dialog

When you select Wizards|Use Data Module, you will see the following dialog:

Select a data module by clicking the ellipsis in the DataModule class field. A tree of all known packages and classes is displayed. If you do not see your DataModule class in this list, use Project|Project Properties to add the package or archive to your libraries. Browse to the location of the class files generated when the data module was saved and compiled. Select the data module class.

In the Java Field Declaration box, the default field name is the name of the data module, followed by a "1". It is the name which will be used for the member variable to generate in code. The data module will be referred to by the name given in the component tree. Select a name that describes the data in the data module, such as EmployeeDataModule.

You can choose from the following ways of using the DataModule in your application:

Click OK to add the data module to the package and inject the appropriate code into the current source file to create an instance of the data module.

Based on the choices shown in the dialog above, the following code will be added to the jbInit() method of the Frame file. Note that Share (Static) Instance of Data Module is selected:

dataModule12 = com.borland.samples.dx.datamodule.DataModule1.getDataModule();

If Create New Instance Of DataModule is selected, the following code will be added to the jbInit() method of the Frame file:

dataModule12 = new com.borland.samples.dx.datamodule.DataModule1();

If Caller sets instance with SetModule() is selected, a setModule() method is added to the class being edited.