What is a database, and how can it help you to store or organize the data?
How can a database be connected?
How can your Java application talk to the database? (Or, how can you establish a connection to the database and then how can you insert, update, or delete a record in the database?)
So, let’s examine each of these parts in this chapter.
Note
If you are absolutely new to database programming, you may need to know some key terms that are mentioned briefly in this chapter. So, it is recommended that you visit these terms and definitions repeatedly for a better understanding. Gradually, these terms will be clear to you, and you will be able to perform complex database programming.
Database and DBMS
A database is a collection of related files, usually called tables. A table is a collection of related records. A record is a collection of related fields, and the smallest piece of meaningful information in a file is called a field (or data item).
A database management system (DBMS) is a software package to manage these data effectively. Oracle Database, SQL Server, MySQL, MS-Access, and so forth are some commonly used DBMS packages.
Types of DBMS
Hierarchical DBMS (HDBMS)
Network DBMS (NDBMS)
Relational DBMS (RDBMS)
Object-oriented database (OODB)
Distributed DBMS (DDBMS)
Each of these has its own pros and cons. Selecting a database depends on your own needs. Based upon your needs, instead of choosing an SQL data structure (which is suitable for an RDBMS), you may prefer NoSQL ( it is a non-relational structure and can be suitable for a DDBMS).
In this chapter, you’ll see the usage of an RDBMS and simple SQL statements only.
RDBMS
In RDBMS, data are stored in rows and columns, which is similar to tables. These tables are termed relations. Rows of a table are referred to as tuples , and columns are referred to as attributes .
Each row of a table contains a record. Each column contains fields. Consider the table in Figure 13-2.
You can process different records of a relation based on some mathematical formulation, which is termed relational algebra . Since the entire database can be processed using these mathematical formulae, relational algebra is the theoretical foundation for relational databases and SQL.
Oracle Database, MySQL, Microsoft SQL Server, IBM DB2, and so on are common examples of RDBMS. In this chapter, I have used MySQL to demonstrate the examples.
Note
In Appendix C, I have shown the installation steps of MySQL on a Win10 machine.
SQL
Establish a connection with the database via DriverManager facility. DriverManager class and Driver interface are often used in this part of programming.
Talk to your database through SQL statements. You will often use Connection interface, Statement, PreparedStatement, and CallableStatement for this part of programming. You’ll see the use of Statement in Demonstration 1 and Demonstration 2. Demonstration 3 will show the use of PreparedStatement, and Demonstration 4 will show the use of CallableStatement.
Process the results obtained through different queries through the ResultSet interface.
In this chapter, you will see the use of these basic operations when the Java program interacts with the MySQL database.
Points To Remember
Java, C++, C, etc. are third-generation languages (3GL). In 3GLs, the focus is on “How to solve a problem?”, but in 4GLs, the focus is on “What do you want?” But some advanced 3GLs can combine some of the important aspects of 4GLs.
It is important to note that SQL does not differentiate between uppercase and lowercase character sets.
JDBC is an SQL-level API. It allows you to construct and combine SQL statements inside Java API calls.
Note
The simple SQL statements are used to demonstrate various programs in this chapter. If you are absolutely new to SQL, it is recommended that you do exercises with simple SQL statements in your preferred database to get a better idea before you proceed further.
Connecting to a Database
Type-1 (or JDBC-ODBC bridge ) driver: It converts JDBC method calls into ODBC function calls. The ODBC bridge driver must be installed on the client machine. Here, the JDBC driver can talk to a third-party API that may not be written in Java. Also, Type-1 drivers are not written in Java, so these are not portable. These drivers are suitable only for local connections. Oracle stopped supporting these drivers from Java 8 onward. They now recommend you use the JDBC drivers that are available from specific vendors of the database.
Type-2 (or Native-API ) driver: These drivers use client-side libraries of the database so that they can convert JDBC method calls into native calls of database API. It is a partially Java driver. Since both the native driver and the client libraries stay on the local machine, these drivers are not used for remote network connections. But they can provide a better performance than type-1 drivers.
Type-3 (or Network Protocol ) driver: These are fully written in Java. Here, the clients first communicate with a middleware application server, which converts the JDBC calls into vendor-specific DBMS calls, and then those calls are forwarded to the database server. For these drivers, no client-side library needs to be installed on the local machine, because the application server is capable of doing the required jobs. A single type-3 driver can also be used to connect multiple databases. But network support is essential for the client machine, and the overall maintenance is costly because you may need to provide database-specific coding in the middle tier.
Type-4 (or, Thin ) driver: These are also fully written in Java, but they can provide the highest performance because they are provided by the vendor itself. Here, no special software needs to be installed either on the client machine or on the server machine. The only major drawback is that, since it is provided by a specific vendor, it is dependent on the particular database where the vendor can use different protocols.
Note In Demonstration 5, you will also see the use of a javax.sql.DataSource object to establish a connection between your Java application and the database. From JDBC2.0 onward, this is the recommended approach to connect a datasource. Still I am discussing all of these to help you understand the legacy codes. Also, I believe the learning of “Database Programming in Java” is incomplete without these discussions.
You may have different JDBC drivers to connect to different databases. But as an end user, you don’t need to worry about their implementation. At this moment, it is sufficient for you to know that you need a JDBC driver to connect to a database.
Q&A Session
13.1 How can I decide which driver is suitable for my application?
If you know that you need only one specific database, pick Type-4. If you need to access multiple databases, choose Type-3. When you do not have either Type-3 or Type-4, you can consider Type-2 drivers. Type-1 is in general not recommended to use, but you can limit its use to testing purposes.
13.2 What are typical operations of the application server when any client uses type-3 drivers?
Some typical operations include logging, load balancing, auditing, and so on.
Talking to a Database in a Java Application
Now, you’ll see some demonstrations where Java applications will interact with a MySQL database. You can follow a similar approach for other databases. You’ll see the use of the Type-4 driver in the upcoming demonstrations.
- 1.
Load your JDBC driver.
- 2.
Create a connection object and connect to the database.
- 3.
Exercise the SQL statements with your Java program.
- 4.
Map the retrieved result and process it as per your needs.
Here, I assume that you have installed MySQL on your local computer. If it is not installed yet, you can follow the link https://dev.mysql.com/downloads/installer/ to get the installer and relevant details. At the time of this writing, mysql-installer-community-8.0.16.0 is the latest version. You can also refer to Appendix C, where I have shown the installation steps of MySQL on a Win10 machine.
Important Terms
Now, let’s go through some demonstrations. To understand the upcoming demonstrations, you need to be familiar with the following classes, interfaces, and methods:
DriverManager : This class manages a set of JDBC drivers. It matches the connection request from a Java application with the proper databse driver. (It is important to note that JDBC 2.0 provides an alternate way to connect to a datasource. The use of a DataSource object is a recommended way to connect to a datasource. )
Points To Remember
Similar to connecting with an Oracle database, you may notice the use of the following code:
- To connect with a MS SQL Server, you may notice the use of the following code:Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
Connection : This interface provides the methods with which to connect a database. Your SQL statements execute, and results are returned within the context of a connection. You can simply say that all the communication with the database passes through the connection object.
where the user string indicates the database user name and the password string is that user’s password.
Note
The string localhost is used because I have installed the MySQL database in my local system and test is my local database name.
Statement : It is an interface. A Statement object is used to execute the static SQL statement and returns the results for that. By default, only one ResultSet object per Statement object can be opened in a particular moment.
createStatement() : This method creates a Statement object to send SQL statements to the database.
executeQuery() : This method is used to execute an SQL statement that returns a single ResultSet object.
executeUpdate() : This method is used to execute an SQL statement that can be any of the insert, update, or delete statements. You can also use DDL statements, which return nothing. (You can refer to Q&A 13.10 in this context.)
Note
The executeQuery() or the executeUpdate() methods cannot be called on a PreparedStatement or on a CallableStatement.
ResultSet : This is an interface that represents the result set of a database query. The SQL statements that read data (using a database query) return the data in a result set. The select statement is a standard way to select rows and view them in the result set.
In Demonstration 1, you will notice that you retrieve the query result once an SQL statement is executed using a Statement object. It acts like an iterator so that you can easily move through its data. In this context, it is useful to know that a ResultSet object maintains a cursor to point at the current row in the result set.
SQLException : This class is used to describe various database access errors (or any other errors that may occur in a database application).
Creating a Database and Inserting Records
Demonstration 1 shows how you can connect to a MySQL database and how you can retrieve the records from a table in the database.
Before I start, I create a database test, and then I create a table employee in that database. In the employee table, I insert three records only. Creating a database and creating a table inside the database is very easy. You can skip the following section contained in square brackets [ ] if you know these commands.
To create the database called test, you can use the following command:
To create the table called employee, you can use the following command:
To insert a record in your employee table, you can use the following command:
Similarly, you can insert other records.
Now, when you insert a record into the employee table, you need to supply the information for EmpId. In short, by using a primary key, you can uniquely identify a record.]
But to understand the upcoming demonstrations, you need not be familiar with MySQL Workbench in detail. Here, I have used this graphical tool to show you the current database and the tables in it before you start programming with JDBC.
MySQL Command Prompt View
Demonstration 1
Demonstration 2
In Demonstration 2, I’ll update some records, then I’ll delete a record. Finally, I’ll update the records in such a way that I can obtain the initial state of the table. For example, you’ll see that though Amit’s age was updated from 25 to 35, at the end I have reset it back to 25. Also, I have deleted the newly added record for John. Similarly, though I made a change to Bob’s salary, at the end I have reset the value.
Note
This program can be further improved if you use separate methods for display records and update (or, insert) records and call those methods from your main() method. You can follow the same for other demonstrations in this chapter. I just focused on updating and inserting the records in this example and kept it aligned with demonstration 1.
Demonstration 3
You can use parameterized SQL statements.
You can reuse the statement with new values.
You can provide batch processing and faster execution.
It is important to note that the first argument of these setter methods specifies the question mark placeholder. For example, the two setInt() calls specify the first and third placeholders, respectively; setString() specifies the second placeholder; and setDouble() specifies the fourth placeholder.
Q&A Session
13.3 Why is the use of PreparedStatement objects considered faster than using Statement objects?
PreparedStatement objects can contain precompiled SQL statements. So, if you pass the same query (with the same or different data) multiple times, DBMS can run the query much faster. But, in the case of a Statement object, SQL needs to validate the query each time you use it.
13.4 Is passing the parameters mandatory for PreparedStatement objects ?
Normally, you use PreparedStatement when your SQL query takes parameters. The SQL statement that takes parameters can help you to execute the statement with different values, which is very common in real-world scenarios. For simplicity and to make the program shorter, I have not used command-line arguments or user-defined inputs. But in practice, you can always pass the arguments using the command line, which in turn will replace the question marks before your query is processed.
13.5 How is the executeQuery() method different from executeUpdate()?
The executeUpdate() method is associated with insert, update, or delete operations or SQL statements that return nothing, such as DDL statements. This method does not return any ResultSet object.
On the other hand, executeQuery() executes an SQL statement that returns a single ResultSet object. This method cannot be called on PreparedStatement or CallableStatement (this will be discussed in the next demonstration).
13.6 What are the key advantages of using PreparedStatement?
You can pass parameterized SQL statements.
You can reuse the statement with different values.
You can provide batch processing.
Since it supports precompiled SQL statements, you may enhance the execution time.
13.7 What is batch processing ? Can you give an example?
By “batch processing,” I mean that you can execute a bunch (or group or set) of queries. The addBatch() and executeBatch() methods in the Statement interface can help you in this area.
Demonstration 4
This demonstration shows the use of the CallableStatement object . CallableStatement is an interface that extends PreparedStatement, which in turn extends the Statement interface. CallableInterface is used to execute stored procedures and functions in SQL.
Note
There are some significant differences between stored procedures and functions. For example, in MySQL, a stored procedure can be used to return one or multiple values or no value, whereas a function always returns single value. Also, you can call a function directly with a SQL statement while you cannot do the same for a procedure. A stored procedure can have IN, OUT, INOUT parameters but a stored function can have only IN parameters by default. To make the example short and simple, in Demonstration 4 you’ll see the use of a small function only.
The numbertable Table Created in the Database
FirstNumber | SecondNumber |
---|---|
12.3 | 15.7 |
32.5 | 25.3 |
25.0 | 75.0 |
You can see that the table has two attributes, FirstNumber and SecondNumber, and each row of the table contains various double type values. Let’s say you want to calculate the aggregate of the two double values of each row in the table; you can accomplish this task using a function called total().
- 1.
Create NumberTable and fill the table with necessary data.
- 2.
You create a function total() that accepts two double type values as parameters and returns the aggregate.
You can complete Step 1 and Step 2 in various ways and in your preferred order. In the following section, I give you the commands (with corresponding outputs) that I used once I connected my database to complete these steps. The SQL statements are shown in bold for a better readability. I am also putting the supporting comments inside brackets [ ].
Step 1
Step 2
Note
As per the MySQL 8.0 reference manual: “A routine is considered ‘deterministic’ if it always produces the same result for the same input parameters, and “’not deterministic’ otherwise. If neither DETERMINISTIC nor NOT DETERMINISTIC is given in the routine definition, the default is NOT DETERMINISTIC.”
Here is a snapshot from the MySQL 8.0 command-line client for better readability:
You can see that a CallableStatement object is created by invoking the prepareCall() method, and that the prepareCall() method accepts a String parameter.
Note
Like many other methods, there are various overloaded versions of the prepareCall() method. I have used the simplest one in this example.
Notice the three question marks. You know that these are used for method parameters. These parameters are sequential in nature, and the first parameter starts with 1.
Q&A Session
13.8 When should I prefer a Statement object over a PreparedStatement or a CallableStatement?
If you want to execute simple SQL statements (for example, select * from Table_name;” ), use a Statement object.
If you want to use precompiled statements, use PreparedStatement.
If you want to use stored procedures (or functions), use CallableStatement.
13.9 What is a stored procedure?
In simple words, if you want to repeat a sequence of tasks, you create a stored procedure. A stored procedure is much like writing a method in Java. The steps to create a stored procedure can vary across the databases.
In this chapter, I have used a simple function, total(), in Demonstration 4 to serve our needs.
13.10 You have used the term DDL in the context of SQL in some places. What does it mean?
DDL (Data Definition Language) statements are used to create or modify a database object’s structure. You use create, alter, drop, and truncate statements in this context.
DML (Data Manipulation Language) statements are used to retrieve, insert, update, and delete records in a database. For example, you use insert, update, delete, and select statements in this context. Some engineers prefer to put select statements in a separate category called DQL (Data Query Language).
DCL (Data Control Language) statements can be used to create various roles and permissions to control access to a database. For example, you may use grant and revoke statements in this context.
TCL (Transaction Control Language) statements are used to manage different transactions that occur in a database. For example, you may use commit, rollback, etc. statements in this context.
Note As said before, to understand each of these terms in detail, you may need to exercise SQL statements on your own. In this chapter, our focus was not on detailed coverage of SQL; the focus was on Java applications that can simply talk to a database and perform some basic operations.
Demonstration 5
This demonstration shows the use of a javax.sql.DataSource interface object to connect to a datasource. It is a new addition to the JDBC 2.0 API and a preferred way to connect to a datasource. Using a DataSource object can provide connection pooling and distributed transactions. But since you are just starting your journey, we’ll focus on the the connection part only.
In Demonstration 5, the getMySqlDataSource() method is used. In this method, you create a MySqlDataSource object, set the database URL, and pass the user ID and password to connect to the database. Once this information is set, you can use this MySqlDataSource object to connect to the database.
You will understand the changes better if you compare Demonstration 5 with Demonstration 1. To make things simple, only a small portion of code in Demonstration 1 has been changed, and there is no significant change in the output. But you must take note of this new way of connecting to the database.
Before you proceed, I suggest you go through the following points.
Points To Remember
A DataSource object is used for a particular DBMS (or some other datasource, such as a file). If you need to use multiple datasources, you need to deploy a separate DataSource object for each of them.
The MysqlDataSource name has recently been changed from com.mysql.jdbc.jdbc2.optional.MysqlDataSource to com.mysql.cj.jdbc.MysqlDataSource.
The DataSource interface is available in the javax.sql package. It has two overloaded methods: Connection getConnection() throws SQLException and Connection getConnection(String username, String password) throws SQLException. You can use either of them.
The DataSource interface implementation may vary from vendor to vendor. This is why, to connect to a MySQL database, I imported the com.mysql.cj.jdbc.MysqlDataSource class to get the basic implementation of the DataSource interface. If you wish to connect to a different database, say, Oracle, you may need to import the oracle.jdbc.pool.OracleDataSource class.
Summary
What is JDBC?
What is a database?
What is a DBMS? What are different types of DBMS?
What is RDBMS?
What is SQL?
How can a Java application talk to a database?
How can you connect to MySQL?
How do you use Statement, PreparedStatement, and CallableStatement in your program?
How can you invoke a small function using a Connection object?
As per the new recommendation, how can you use a javax.sql.DataSource interface object to connect to a datasource?