
- •Contents at a Glance
- •Contents
- •About the Authors
- •About the Technical Reviewer
- •Acknowledgments
- •Introduction
- •Oracle Java Certifications: Overview
- •FAQ 1. What are the different levels of Oracle Java certification exams?
- •FAQ 4. Is OCPJP 7 prerequisite for other Oracle certification exams?
- •FAQ 5. Should I take the OCPJP 7 or OCPJP 6 exam?
- •The OCPJP 7 Exam
- •FAQ 7. How many questions are there in the OCPJP 7 exam?
- •FAQ 8. What is the duration of the OCPJP 7 exam?
- •FAQ 9. What is the cost of the OCPJP 7 exam?
- •FAQ 10. What are the passing scores for the OCPJP 7 exam?
- •FAQ 11. What kinds of questions are asked in the OCPJP 7 exam?
- •FAQ 12. What does the OCPJP 7 exam test for?
- •FAQ 13. I’ve been a Java programmer for last five years. Do I have to prepare for the OCPJP 7 exam?
- •FAQ 14. How do I prepare for the OCPJP 7 exam?
- •FAQ 15. How do I know when I’m ready to take the OCPJP 7 exam?
- •Taking the OCPJP 7 Exam
- •FAQ 16. What are my options to register for the exam?
- •FAQ 17. How do I register for the exam, schedule a day and time for taking the exam, and appear for the exam?
- •The OCPJP 7 Exam: Pretest
- •Answers with Explanations
- •Post-Pretest Evaluation
- •Essentials of OOP
- •FunPaint Application: An Example
- •Foundations of OOP
- •Abstraction
- •Encapsulation
- •Inheritance
- •Polymorphism
- •Class Fundamentals
- •Object Creation
- •Constructors
- •Access Modifiers
- •Public Access Modifier
- •Private Access Modifier
- •Protected and Default Access Modifier
- •Overloading
- •Method Overloading
- •Constructor Overloading
- •Overload resolution
- •Points to Remember
- •Inheritance
- •Runtime Polymorphism
- •An Example
- •Overriding Issues
- •Overriding: Deeper Dive
- •Invoking Superclass Methods
- •Type Conversions
- •Upcasts and Downcasts
- •Casting Between Inconvertible Types
- •Using “instanceof” for Safe Downcasts
- •Java Packages
- •Working with Packages
- •Static Import
- •Summary
- •Abstract Classes
- •Points to Remember
- •Using the “final” Keyword
- •Final Classes
- •Final Methods and Variables
- •Points to Remember
- •Using the “static” Keyword
- •Static Block
- •Points to Remember
- •Flavors of Nested Classes
- •Static Nested Classes (or Interfaces)
- •Points to Remember
- •Inner Classes
- •Points to Remember
- •Local Inner Classes
- •Points to Remember
- •Anonymous Inner Classes
- •Points to Remember
- •Enum Data Types
- •Points to Remember
- •Summary
- •Interfaces
- •Declaring and Using Interfaces
- •Points to Remember
- •Abstract Classes vs. Interfaces
- •Choosing Between an Abstract Class and an Interface
- •Object Composition
- •Composition vs. Inheritance
- •Points to Remember
- •Design Patterns
- •The Singleton Design Pattern
- •Ensuring That Your Singleton Is Indeed a Singleton
- •The Factory Design Pattern
- •Differences Between Factory and Abstract Factory Design Patterns
- •The Data Access Object (DAO) Design Pattern
- •Points to Remember
- •Summary
- •Generics
- •Using Object Type and Type Safety
- •Using the Object Class vs. Generics
- •Container Implementation Using the Object Class
- •Container Implementation Using Generics
- •Creating Generic Classes
- •Diamond Syntax
- •Interoperability of Raw Types and Generic Types
- •Generic Methods
- •Generics and Subtyping
- •Wildcard Parameters
- •Limitations of Wildcards
- •Bounded Wildcards
- •Wildcards in the Collections Class
- •Points to Remember
- •The Collections Framework
- •Why Reusable Classes?
- •Basic Components of the Collections Framework
- •Abstract Classes and Interfaces
- •Concrete Classes
- •List Classes
- •ArrayList Class
- •The ListIterator Interface
- •The LinkedList Class
- •The Set Interface
- •The HashSet Class
- •The TreeSet Class
- •The Map Interface
- •The HashMap Class
- •Overriding the hashCode() Method
- •The NavigableMap Interface
- •The Queue Interface
- •The Deque Interface
- •Comparable and Comparator Interfaces
- •Algorithms (Collections Class)
- •The Arrays Class
- •Methods in the Arrays Class
- •Array as a List
- •Points to Remember
- •Summary
- •Generics
- •Collections Framework
- •Processing Strings
- •String Searching
- •The IndexOf() Method
- •The regionMatches() Method
- •String Parsing
- •String Conversions
- •The Split() Method
- •Regular Expressions
- •Understanding regex Symbols
- •Regex Support in Java
- •Searching and Parsing with regex
- •Replacing Strings with regex
- •String Formatting
- •Format Specifiers
- •Points to Remember
- •Summary
- •Reading and Writing from Console
- •Understanding the Console Class
- •Formatted I/O with the Console Class
- •Special Character Handling in the Console Class
- •Using Streams to Read and Write Files
- •Character Streams and Byte Streams
- •Character Streams
- •Reading Text Files
- •Reading and Writing Text Files
- •“Tokenizing” Text
- •Byte Streams
- •Reading a Byte Stream
- •Data Streams
- •Writing to and Reading from Object Streams: Serialization
- •Serialization: Some More Details
- •Points to Remember
- •Summary
- •A Quick History of I/O APIs
- •Using the Path Interface
- •Getting Path Information
- •Comparing Two Paths
- •Using the Files Class
- •Checking File Properties and Metadata
- •Copying a File
- •Moving a File
- •Deleting a File
- •Walking a File Tree
- •Revisiting File Copy
- •Finding a File
- •Watching a Directory for Changes
- •Points to Remember
- •Summary
- •Introduction to JDBC
- •The Architecture of JDBC
- •Two-Tier and Three-Tier JDBC Architecture
- •Types of JDBC Drivers
- •Setting Up the Database
- •Connecting to a Database Using a JDBC Driver
- •The Connection Interface
- •Connecting to the Database
- •Statement
- •ResultSet
- •Querying the Database
- •Updating the Database
- •Getting the Database Metadata
- •Points to Remember
- •Querying and Updating the Database
- •Performing Transactions
- •Rolling Back Database Operations
- •The RowSet Interface
- •Points to Remember
- •Summary
- •Define the Layout of the JDBC API
- •Connect to a Database by Using a JDBC driver
- •Update and Query a Database
- •Customize the Transaction Behavior of JDBC and Commit Transactions
- •Use the JDBC 4.1 RowSetProvider, RowSetFactory, and RowSet Interfaces
- •Introduction to Exception Handling
- •Throwing Exceptions
- •Unhandled Exceptions
- •Try and Catch Statements
- •Programmatically Accessing the Stack Trace
- •Multiple Catch Blocks
- •Multi-Catch Blocks
- •General Catch Handlers
- •Finally Blocks
- •Points to Remember
- •Try-with-Resources
- •Closing Multiple Resources
- •Points to Remember
- •Exception Types
- •The Exception Class
- •The RuntimeException Class
- •The Error Class
- •The Throws Clause
- •Method Overriding and the Throws Clause
- •Points to Remember
- •Custom Exceptions
- •Assertions
- •Assert Statement
- •How Not to Use Asserts
- •Summary
- •Introduction
- •Locales
- •The Locale Class
- •Getting Locale Details
- •Resource Bundles
- •Using PropertyResourceBundle
- •Using ListResourceBundle
- •Loading a Resource Bundle
- •Naming Convention for Resource Bundles
- •Formatting for Local Culture
- •The NumberFormat Class
- •The Currency Class
- •The DateFormat Class
- •The SimpleDateFormat Class
- •Points to Remember
- •Summary
- •Introduction to Concurrent Programming
- •Important Threading-Related Methods
- •Creating Threads
- •Extending the Thread Class
- •Implementing the Runnable Interface
- •The Start( ) and Run( ) Methods
- •Thread Name, Priority, and Group
- •Using the Thread.sleep() Method
- •Using Thread’s Join Method
- •Asynchronous Execution
- •The States of a Thread
- •Two States in “Runnable” State
- •Concurrent Access Problems
- •Data Races
- •Thread Synchronization
- •Synchronized Blocks
- •Synchronized Methods
- •Synchronized Blocks vs. Synchronized Methods
- •Deadlocks
- •Other Threading Problems
- •Livelocks
- •Lock Starvation
- •The Wait/Notify Mechanism
- •Let’s Solve a Problem
- •More Thread States
- •timed_waiting and blocked States
- •waiting State
- •Using Thread.State enum
- •Understanding IllegalThreadStateException
- •Summary
- •Using java.util.concurrent Collections
- •Semaphore
- •CountDownLatch
- •Exchanger
- •CyclicBarrier
- •Phaser
- •Concurrent Collections
- •Apply Atomic Variables and Locks
- •Atomic Variables
- •Locks
- •Conditions
- •Multiple Conditions on a Lock
- •Use Executors and ThreadPools
- •Executor
- •Callable, Executors, ExecutorService, ThreadPool, and Future
- •ThreadFactory
- •The ThreadLocalRandom Class
- •TimeUnit Enumeration
- •Use the Parallel Fork/Join Framework
- •Useful Classes of the Fork/Join Framework
- •Using the Fork/Join Framework
- •Points to Remember
- •Summary
- •Using java.util.concurrent Collections
- •Applying Atomic Variables and Locks
- •Using Executors and ThreadPools
- •Using the Parallel Fork/Join Framework
- •Chapter 3: Java Class Design
- •Chapter 4: Advanced Class Design
- •Chapter 5: Object-Oriented Design Principles
- •Chapter 6: Generics and Collections
- •Chapter 7: String Processing
- •Chapter 8: Java I/O Fundamentals
- •Chapter 9: Java File I/O (NIO.2)
- •Chapter 10: Building Database Applications with JDBC
- •Chapter 11: Exceptions and Assertions
- •Chapter 12: Localization
- •Chapter 13: Threads
- •Chapter 14: Concurrency
- •OCPJP7 Exam (1Z0-804 a.k.a. Java SE 7 Programmer II) Topics
- •OCPJP 7 Exam (1Z0-805, a.k.a. Upgrade to Java SE 7 Programmer) Topics
- •Answers and Explanations
- •Answer Sheet
- •Answers and Explanations
- •Index
Chapter 10 ■ Building Database Applications with JDBC
ResultSet also provides a set of methods to read the value at the desired column in the current row. In general, these methods come in two flavors: the first flavor takes column number as the input and the second flavor accepts column name as the input. For instance, the methods to read a double value are double getDouble(int columnNumber) and double getDouble(String columnName). In a similar way, ResultSet provides get() methods for all basic types.
Similarly, ResultSet provides a set of methods to update values at the desired column in the selected row. These methods also come in two variants: void updateXXX(int columnNumber, XXX x) and void updateXXX(String columnName, XXX x), where the update methods are defined for various data types represented as XXX.
Querying the Database
Now you know all the necessary interfaces that will be used to execute a simple SQL query on a database: Connection, Statement, and ResultSet. Let’s query a database and print the output. Recollect that you have created a database named addressBook and a table named contact within this database, and inserted two rows within the table. Assume that you want to print the table contents; Listings 10-2 and 10-3 contain the program to do so.
Listing 10-2. DbConnector.java
import java.sql.*;
// Utility class with method connectToDb() that will be used by other programs in this chapter public class DbConnector {
public static Connection connectToDb() throws SQLException { String url = "jdbc:mysql://localhost:3306/";
String database = "addressBook"; String userName = "root"; String password = "mysql123";
return DriverManager.getConnection(url + database, userName, password);
}
}
Listing 10-3. DbQuery.java
import java.sql.*;
// Program to illustrate how to query a database class DbQuery {
public static void main(String[] args) {
//Get connection, execute query, get the result set
//and print the entries from the result rest
try (Connection connection = DbConnector.connectToDb(); Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM contact")){ System.out.println("ID \tfName \tlName \temail \t\tphoneNo");
while (resultSet.next()) { System.out.println(resultSet.getInt("id") + "\t"
+resultSet.getString("firstName") + "\t"
+resultSet.getString("lastName") + "\t"
+resultSet.getString("email") + "\t"
+resultSet.getString("phoneNo"));
}
}
290

Chapter 10 ■ Building Database Applications with JDBC
catch (SQLException sqle) { sqle.printStackTrace(); System.exit(−1);
}
}
}
The output of the program is
|
|
|
|
|
ID |
fName |
lName |
phoneNo |
1Michael Taylor michael@abc.com +919876543210
2William Becker william@abc.com +449876543210
Let’s have a look at what is happening in this code snippet step by step.
•In the main() method, there is a try-with-resources statement. The first statement is a call to the connectToDb() method, which is defined in the program. The connectToDb() method simply connects to the database (which you saw in the last example) and returns a Connection object if it succeeds.
•In the next statement, you create a Statement object from the connection.
•The Statement object is now used to execute a query. You want to fetch all the columns in the contact table; hence you write SELECT * FROM contact as a SQL query. You execute the query using the executeQuery() method of the statement object. The outcome of the query is stored in a ResultSet object.
•Now this ResultSet object is used to print the fetched data. You read all column values in the current row and you do the same for each row in the ResultSet object.
•Since you’ve created the Connection, Statement, and ResultSet objects within a try-with- resources statement, there is no need to explicitly call close() on these resources. However, if you are not using try-with-resources, you need to release them explicitly in a finally block.
Here, you are using column names to read the associated values. You can use column numbers instead to do the same job. Here is the modified code inside the while loop to use column numbers instead:
while (resultSet.next()) { System.out.println(resultSet.getInt(1)
+"\t" + resultSet.getString(2)
+"\t" + resultSet.getString(3)
+"\t" + resultSet.getString(4)
+"\t" + resultSet.getString(5));
}
This code produces exactly the same result as the last example. However, one important thing to observe here is that column index starts from 1, not from 0.
The column index in the ResultSet object starts from 1, not from 0.
291
Chapter 10 ■ Building Database Applications with JDBC
Here, while referring to columns by column index, if you refer to a column by an index that is more than the total number of columns, you will get an exception. For instance, if you change one of the column indices used in the last example to 6, you will get the following exception:
java.sql.SQLException: Column Index out of range, 6 > 5.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074) [. . . this part of the stack trace elided . . .]
at DbQuery.main(DbQuery.java:18)
Hence, you should be careful and always provide the correct column indices.
In this example, you know the number of columns as well as the data types in columns. What if you neither know the number of columns in each row nor the data types in the columns? You can use the getMetaData() method and use the getColumnCount() method to get the column count. When you don’t know the data type of a column entry, you can just use the getObject() method on the ResultSet object. Here is the modified code that makes use of these methods:
// from resultSet metadata, find out how many columns are there and then read the column entries int numOfColumns = resultSet.getMetaData().getColumnCount();
while (resultSet.next()) {
// remember that the column index starts from 1 not 0 for(int i = 1; i <= numOfColumns; i++) {
// since we do not know the data type of the column, we use getObject() System.out.print(resultSet.getObject(i) + "\t");
}
System.out.println("");
}
The output of the program remains the same, so we haven’t shown the resulting output here.
Okay, let’s carry out another exercise. This time you just want to print the name and e-mail address where the first name matches to “Michael.” See Listing 10-4.
Listing 10-4. DbQuery4.java
import java.sql.*;
class DbQuery4 {
public static void main(String[] args) throws SQLException { try (Connection connection = DbConnector.connectToDb();
Statement statement = connection.createStatement();
ResultSet resultset = statement.executeQuery("SELECT firstName, email FROM contact WHERE firstName=\"Michael\"")) {
System.out.println("fName \temail"); while (resultset.next()){
System.out.println(resultset.getString("firstName") + "\t" + resultset.getString("email"));
}
} catch (SQLException e) { e.printStackTrace(); System.exit(−1);
}
}
}
292
4
Chapter 10 ■ Building Database Applications with JDBC
It prints:
fName email
Michael michael@abc.com
Updating the Database
Now let’s update the database. You can update a database in two ways: you can use SQL queries to update the database directly, or you can fetch a ResultSet using a SQL query and then you can change the ResultSet and the database. JDBC supports both of these methods. Let’s focus on retrieving the ResultSet and modifying the ResultSet and the database.
In order to modify the ResultSet and the database, the ResultSet class provides a set of update methods for each data type. Also, there are other supporting methods such as updateRow() and deleteRow() to make the task simpler. It’s time to get your hands dirty: assume that one of your contacts in your addressBook database has changed his phone number, so you are now going to update his phone number in your database using a JDBC program.
Listing 10-5. DbUpdate.java
import java.sql.*;
// To illustrate how we can update a database class DbUpdate {
public static void main(String[] args) throws SQLException { try (Connection connection = DbConnector.connectToDb();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM contact WHERE firstName=\"Michael\"")) {
// first fetch the data and display it before the update operation System.out.println("Before the update");
System.out.println("id \tfName \tlName \temail \t\tphoneNo"); while (resultSet.next()) {
System.out.println(resultSet.getInt("id") + "\t"
+resultSet.getString("firstName") + "\t"
+resultSet.getString("lastName") + "\t"
+resultSet.getString("email") + "\t"
+resultSet.getString("phoneNo"));
}
// now update the resultSet and display the modified data resultSet.absolute(1);
resultSet.updateString("phoneNo", "+919976543210"); System.out.println("After the update"); System.out.println("id \tfName \tlName \temail \t\tphoneNo"); resultSet.beforeFirst();
while (resultSet.next()) { System.out.println(resultSet.getInt("id") + "\t"
+resultSet.getString("firstName") + "\t"
+resultSet.getString("lastName") + "\t"
+resultSet.getString("email") + "\t"
+resultSet.getString("phoneNo"));
}
293
Chapter 10 ■ Building Database Applications with JDBC
} catch (SQLException e) { e.printStackTrace(); System.exit(−1);
}
}
}
Let’s pick out the nitty-gritty of the program step by step:
•You establish the connection using the DbConnector.connectToDb() method.
•After creating a Statement object, you execute a query on the database to find out the record associated with Michael. (For the sake of simplicity we are assuming that the ResultSet will contain exactly one record.)
•You print the retrieved record.
•You use the absolute() method to move the cursor to the first row in the ResultSet object; then you update the phone number using the updateString() method.
•And finally you print the modified resultset.
Well, that looks straightforward. Now, execute it and see what this program prints:
Before the |
update |
|
|
||
id |
fName |
lName |
phoneNo |
||
1 |
Michael Taylor |
michael@abc.com |
+919876543210 |
||
com.mysql.jdbc.NotUpdatable: Result Set |
not updatable.(. . .rest of the text elided) |
||||
|
at |
com.mysql.jdbc.ResultSetImpl.updateString(ResultSetImpl.java:8618) |
|||
|
at |
com.mysql.jdbc.ResultSetImpl.updateString(ResultSetImpl.java:8636) |
|||
|
at |
DbUpdate.main(DbUpdate.java:34) |
|||
|
|
|
|
|
|
Oops, the program crashed after throwing an exception! What happened?
You are trying to update a ResultSet object that is not updatable. In other words, in order to make the update in the ResultSet and the database, you need to make this ResultSet updatable. You can do that by creating a proper Statement object; while calling the createStatement() method you can pass inputs such as whether you want a scrollable ResultSet that is sensitive to changes or you want an updatable ResultSet.
So, make this one single change to the call to the createStatement() method in Listing 10-5:
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_ UPDATABLE);
Now run this changed program to see if it works.
|
|
|
|
|
Before the update |
|
|
||
id |
fName |
lName |
phoneNo |
|
1 |
Michael |
Taylor |
michael@abc.com |
+919876543210 |
After the update |
|
|
|
|
id |
fName |
lName |
phoneNo |
|
1 |
Michael |
Taylor |
michael@abc.com |
+919876543210 |
|
|
|
|
|
Good, the program did not result in any exception. But wait, the phone number of Michael is not updated! What happened? You forgot a vital statement after the update: the updateRow() method. Every time you make change in ResultSet using the appropriate updateXXX() method, you need to call updateRow() to make sure that all the values are actually updated in the database. Make this change and try again (see Listing 10-6).
294
Chapter 10 ■ Building Database Applications with JDBC
Listing 10-6. DbUpdate2.java
import java.sql.*;
// To illustrate how we can update a database class DbUpdate2 {
public static void main(String[] args) throws SQLException { try (Connection connection = DbConnector.connectToDb();
//create a statement from which the created ResultSets
//are "scroll sensitive" as well as "updatable" Statement statement =
connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet resultSet = statement.executeQuery("SELECT * FROM contact WHERE firstName=\"Michael\"")) {
//first fetch the data and display it before the update operation System.out.println("Before the update");
System.out.println("id \tfName \tlName \temail \t\tphoneNo"); while (resultSet.next()) {
System.out.println(resultSet.getInt("id") + "\t"
+resultSet.getString("firstName") + "\t"
+resultSet.getString("lastName") + "\t"
+resultSet.getString("email") + "\t"
+resultSet.getString("phoneNo"));
}
//now update the resultSet and display the modified data resultSet.absolute(1);
resultSet.updateString("phoneNo", "+919976543210");
//reflect those changes back to the database by calling updateRow() method resultSet.updateRow();
System.out.println("After the update"); System.out.println("id \tfName \tlName \temail \t\tphoneNo"); resultSet.beforeFirst();
while (resultSet.next()) { System.out.println(resultSet.getInt("id") + "\t"
+resultSet.getString("firstName") + "\t"
+resultSet.getString("lastName") + "\t"
+resultSet.getString("email") + "\t"
+resultSet.getString("phoneNo"));
}
} catch (SQLException e) { e.printStackTrace(); System.exit(−1);
}
}
} |
|
|
|
|
|
Now this program prints the following: |
|
||
|
|
|
|
|
Before the update |
|
|
||
id |
fName |
lName |
phoneNo |
|
1 |
Michael Taylor |
michael@abc.com |
+919876543210 |
295

Chapter 10 ■ Building Database Applications with JDBC
After the update |
|
|
|
|
id |
fName |
lName |
phoneNo |
|
1 |
Michael |
Taylor |
michael@abc.com |
+919976543210 |
|
|
|
|
|
Yes, it is working fine now. Now you know the requirements and steps required to update a row in a database.
Always call updateRow() after modifying the row contents; otherwise you will lose the changes.
Next, how about inserting a record in the RecordSet and the database? Try the next example, shown in Listing 10-7.
Listing 10-7. DbInsert.java
import java.sql.*;
// To illustrate how to insert a row in a ResultSet and in the database class DbInsert {
public static void main(String[] args) throws SQLException { try (Connection connection = DbConnector.connectToDb(); Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet resultSet = statement.executeQuery("SELECT * FROM contact")) { System.out.println("Before the insert");
System.out.println("id \tfName \tlName \temail \t\tphoneNo"); while (resultSet.next()){
System.out.println(resultSet.getInt("id") + "\t"
+resultSet.getString("firstName") + "\t"
+resultSet.getString("lastName") + "\t"
+resultSet.getString("email") + "\t"
+resultSet.getString("phoneNo"));
}
resultSet.moveToInsertRow(); resultSet.updateString("firstName", "John"); resultSet.updateString("lastName", "K."); resultSet.updateString("email", "john@abc.com"); resultSet.updateString("phoneNo", "+19753186420"); resultSet.insertRow();
System.out.println("After the insert"); System.out.println("id \tfName \tlName \temail \t\tphoneNo"); resultSet.beforeFirst();
while (resultSet.next()){ System.out.println(resultSet.getInt("id") + "\t"
+resultSet.getString("firstName") + "\t"
+resultSet.getString("lastName") + "\t"
+resultSet.getString("email") + "\t"
+resultSet.getString("phoneNo"));
}
296
Chapter 10 ■ Building Database Applications with JDBC
} catch (SQLException e) { e.printStackTrace();
}
}
}
What happened in this example? After printing the current records, you call the moveToInsertRow() method. This method sets the cursor to a new record and prepares the ResultSet for the insertion of a row (creates a buffer to hold the column values). After it, you use the updateString() method to modify each column value in the newly added row. And finally, you call insertRow() to finally insert the new row into the ResultSet and the database.
One important thing to note here is that you need to provide correct types of values for each column. Also, you cannot leave a column blank (i.e., not provide any value) if the column value can not be left unfilled. In both of these violations, you may get a SQLException.
Let’s see what this program prints.
|
|
|
|
|
Before the insert |
|
|
||
id |
fName |
lName |
phoneNo |
1Michael Taylor michael@abc.com +919976543210
2William Becker william@abc.com +449876543210 After the insert
id |
fName |
lName |
phoneNo |
1Michael Taylor michael@abc.com +919976543210
2William Becker william@abc.com +449876543210
3 |
John |
K. |
john@abc.com |
+19753186420 |
|
|
|
|
|
Looks good! Now let’s try another operation: delete a record from the database. Take a look at the program in Listing 10-8.
Listing 10-8. DbDelete.java
import java.sql.*;
// To illustrate how to delete a row in a ResultSet and in the database class DbDelete {
public static void main(String[] args) throws SQLException { try (Connection connection = DbConnector.connectToDb();
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet resultSet1 = statement.executeQuery
("SELECT * FROM contact WHERE firstName=\"John\"")) { if(resultSet1.next()){
// delete the first row resultSet1.deleteRow();
}
resultSet1.close();
// now fetch again from the database try (ResultSet resultSet2 =
statement.executeQuery("SELECT * FROM contact")) {
297
Chapter 10 ■ Building dataBase appliCations with JdBC
System.out.println("After the deletion"); System.out.println("id \tfName \tlName \temail \t\tphoneNo"); while (resultSet2.next()){
System.out.println(resultSet2.getInt("id") + "\t"
+resultSet2.getString("firstName") + "\t"
+resultSet2.getString("lastName") + "\t"
+resultSet2.getString("email") + "\t"
+resultSet2.getString("phoneNo"));
}
}
} catch (SQLException e) { e.printStackTrace(); System.exit(−1);
}
}
}
This program simply selects a proper row to delete and calls the deleteRow() method on the current selected row. Here’s the output of the program:
After the deletion |
|
|
||
id |
fName |
lName |
phoneNo |
1Michael Taylor michael@abc.com +919976543210
2William Becker william@abc.com +449876543210
Well, the program works fine and correctly removes the row where the first name of the person is “John.” You might have remembered that you have created a table named contact in your database to work with.
At that time, you created that table from the MySQL command prompt. The same task could have been done through a JDBC program. At this juncture, let’s create a new table named familyGroup in the database programmatically (see Listing 10-9). You will use this table later in this chapter.
Listing 10-9. DbCreateTable.java
import java.sql.*; class DbCreateTable {
public static void main(String[] args) {
try (Connection connection = DbConnector.connectToDb(); Statement statement = connection.createStatement()){
// use CREATE TABLE SQL statement to create table familyGroup
int result = statement.executeUpdate("CREATE TABLE familyGroup (id int not null auto_increment, nickName varchar(30) not null, primary key(id));"); System.out.println("Table created successfully");
}
catch (SQLException sqle) { sqle.printStackTrace(); System.exit(−1);
}
}
}
298