Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
752 KB
Nội dung
Chapter 4:Introduction to JDBC
-149-
2. Set a new value for each column in the row by using the appropriate update method.
3. Call the method insertRow() to insert the new row into the result set and, simultaneously, into the
database.
Listing 4-9 demonstrates the use of the UpdatableResultSet to insert a new row into a
database.
Listing 4-9: Using UpdatableResultSet to insert a new row
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection ("jdbc:odbc:Contacts");
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(query);
rs.moveToInsertRow();
rs.updateInt("Contact_ID", 150);
rs.updateString("First_Name", "Nigel");
rs.updateString("Last_Name", "Thornebury");
rs.insertRow();
If you insert a row without supplying a value for every column in the row, the default
value for the column will be used if there is one. Otherwise, if the column accepts
SQL NULL values, a NULL will be inserted. Failing either of those, a SQLException
will be thrown.
You will also get a SQLException if a required table column is missing in the
ResultSet you use to insert the row, so the query used to get the ResultSet object
should generally select all columns, though you will probably want to use a WHERE
clause to limit the number of rows returned by your SELECT statement.
Caution
If you move the cursor from the insert row before calling the method
insertRow(), you will lose all
of the values you have added to the insert
row.
To move the cursor from the insert row back to the result set, you can use any of the
methods that put the cursor on a specific row: first, last, beforeFirst, afterLast, and
absolute. You can also use the methods previous and relative because the result set
maintains a record of the current row while accessing the insert row.
In addition, you can use a special method: moveToCurrentRow(), which can be called
only when the cursor is on the insert row. This method moves the cursor from the
insert row back to the row that was previously the current row.
TEAMFLY
Team-Fly
®
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-150-
Deleting a Row
Deleting a row in an UpdatableResultSet is very simple. All you have to do is move
the cursor to the row you want to delete and call the method deleteRow().
The example in the following code snippet shows how to delete the third row in a
result set by getting the ResultSet object, moving the cursor to the third row, and
using the deleteRow() method:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection ("jdbc:odbc:Contacts");
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(query);
rs.absolute(3);
rs.deleteRow();
Caution
Be aware that different JDBC drivers handle deletions in different ways.
Some remove a deleted row so that it is no longer visible in a result set,
and others insert a blank row where the deleted row used to be.
When you make a change to a ResultSet, the change may not necessarily be visible.
The next section explains the reasons.
Seeing Changes in ResultSets
Changes made to a ResultSet are not necessarily visible, either to the ResultSet itself
or to other open transactions. In this context, the terms visible and not visible have
the following meanings:
§ An update is visible if the updated value can be retrieved by calling the appropriate getter method
after making an update.
§ An update is not visible if the getter method still returns the initial column value.
Similarly, an inserted row is visible if it appears in the ResultSet after calling
insertRow(). Deletions are visible if deleted rows are either removed from the result
set or if deleted rows leave a hole in the result set.
There are a number of factors affecting the visibility of changes, including the
following:
§ JDBC driver implementation
§ Transaction isolation level in effect
§ Result-set type
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-151 -
An application can determine if the changes a result set makes are visible to the
result set itself by calling these DatabaseMetaData methods:
§ ownUpdatesAreVisible(int ResultSet.TYPE_XXX)
§ ownDeletesAreVisible(int ResultSet.TYPE_XXX)
§ ownInsertsAreVisible(int ResultSet.TYPE_XXX)
The DatabaseMetaData interface also provides the following methods that allow an
application to determine whether a JDBC driver can detect changes for a particular
result-set type:
§ insertsAreDetected(ResultSet.TYPE_XXX)
§ deletesAreDetected(ResultSet.TYPE_XXX)
§ updatesAreDetected(ResultSet.TYPE_XXX)
If these methods return true, the following methods can be used to detect changes to
a ResultSet:
§ wasInserted()
§ wasDeleted()
§ wasUpdated()
Remember that if you modify data in a ResultSet object, the change will always be
visible if you close the ResultSet and reopen it by executing the same query again
after the changes have been made.
Another way to get the most recent data is to use the method refreshRow(), which
gets the latest values for a row straight from the database. This is done by positioning
the cursor to the desired row and calling refreshRow(), as shown here:
rs.absolute(3);
rs.refreshRow();
Note
The result set should be TYPE_SCROLL_SENSITIVE; if you use the
method refreshRow() with a ResultSet object that is
TYPE_SCROLL_INSENSITIVE, refreshRow() does nothing.
Another way to get data from a database is to use a RowSet object. RowSets add
JavaBeans support to the functionality of the ResultSet, as explained in the next
section.
RowSets
A RowSet is an object that contains a set of rows from a result set or some other
source of tabular data, like a file or spreadsheet. RowSet is an extension of ResultSet,
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-152 -
with the added feature that it adds JavaBeans support to the JDBC API. Similarly, the
RowSetMetaData interface extends the ResultSetMetaData interface.
Being JavaBeans, RowSets follow the JavaBeans model for setting and getting
properties and for event notification, so they are easy to combine with other
components in an application.
RowSets make it easy to send tabular data over a network. They can also be used as
a wrapper, providing scrollable result sets or updatable result sets when the
underlying JDBC driver does not support them.
There are two main types of RowSets: connected and disconnected.
§ A connected RowSet, like a ResultSet, maintains a connection to a data source for as long as the
RowSet is in use.
§ A disconnected RowSet gets a connection to a data source to load data or to propagate changes
back to the data source, but most of the time it does not have a connection open.
While it is disconnected, a RowSet does not need a JDBC driver or the full JDBC API,
so its footprint is very small.
Because it is not continually connected to its data source, a disconnected RowSet
stores its data in memory. It maintains MetaData about the columns it contains and
information about its internal state. It also includes methods for making connections,
executing commands, and reading and writing data to and from the data source.
Implementations of RowSets include the following:
§ JDBCRowSet — A connected RowSet that serves mainly as a thin wrapper around a ResultSet
object to make a JDBC driver look like a JavaBeans component
§ CachedRowSet — A disconnected RowSet that caches its data in memory
§ WebRowSet — A connected RowSet that uses the HTTP protocol internally to talk to a Java
servlet that provides data access
Creating a Rowset and Setting Properties
Since RowSets are JavaBeans, they contain setter and getter methods for retrieving
and setting properties.
These methods include the following:
§ setCommand — The SQL command to be executed
§ setConcurrency — Read only or updatable
§ setType — Scrollable or foward only
§ setDataSourceName — Used with DataSource access
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-153 -
§ setUrl — used with DriverManager access
§ setUsername
§ setPassword
§ setTransactionIsolation
You need only set those properties that are needed for your particular use of a
RowSet.
The following lines of code make the CachedRowSet object crset scrollable and
updatable.
CachedRowSet crset = new CachedRowSet();
crset.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
crset.setConcurrency(ResultSet.CONCUR_UPDATABLE);
crset.setCommand("SELECT * FROM Customers");
crset.setDataSourceName("jdbc/customers");
crset.setUsername("myName");
crset.setPassword("myPwd");
crset.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
crset.addRowSetListener(listener);
If the DriverManager were being used to make a connection, you would set the
properties for a JDBC URL, a user name, and a password. The preferred means of
getting a connection is to use a DataSource object with the owner's user name and
the owner's password.
Now that the CachedRowSet has been created and initialized, all that remains is to
call the execute() method; the RowSet uses the information in its properties to make a
connection and execute the query. The data in the RowSet can then be accessed
and updated.
Rowset Events
A RowSetEvent is generated when something important happens in a RowSet, such
as a change in a column value. Being JavaBeans, RowSets can use the Java event
model to notify listeners when the RowSet is changed.
These are the RowSetListener methods:
§ rowChanged (Called when the RowSet is changed)
§ rowSetChanged(Called when a RowSet is inserted, updated, or deleted)
§ cursorMoved (Called when a RowSet's cursor is moved)))
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-154 -
In addition to obtaining the data stored in the database, it is frequently ver useful to be
able to obtain data about the database and its contents. This capability is supported
by the MetaData objects discussed in the next section.
MetaData
MetaData is information about the database or its contents made available by the
JDBC API.
These are the main types of MetaData accessible from JDBC:
§ DatabaseMetaData
§ ResultSetMetaData
§ ParameterMetaData
DatabaseMetaData
The DatabaseMetaData interface provides information about the underlying database
as a whole. The interface defines over 150 different methods providing the following
types of information about the database:
§ General information about the data source
§ Data-source limits
§ Levels of transaction support
§ Feature support
§ Information about the SQL objects that the source contains
Many of the DatabaseMetaData methods return information in ResultSets, allowing
you to use ResultSet methods such as getString and getInt to retrieve this information.
If a given form of MetaData is not available, these methods should throw a
SQLException.
Some of the DatabaseMetaData methods take arguments that are String patterns
conforming to the normal wild-card rules for SQL Strings. For pattern String
arguments, "%" means match any substring of zero or more characters, and "_"
means match any one character. If a search pattern argument is set to null, that
argument's criteria will be ignored in the search.
If a driver does not support a MetaData method, a SQLException will normally be
thrown. In the case of methods that return a ResultSet, either a ResultSet (which may
be empty) is returned or a SQLException is thrown.
A DatabaseMetaData object is created using the Connection.getMetaData() method.
It can then be used to get information about the database, as in the following example,
which gets the names of the tables in the database:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-155-
Connection con = DriverManager.getConnection ("jdbc:odbc:Customers");
DatabaseMetaData dbmd = con.getMetaData();
ResultSet rs = dbmd.getTables(null,null,"%",new String[]{"TABLE"});
General information about the underlying database is accessible from the
DatabaseMetaData interface by using methods such as these:
§ getURL()
§ getUserName()
§ getDatabaseProductName()
§ getSQLKeywords()
§ nullsAreSortedHigh() and nullsAreSortedLow()
Useful methods for retrieving information about supported functionality include the
following:
§ supportsBatchUpdates()
§ supportsStoredProcedures()
§ supportsFullOuterJoins()
§ supportsPositionedDelete()
These methods are provided to determine limits the database imposes:
§ getMaxRowSize()
§ getMaxStatementLength()
§ getMaxConnections()
§ getMaxColumnsInTable()
Useful methods for retrieving information about SQL objects and their attributes
include the following:
§ getSchemas()
§ getCatalogs()
§ getTables()
§ getPrimaryKeys()
§ getProcedures()
The transaction-support capabilities of the database management system can be
queried using these methods:
§ supportsMultipleTransactions()
§ getDefaultTransactionIsolation()
§ supportsSavePoints()
Note
Many of the DatabaseMetaData
methods have been added or modified in
JDBC 2.0 and JDBC 3.0, so if your driver is not JDBC 2.0 or JDBC 3.0
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-156 -
compliant, a SQLException may be thrown.
ResultSetMetaData
Information about the columns in a ResultSet is available by calling the getMetaData()
method. The ResultSetMetaData object returned gives the number, types, and
properties of its ResultSet object's columns.
Some of the methods available to access ResultSetMetaData are as follows:
§ getColumnCount() — Returns the number of columns in the ResultSet
§ getColumnDisplaySize(int column)— Returns the column's normal max width in chars
§ getColumnLabel(int column) — Returns the column title for use in printouts and displays
§ getColumnName(int column) — Returns the column name
§ getColumnType(int column) — Returns the column's SQL data-type index
§ getColumnTypeName(int column)— Returns the name of the column's SQL data type
§ getPrecision(int column)— Returns the number of decimal digits in the column
§ getScale(int column) — Returns the number of digits to right of the decimal point
§ getTableName(int column) — Returns the table name
§ isAutoIncrement(int column) — Returns true if the column is automatically numbered
§ isCurrency(int column) — Returns true if the column value is a currency
§ isNullable(int column)— Returns true if the column value can be set to NULL
Listing 4-10 illustrates the use of the ResultSetMetaData methods getColumnCount
and getColumnLabel in an example where the column names and column count are
unknown.
Listing 4-10: Using ResultSetMetaData
public void printResultSet(String query){
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection
("jdbc:odbc:Inventory");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData md = rs.getMetaData();
int nColumns = md.getColumnCount();
for(int i=1;i<=nColumns;i++){
System.out.print(md.getColumnLabel(i)+((i==nColumns)?"\n":"\t"));
}
while (rs.next()) {
for(int i=1;i<=nColumns;i++){
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-157 -
System.out.print(rs.getString(i)+((i==nColumns)?"\n":"\t"));
}
}
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
catch(SQLException e){
e.printStackTrace();
}
}
Notice in particular the use of the getColumnLabel method. This method returns the
preferred display name for the column, defaulting to the column name if no specific
label is assigned.
ParameterMetaData
The PreparedStatement method getMetaData() retrieves a ResultSetMetaData
object containing a description of the columns that will be returned when the
PreparedStatement is executed. Here's an example:
PreparedStatement ps = con.PrepareStatement("SELECT * FROM CUSTOMERS");
ResultSetMetaData md = ps.getMetaData();
int cols = md.getColumnCount();
The method getParameterMetaData() returns a ParameterMetaData object
containing descriptions of the IN and OUT parameters the PreparedStatement uses,
as shown here:
PreparedStatement ps = con.PrepareStatement("SELECT * FROM CUSTOMERS");
ParameterMetaData pd = ps.getParameterMetaData();
int pType = pd.getParameterType(1);
Note
Support for ParameterMetaData is provided as part of the JDBC 3.0 API,
and requires JDK 1.4
JDBC Mapping of SQL Data Types
The JDBC Core API provides automatic type conversion between SQL data types
and Java data types. Table 4-5 summarizes these conversions.
Table 4-5: Standard Mapping from SQL Types to Java
SQL type Java Type Description
CHAR String Fixed-length character string. For a CHAR type
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 4:Introduction to JDBC
-158-
Table 4-5: Standard Mapping from SQL Types to Java
SQL type Java Type Description
of length n, the DBMS invariably assigns n
characters of storage, padding unused space.
VARCHAR String Variable-length character string. For a
VARCHAR of length n, the DBMS assigns up
to n charcters of storage, as required.
LONGVARCHAR String Variable-length character string. JDBC allows
retrieval of a LONGVARCHAR as a Java input
stream.
NUMERIC java.math.BigDecimal Arbitrary-precision signed decimal numbers.
Can be retrieved using either BigDecimal or
String.
DECIMAL java.math.BigDecimal Arbitrary-precision signed decimal numbers.
Can be retrieved using either BigDecimal or
String.
BIT boolean Yes / No value
TINYINT byte 8 bit integer values
SMALLINT short 16 bit integer values
INTEGER int 32 bit integer values
BIGINT long 64 bit integer values
REAL float Floating point number, mapped to float
FLOAT double Floating point number, mapped to double
DOUBLE double Floating point number, mapped to double
BINARY byte[] Retrieve as byte array.
VARBINARY byte[] Retrieve as byte array.
LONGVARBINARY byte[] Retrieve as byte array. JDBC allows retrieval of
a LONGVARCHAR as a Java input stream.
DATE java.sql.Date Thin wrapper around java.util.Date
TIME java.sql.Time Thin wrapper around java.util.Date
TIMESTAMP java.sql.Timestamp Composite of a java.util.Date and a separate
nanosecond value
Cross-Reference
In addition to the data types supported by the JDBC Core API,
JDBC 2.0 and JDBC 3.0 have introduced supp
ort for other data
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... byte[] Retrieve as byte array LONGVARBINARY byte[] Retrieve as byte array JDBC allows retrieval of a LONGVARCHAR as a Java input stream DATE java. sql.Date Thin wrapper around java. util.Date TIME java. sql.Time Thin wrapper around java. util.Date TIMESTAMP java. sql.Timestamp Composite of a java. util.Date and a separate nanosecond value As you can see from Table 5-2, most of the fields we will be using can... mapping of these SQL3 data types into the Javaprogramming language With these new interfaces, you can work with SQL3 data types the same way you do other data types Object Relational Databases Object relational databases are simply an extension to normal relational database management systems supporting the use of an object-oriented-design approach to the database world For example, in a normal RDBMS,... class, which connects to the database and creates the table (See Listing 5-3.) Listing 5-3: Swing-based Table Builder — the main JFrame package jdbc_bible.part2; import java. awt.*; import java. awt.event.*; import javax.swing.*; import javax.swing.event.*; public class DBManager extends JFrame{ JMenuBar menuBar = new JMenuBar(); JDesktopPane desktop = new JDesktopPane(); String database = null; String tableName... Split-Merge on www.verypdf.com to remove this watermark Chapter 4:Introduction to JDBC sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcOdbcStatement .java: 229) at java_ databases.ch04.Logging.main(Logging .java: 30) Summary Part I is an introduction to database management systems, SQL, and JDBC, providing a theoretical overview of the topics as a basis for the more detailed explanations in subsequent... with JDBC and SQL Table 5-2: Standard Mapping from SQL Types to Java SQL type Java type Description LONGVARCHAR String Variable-length character string JDBC allows retrieval of a LONGVARCHAR as a Java input stream NUMERIC java. math.BigDecimal Arbitrary-precision signed decimal numbers Can be retrieved using either BigDecimal or String DECIMAL java. math.BigDecimal Arbitrary-precision signed decimal numbers... § Redirect System.err to a logging file by using System.setErr() Listing 4-11: Logging errors to a file package java_ databases.ch04; import java. io.*; -165- Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Chapter 4:Introduction to JDBC import java. sql.*; import java. util.*; public class Logging{ public static void main(String args[]){ PrintWriter errLog = null; PrintStream... Expected 1 NextException: null java. sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Too few parameters Expected 1 at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc .java: 6031) at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc .java: 6188) at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc .java: 2494) at sun.jdbc.odbc.JdbcOdbcStatement.execute(JdbcOdbcStatement .java: 314) at -167 - Please purchase... TableBuilderFrame(tableName); tableMaker.setCommandListener(new CommandListener()); desktop.add(tableMaker); tableMaker.setVisible(true); } private void selectDatabase(){ database = JOptionPane.showInputDialog(this, "Database: ", "Select database" ,JOptionPane.QUESTION_MESSAGE); dbUtils = new DatabaseUtilities(); -182 - Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Chapter 5:Creating a Table with... are discussed in the next section Using Tables Relational databases store data in tables A given database may contain one or more tables, depending on the application Tables are intended to store logically related data items together, so a database may contain one table for business contacts, another for projects, and so on Each table in a database is like a spreadsheet When you create a table, you... password or pass a Java Properties object with the URL: getConnection(String url,String user,String password); getConnection(String url, Properties info); A connection represents a session with a specific database, providing the context in which our SQL statements are executed and results are returned Statement The term Statement refers to the Java class that passes the SQL Query to the database via the . as a Java input stream.
DATE java. sql.Date Thin wrapper around java. util.Date
TIME java. sql.Time Thin wrapper around java. util.Date
TIMESTAMP java. sql.Timestamp.
sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcOdbcStatement .java: 229)
at java_ databases.ch04.Logging.main(Logging .java: 30)
Summary
Part I is an introduction to database management systems,