Example 7.2 shows the Java code for the DatabaseItem interface. This base class provides slots for a global java.sql.Connection object and for a validity flag. The global Connection is used for all transactions made by the data objects with the database to retrieve or update their data. The DatabaseItem interface also includes two abstract methods: updateToDbase() and updateFrom-Dbase(). These have to be implemented in subclasses to perform the necessary database transactions to store the object’s data to the database, and to retrieve the object’s current data from the database, respectively. Anytime during the lifetime of a DatabaseItem, its updateFromDbase() method can be called to refresh the local data from the database, or its updateToDbase() method can be called to update the database with the local data.
// This constructor is used to create a representation
// of a constraint in the database.
public TimeConstraint(int type, int tid1, int tid2,
boolean insert) {
ctype = type;
task1 = tid1;
task2 = tid2;
if (insert) {
// Create a new record in the database.
try {
Statement s = DatabaseItem.dbConn.createStatement();
int numr = s.executeUpdate("INSERT INTO time_constraint "
+ "(type, task1, task2) VALUES ("
+ type + ", " + task1 + ", " + task2 + ")");
if (numr != 1)
valid= false;
else
valid= true;
}
catch (SQLException e) {
valid= false;
}
}
}
public int getTask1Id() { return task1; }
public int getTask2Id() { return task2; }
public int getType() { return ctype; }
static public Vector constraintsFor(int tid) {
Vector constraints = new Vector();
try {
Statement s = DatabaseItem.dbConn.createStatement();
ResultSet r = s.executeQuery("SELECT task1, task2, type FROM "
+ "time_constraint where task1 = "
+ tid + " or task2 = " + tid);
while (r.next()) {
int tid1 = r.getInt("task1");
int tid2 = r.getInt("task2");
int type = r.getInt("type");
TimeConstraint c = new TimeConstraint(type, tid1, tid2,
false);
constraints.addElement(c);
}
}
catch (Exception e) {}
return constraints;
}
// This class represents non-indexed table data, so we can't
// load or update one uniquely from the database
public boolean updateFromDbase() { return false; }
public boolean updateToDbase() { return false; }
}
Example 7-6. Resource Assignment Object
package dcj.examples.dbase;
import java.sql.*;
import java.util.Vector;
import java.util.Date;
class ResAssignment extends DatabaseItem {
int rid;
int tid;
Date timestamp;
ResAssignment(int res, int task, Date time, boolean insert) {
rid= res;
tid= task;
timestamp = time;
if (insert) {
// Create a new record in the database.
try {
Statement s = DatabaseItem.dbConn.createStatement();
int numr = s.executeUpdate("INSERT INTO res_assignment "
+ " (resource, task, time) VALUES ("
+ rid + ", " + tid + ", " + time + ")");
if (numr != 1)
valid= false;
else
valid= true;
}
catch (SQLException e) {
valid= false;
}
}
}
public int getResourceId() { return rid; }
public int getTaskId() { return tid; }
public Date getTimeStamp() { return timestamp; }
static public Vector assignmentsFor(int rid) {
Vector ras = new Vector();
try {
Statement s = DatabaseItem.dbConn.createStatement();
ResultSet r = s.executeQuery("SELECT task, time FROM "
+ "res_assignment where resource = "
+ rid);
while (r.next()) {
int tid= r.getInt("task");
Date time = r.getDate("time");
ResAssignment ra = new ResAssignment(rid, tid, time, false);
ras.addElement(ra);
}
}
catch (Exception e) {}
return ras;
}
// This class represents non-indexed table data, so we can't
// load or update one uniquely from the database
public boolean updateFromDbase() { return false; }
public boolean updateToDbase() { return false; }
}
复制代码
With these data objects defined, we can now use them in several distributed application contexts to access local and remote schedule databases. If the schedule database is local, then we simply need to have the JDBC drivers for the DBMS on our class path when we run an application built against these objects. The application will create a java.sql.Connection object with the name of the local database and use it to initialize all schedule-related objects. If we want to put the database on a remote server, then we have two ways to connect these data objects to the database. If the native DBMS interface provides a network interface and if the JDBC drivers we are using support this vendor-specific network interface, then we can install the DBMS network interface and modify the URL used to create the JDBC connection to the database to reflect the remote location. If this is not an option, either because the DBMS has no network interface, or because we cannot use the DBMS network interface on the client machine for some reason, then we have the option of using JDBC drivers with their own network protocol (as we discussed in an earlier section). The database host machine would need to have the corresponding server drivers installed, including the drivers that speak the native DBMS interface protocol.