Sie sind auf Seite 1von 14

Islamic University of Gaza

Faculty of Engineering
Department of Computer Engineering
ECOM 3422: Database Systems [spring 2020] Abeer J. Al-Aydi &
Abdallah H. Azzami

Lab 7
JDBC 1 [Part 2]

Objectives
1. To be familiar with JDBC library statements to execute queries and updates.
2. To build organized and meaningful outputs from resultsets and metadata.

Table of Content
OBJECTIVES _________________________________________________________________________________________ 1
TABLE OF CONTENT ___________________________________________________________________________________ 1
INTRODUCTION ______________________________________________________________________________________ 2
CONNECT TO A DATABASE _____________________________________________________________________________ 2
READING GENERAL DATABASE METADATA ________________________________________________________________ 2
JDBC STATEMENTS____________________________________________________________________________________ 3
JAVA.SQL.STATEMENT __________________________________________________________________________________ 3
Creating a java.sql.Stamenet________________________________________________________________________ 3
Giving parameters to a Statement ___________________________________________________________________ 3
JAVA.SQL.PREPAREDSTATEMENT ___________________________________________________________________________ 4
Creating a java.sql.PreparedStamenet ________________________________________________________________ 4
EXECUTING JDBC SQL STATEMENTS ______________________________________________________________________ 5
EXECUTION METHODS __________________________________________________________________________________ 5
executeUpdate() _________________________________________________________________________________ 5
executeQuery() __________________________________________________________________________________ 5
execute() _______________________________________________________________________________________ 5
EXECUTION RESULTS ___________________________________________________________________________________ 5
UpdateCount ____________________________________________________________________________________ 5
ResultSet _______________________________________________________________________________________ 5
ResultSetMetaData _______________________________________________________________________________ 6
STATEMENT INSTANCE RESULTS METHODS _____________________________________________________________________ 6
EXAMPLES __________________________________________________________________________________________ 8
LABWORK__________________________________________________________________________________________ 13
Lab 7 | JDBC 1

Introduction
With the help of JDBC API, we can connect to a database, query it, add data, update data and even
delete data from it very easily. New JDBC releases have features geared towards both the client-side
(namely the package java.sql) and the server-side (javax.sql). Our focus now is on the client-side package.
In this part of the lab we will walk you through the steps of querying data from a table, inserting a
row into a table, updating existing data in a table, and deleting data from a table. Together, we will build
an interactive command line program that understands our new ‘super simple’ queries😊 and executes
them on our sample university database.

Connect to a database
In part1, we learned that the slandered steps for connecting to a database with JDBC from a Java
application are:
1. Locate the database we want to access.
2. Import the java.sql library in application project.
3. Download JDBC PostgreSQL jar file.
4. Ensure the JDBC PostgreSQL driver is on our classpath, or include it as a library.
5. Use the JDBC library to obtain a connection to the database.
6. Test the connection by issuing simple SQL commands.
7. Finally, close the connection.

Reading General Database Metadata


JDBC DatabaseMetaData is an interface from the java.sql package. DatabaseMetaData is generally
provided by the Database application vendor in order to allow database programmers to know meta
information about the current database, current database driver, current DBMS, and even current system.
This interface is a very useful tool for programmers who need to explore the database.
Example
try {
DatabaseMetaData metadata = conn.getMetaData();
System.out.println("DBMS Name: " + metadata.getDatabaseProductName());
System.out.println("DBMS Version: " + metadata.getDatabaseProductVersion());
System.out.println("Logged User: " + metadata.getUserName());
System.out.println("JDBC Driver: " + metadata.getDriverName());
System.out.println("Driver Version: " + metadata.getDriverVersion());
System.out.println("Server URL: " + metadata.getURL());
System.out.println("Max connections: " + metadata.getMaxConnections());
} catch (SQLException e) {}

Result:

Page 2 of 14
Lab 7 | JDBC 1

JDBC Statements
Today, we will use two statement types in our application; java.sql. Statement and java.sql.PreparedStatement

java.sql.Statement
We use this statement interface for general-purpose access to our database. It is useful when
using static SQL statements at runtime. The Statement interface cannot accept parameters and doesn’t
contain parameters setters.

Creating a java.sql.Stamenet
Before you can use a Statement object to execute an SQL statement, you need to create it using the
Connection's createStatement( ) method, as in the following:
String query = "Select max(salary) from instructor;";
Statement stmt=con.craeteStatement();
Stmt.execute(query);
Note that this method doesn’t take a string query as parameter:

Giving parameters to a Statement


When a programmer who is using the statement interface needs to take input parameters at
runtime, his only option is to use string concatenations to construct the query statement, for
example

String query = "Select count(distinct "+ attr +" ) from "+ table +" ;";

Using this way to receive input parameters exposes the program to a very famous and destructive
vulnerability that can exploited by attackers: “SQL injection”. If a programmer wants to use this
string concatenation way, it is very important for him to implement countermeasures such as using
regular expressions to validate inputs. Or he can avoid this headache and use PreparedStatement
instead.

Page 3 of 14
Lab 7 | JDBC 1

java.sql.PreparedStatement
PreparedStatement is a more sophisticated version of the Statement interface.
PreparedStatement allows the programmer to create precompiled query statements with place holders
for parameters. PreparedStatement can also be used with an SQL statement with no parameter.
PreparedStatement is the correct choice when you plan to use the same SQL statement many times. If
you do so, it does not compile the query every time you use it. Instead, it compiles the query only once
then it uses the compiled version every time that statement is executed.

Creating a java.sql.PreparedStamenet
Unlike Statement, PreparedStatement is given an SQL statement when it is created. You need to
create one using the Connection's PrepareStatement (String) method, as in the following:

String query = "UPDATE student SET tot_cred = ? WHERE id = ?";


PreparedStatement ptmt=con.prepareStatement(query);

This ptmt object contains the query that is prepared to receive parameters. Now we pass the
parameter to ptmt object. If we at some point change our mind, we can easily change those
parameters before the execution.

ptmt.setString(2,"2203");
ptmt.setInt(1,80);
ptmt.setString(2,"2223");

Although PreparedStatement objects can be used for SQL statements with no parameters, you
probably use them most often for SQL statements that take parameters. The advantage of using SQL
statements that take parameters is that you can use the same statement and supply it with different
values each time you wish to execute it.

Page 4 of 14
Lab 7 | JDBC 1

Executing JDBC SQL statements


To execute one of the JDBC statements we mentioned earlier, we have the following options:

Execution methods
executeUpdate()
To update data in the database. executeUpdate is used to execute the UPDATE, INSERT, DELETE
queries. executeUpdate returns the number of rows affected by the INSERT, UPDATE, or DELETE
statement.
executeQuery()
executeQuery is used to execute the SELECT queries.
execute()
If you do not know ahead of time whether the SQL statement will be a SELECT or an UPDATE/
INSERT/ DELETE, then you can use this method. It will return true if the SQL query was a SELECT,
or false if it was an UPDATE, INSERT, or DELETE statement.

Be careful: if you use a PreparedStatement, then all of the above execution methods will cause a
runtime error if you pass a query string as a parameter. You must write pStmt.execute() not
pStmt.execute(qry:String).

Execution Results
UpdateCount
If executeUpdate() returns without throwing an exception, it returns the number of rows affected
by the SQL statement (an INSERT typically affects one row, but an UPDATE or DELETE statement
can affect more).
ResultSet
JDBC ResultSet is an interface of java.sql package. It is a table of data representing a database
SELECT query result, which is obtained by calling the executeQuery() method on statements.
A ResultSet object maintains a cursor pointing to its current row of data. Initially the cursor is
positioned before the first row. The next() method moves the cursor to the next row. The next()
method returns false when there are no more rows in the ResultSet object. Because of that it can
be used in a while loop to iterate through the result set.
The default ResultSet object is not updateable therefore the cursor moves only forward from the
first row to the last row only once.
ResultSet provides getXXX() methods to get data from each row iteration. Here XXX represents
datatypes. You also need to specify only the column name or index number ( starting at 1 ) in
getter parameters.

Page 5 of 14
Lab 7 | JDBC 1

ResultSetMetaData
Metadata means data about data. If you wish to get the metadata of a table, like total number of
columns, column names, column types etc. then you can use ResultSetMetaData.
ResultSetMetaData is useful because it provides methods to get metadata from the ResultSet
object.
Geting the ResultSetMetaData object:
The getMetaData() method of ResultSet interface returns the object of ResultSetMetaData.
Commonly used methods of ResultSetMetaData interface:
1. getColumnCount() : int
2. getColumnName(int index) : String
3. getColumnTypeName(int index) : String
4. getTableName(int index) : String

Statement instance results methods


After we talked about results, I’d like to tell that each of statement and preparedStatement instances has
many result methods that initially returns the default {-1, null, false} values, but after you call any execute
method on it, the result methods will return meaningful values. What the advantage of that? It is
important in the case of using “execute()” which returns a boolean value that indicates the query type, if
the statement was a SELECT query, you can retrieve the results by calling the getResultSet() method on
that statement instance (statement or preparedStatement). If the statement was an UPDATE, INSERT, or
DELETE statement, you can retrieve the affected rows count by calling getUpdateCount() on the
Statement instance. These methods are also important when you need to return back to the open
executed statement’s results without executing it another time.

Example1( execute() for select query): Get count of all instructors.


void getInstructorsCount(){
try {
Statement st = conn.createStatement();
if(st.execute("select count(*) as c from instructor;")){
if(st.getResultSet().next())
System.out.println(st.getResultSet().getInt(1));
}

} catch (SQLException ex) {


System.out.println(ex.getMessage());
}
}
In this example, we can simply use Statement, and as the query is SELECT we can simply execute statement with
executeQuery(), but here we want to test the knowledge of the last topic, so we use the execute() method which
will returns true in our query case.
We get the query result by the statement instance using the corresponding st.getResultSet() method, but firstly we
need to move the cursor forward, we include this forwarding in an if condition to guarantee that the cursor doesn’t
point to a null, after that we get the result “single count value” from the resultset by the suitable getter method on
intended column, the first column in our case, whose type is integer.

Page 6 of 14
Lab 7 | JDBC 1

Example2( execute() for update query): Given student id, update his name.
void updateStudentName(){
try {
PreparedStatement pst = conn.prepareStatement(
"update student set name = ? where id = ?;");
pst.setString(1, "Alex");
pst.setString(2, "99978");
if(!pst.execute()){
System.out.println("Rows "+pst.getUpdateCount());
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
In this example, we need parameters placeholders in query , so we use PreparedStatement, and as the query is
UPDATE we can simply execute statement with executeUpdate(), but here we want to test the knowledge of the last
topic, so we use the execute() method which will returns false in our query case.
We get the query result by the PreparedStatement instance using the corresponding pst.getUpdateCount ()
method, which tell us about the number of rows that are affected.

Page 7 of 14
Lab 7 | JDBC 1

Examples
Example1: Write a JAVA method that returns the maximum of students IDs.
int getMaxStdID() {
//executeQuery using Statement
String SQL = "SELECT max(id) FROM student;";
int max = 0;
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(SQL)
){
rs.next();
max = rs.getInt(1);
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
return max;
}
In this example, we can simply use Statement, and as the query is SELECT we can simply execute statement with
executeQuery(SQL), which returns a ResultSet object, firstly we need to move the cursor forward with rs.next(),
after that we get the result “single max value” from the resultset by the suitable getter method on intended column,
the first column in our case, whose type is integer.

Notice the try-with-resources Statement.


The try-with-resources statement is a try statement that declares one or more resources inside the try
parentheses. A resource is an object that must be closed after the program is finished with it. The try-with-
resources statement ensures that each resource is closed at the end of the try block. No matter if the try
block concluded without errors or ended dur to an exception, in both cases try-with-resources ensures it
is closed. Any object that implements java.lang.AutoCloseable, which includes all objects which
implement java.io.Closeable, can be used as a resource. JDBC implements
java.lang.AutoCloseable for all its resources objects, so we will declare any JDBC resources in
try-with-resources statement.

Page 8 of 14
Lab 7 | JDBC 1

Example2: Write a JAVA method to print all instructors information.


void getAllInstructors() {
String SQL = "SELECT * FROM instructor ;";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(SQL)){

System.out.println("\n Fetching Query..............");

while (rs.next()) {
System.out.printf("%-20s", rs.getString(1));
System.out.printf("%-20s", rs.getString(2));
System.out.printf("%-20s", rs.getString(3));
System.out.printf("%-20f", rs.getDouble(4));
System.out.println();
}
}
catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}

Page 9 of 14
Lab 7 | JDBC 1

Example3(ResultSetMetaData)
try {
PreparedStatement ps = conn.prepareStatement("select * from student");
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println("Total columns: " + rsmd.getColumnCount());
System.out.println("Column Name of 1st column: " + rsmd.getColumnName(1));
System.out.println("Column Type Name of 1st column: " +
rsmd.getColumnTypeName(1));
} catch (SQLException e) {}

This example illustrates how we can get information about the table of the ResultSet.

Result:

Example2 – another version


void getAllInstructors() {
//executeQuery using Statement
String SQL = "SELECT * FROM instructor ;";
try (
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(SQL)) {
ResultSetMetaData md = rs.getMetaData();

System.out.println("\n Fetching Query..............");


for (int i = 1; i <= md.getColumnCount(); i++) {
System.out.printf("%-20s", md.getColumnLabel(i));
}

System.out.println("");

while (rs.next()) {
for (int i = 1; i <= md.getColumnCount(); i++) {
System.out.printf("%-20s", rs.getString(i));
}
System.out.println();
}

} catch (SQLException ex) {


System.out.println(ex.getMessage());
}}
This example illustrates how we can extract data and deal with resultset even if we initially don’t have any
information about its columns number and types, using the metadata of this ResultSet.

Page 10 of 14
Lab 7 | JDBC 1

Example4: Write a JAVA method that insert a student, method takes name and
dept_name from user, initially set tot_cred to zero, give the next available
id (maxID+1) for this student.
void insertStudent(String name, String dept) {
String SQL = "INSERT INTO student(id,name,dept_name,tot_cred) "
+ "VALUES(?,?,?,?)";
int addID = getMaxStdID() + 1;

try (PreparedStatement pstmt = conn.prepareStatement(SQL)) {

pstmt.setString(1, String.valueOf(addID));
pstmt.setString(2, name);
pstmt.setString(3, dept);
pstmt.setInt(4, 0);

int affectedRows = pstmt.executeUpdate();


// check the affected rows
if (affectedRows > 0) {
System.out.println("added successfully :)\n ID is " + addID);
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}

Example5: Write a JAVA method that updates the instructor salary,


method should take the id of the instructor and the new salary.
void updateSalary(String id, String newVal) {
String SQL = "UPDATE instructor"
+ " SET salary = ? "
+ "WHERE id = ? ;";

int affectedrows = 0;

try (PreparedStatement pstmt = conn.prepareStatement(SQL)) {

pstmt.setDouble(1, Double.parseDouble(newVal));
pstmt.setString(2, id);

affectedrows = pstmt.executeUpdate();

} catch (SQLException ex) {


System.out.println(ex.getMessage());
}
if (affectedrows > 0) {
System.out.println("The instructor with id = " + id +
" is updated successfully");
}
}

Page 11 of 14
Lab 7 | JDBC 1

Example6: Write a JAVA method that deletes the student who has the given
id, method takes the id of the student from user.
void deleteByID( String id) {

String SQL = "DELETE FROM student WHERE id = ?";


int affectedrows = 0;

try (PreparedStatement pstmt = conn.prepareStatement(SQL)) {


pstmt.setString(1, id);
affectedrows = pstmt.executeUpdate();
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
if (affectedrows > 0) {
System.out.println("The student with id = " + id +
" is deleted successfully");
}
}

Page 12 of 14
Lab 7 | JDBC 1

Labwork
Using the knowledge mentioned above, write a Java application that receives ‘super simple query’
commands from the user via command line (console or terminal), executes those commands on our
university database, and shows the output.
Examples of our ‘super simple’ queries:

Query Use
get student all views all students in our university
get student count shows how many students we have
get instructor all views all instructors in our university
get instructor count shows how many instructors we have
add student Amal Music Insert student with name Amal and dept. name Music to our
university
mod student id 2525 % name Hala Updates the name of student who has the ID 2525
mod instructor id 2525 % dept Updates the dept_name of instructor who has the ID 2525
Finance
mod student id 2525 % cred 100 Updates the tot_cred of student who has the ID 2525
mod instructor id 2525 % salary 2000 Updates the salary of instructor who has the ID 2525
del student id 2222 Delete the student who has the id 2222 from our university
del student name Amani Delete the student whose name is Amani from our university

Page 13 of 14
Lab 7 | JDBC 1

Screenshot for running some commands:

Page 14 of 14

Das könnte Ihnen auch gefallen