Sunteți pe pagina 1din 37

Session 15

DATABASES & JDBC


Agenda

• Relational Databases
• JDBC
What is a database?

• A database is a special set of files which:


– Stores data using a binary format
– Allows data to be inserted, deleted, updated,
and queried
• A database consists of multiple tables
– Each table is organized into columns and rows,
just like an Excel sheet.
• Data is found at the intersection between
column and row
RDBMS

• Relational Database Management System


• Examples: MSSQL Server, MySQL,
PostgreSQL, DB2, Oracle, …
• They are SW products suites which allow
for DB authoring (creation, deletion,
update, etc), DB programming, and of
course, data storage / organization.
SQL

• Structured Query Language


• Lets you access and manipulate databases:
– Execute queries against a DB => receive data / results
– Insert data into a DB
– Update records in a DB
– Delete records from a DB
– Create new DBs
– Create new tables in a DB
– Create stored procedures in a DB (more on this later)
– Create views in a DB
– Set up security: who can do which operations
SQL

• An ANSI standard
• BUT: most vendors have their own extensions to
the standard.
• However, they all support at least the 4 most
important commands:
– SELECT
– UPDATE
– DELETE
– INSERT
Activity – Postgresql installation

• Download installation package:


http://www.postgresql.org/downloa
d/windows/
• Windows: run the installer
Postgresql– DB commands

create database [db_name];


drop database [db_name];

Ex:
create database books;
drop database books;
SQL– sample commands

select 1+1; # this is a comment


create database books;
use books;
create table authors (id int, name varchar(64), email
varchar(64));
show tables;
describe authors;
insert into authors (id, name, email) values (1, “Georgel
Ionescu”, “georgel.ionescu@gmail.com”);
select * from authors;
select count(*) from authors;
SQL– language syntax

• Most actions on a DB are performed using SQL statements


• SQL is a free-form language whose statements can:
– Be in uppercase or lowercase (SELECT, select, SeLEct are all identical)
– Continue on the next line as long as you don’t split words, tokens or quoted
strings in two
– Be on the same line with other statements
– Start in any column
• SQL statements consist of clauses and expressions
– Example:
SELECT FirstName, LastName FROM employees WHERE location=‘TM’;
SQL– language syntax

• Most actions on a DB are performed using SQL statements


• SQL is a free-form language whose statements can:
– Be in uppercase or lowercase (SELECT, select, SeLEct are all identical)
– Continue on the next line as long as you don’t split words, tokens or quoted
strings in two
– Be on the same line with other statements
– Start in any column
• SQL statements consist of clauses and expressions
– Example:
SELECT FirstName, LastName FROM employees WHERE location=‘TM’;
columns table name expression
SQL– language syntax

• Most actions on a DB are performed using SQL statements


• SQL is a free-form language whose statements can:
– Be in uppercase or lowercase (SELECT, select, SeLEct are all identical)
– Continue on the next line as long as you don’t split words, tokens or quoted
strings in two
– Be on the same line with other statements
– Start in any column
• SQL statements consist of clauses and expressions
– Example:
SELECT FirstName, LastName FROM employees WHERE location=‘TM’;
columns table name expression
• SQL can be divided into two parts:
– DML: Data Manipulation Language (SELECT, UPDATE, etc)
– DDL: Data Definition Language (CREATE/ALTER database / table / index, etc)
Postgresql– language syntax

• Three comments style:


– “#” to the end of the line
– “--” to the end of the line, as long as after “--” there is at least one whitespace
– /* comment */: multi-line comment

SELECT 1+1; # single line comment


SELECT 1+1; -- single line comment
SELECT 1 + /* this is a multiline
comment */ 1;
Postgresql– Some functions

• ABS(): absolute value of number


• ADDDATE(): ADDDATE(‘2015-08-20’, INTERVAL 31 DAY)
• AVG(): select name, AVG(score) from student group by name;
• BETWEEN x AND y: SELECT 2 BETWEEN 1 and 3 => 1 (TRUE)
• CEIL(): select ceil(0.5) => 1
• CHAR(): select CHAR(77,121,83,81,’76’) => ‘MySQL’
• CHAR_LENGTH(): select char_length(‘MySQL’) => 5
• CONCAT(): select concat(‘My’, ‘SQL’) => ‘MySQL’
• CURRENT_DATE()/_TIME()/_TIMESTAMP(): select current_date();
• CURRENT_USER()
• FLOOR(): select FLOOR(0.5) => 0
• IF(), IFNULL(): select (1>2, 2, 3) => 3
• IN(): select 2 in (0,2,7,8) => 1 (TRUE)
• INSERT(str, pos, len, newstr)
Postgresql– Some functions

• LIKE: select expr like pattern => 1 or 0


• LOAD_FILE(path): reads and returns the file contents as a string
• LOWER(str): select lower(‘MySQL’) => ‘mysql’
• LTRIM/RTRIM/TRIM(str): LTRIM(‘ cucu’) => ‘cucu’
• MIN/MAX(expr): select name, MIN(score), MAX(score) from stud group by
name;
• %, MOD(): modulo
• NOT, !: boolean negation
• OR, ||: boolean or
• PASSWORD(str): select password(‘badpwd’) => ‘*AAB3E28…’
• POW(x, y): x to the power of y
• RAND(): random float in [0,1)
• ROW_COUNT(): insert into t values (1), (2), (3); select row_count()
=> 3
• SLEEP(duration)
• STRCMP(str1, str2): returns -1, 0, or 1.
• SUBSTR(str, pos [,len]): returns substring from a string
Index

• Indexes are used to speed up searches into a table by a


certain column, without looking into the whole table.
• Not visible to the user; just used to speed up searches
• CREATE INDEX index_name ON table_name(col_name);
Primary keys

• It is a constraint which uniquely identifies each record in a table


• Cannot contain null values!
• Each table should have one and only one PK

create table customers (


id int NOT NULL AUTO_INCREMENT,-- auto_increment is optional
lastName varchar(255) not null,
firstName varchar(255),
address varchar(255),
PRIMARY_KEY(id)
);
alter table customers add primary key(id);
Foreign keys

• A foreign key in a table points to a primary key in another table


• It is the mechanism of relating two tables by a table column
• Purpose: don’t duplicate data

create table orders (


id int not null auto_increment,
orderNr int not null,
client int,
primary key(id),
FOREIGN KEY(client) references customers(id)
);
Foreign keys

• A foreign key in a table points to a primary key in another table


• It is the mechanism of relating two tables by a table column
• Purpose: don’t duplicate data

create table orders (


id int not null auto_increment,
orderNr int not null,
client int,
primary key(id),
FOREIGN KEY(client) references customers(id)
); table_name(pk)
Joins

• The JOIN keyword is used in an SQL statement to query


data from two / more tables, based on a relationship
between certain columns in these tables
• Types of joins:
– Inner join / join: the default; return rows when there is at least one
match in both tables
– Left outer join: return all rows from the left table, even if there are no
matches in the right table => null values for the right table columns
– Right outer join: return all rows from the right table, even if there are
no matches in the left table => null values for the left table columns
– Full join: combination of left and right outer joins
– Cross join: a full cartesian product between left and right
• MySQL differs syntactically from standard SQL: JOIN,
CROSS JOIN and INNER JOIN are equivalent.
DB Normalization

• How we organize the tables, columns and


relationships such that data redundancy is
minimal
• Always a trade-off between less data redundancy
and higher speed
– Sometimes it’s better to have data redundancy in order for
some frequently used (and slow) queries to become faster
– This, of course, complicates the writes.
Transactions

• We may have multiple operations on some DB tables which need


to:
– Either all be executed successfully
– OR no one is executed at all
•  a set of operations need to be atomic
• This can be ensured by transactions
– Start transaction
– Execute statements
– IF no errors OR condition_holds THEN commit() ELSE rollback()
• DBMSs commit statements by default =>

SET autocommit=0;
start transaction;
do stuff;…
commit;
OR
rollback;
j2db

• Problem: Access a database from within a Java application,


execute queries, get the results, and transform them into Java
objects.
• Solution: Sun Microsystems (currently Oracle) created the JDBC
specifications for:
– JDBC driver: allows Java to interact with any DBMS
– JDBC API: specifies the API for a JDBC application: the steps to
needed to execute statements, process results, etc
JDBC Drivers

• Allows a Java application to connect to a DBMS


• Only a specification: the implementation needs to be done by
DBMS manufacturers
• Translator between Java and DBMS:
– Basic (built-in) data types bi-directional conversion
– Convert java.sql.Time to/from specific DATE* data types
– Support for character sets
– Support for XML data
– Transaction management
• JDBC application is able to work in the same manner with any
JDBC driver; we need a different drivers for different DBMSs
• BUT: the JDBC application does not change
– Only the SQL statements themselves, because JDBC allows the
execution of SQL statements AND these statements are DBMS-specific
JDBC Driver types

• Type 1 JDBC-ODBC bridge (MS Open Database Connection)


– Needs ODBC to be installed (MS specific)
– Java message  JDBC driver  ODBC driver  DB library API  DBMS
– Bad performance: too many layers
• Type 2 Java + Native API driver
– Java message  JNI impl of DB driver API  client-side DB lib API  DB
– Faster than type 1
– Good if DBMS has a client-side library API
• Type 3 (pure) Java protocol:
– Pure Java middleware client => platform independent
– Uses a platform-dependent Middleware (Application server): this is a minus!
• Able to perform connections and results set caching
• Actual DB driver (DBMS specific)

• Type 4 Java Database protocol: the most used driver today


– Pure Java DB driver using DB protocol (direct messages over socket / IPC)
– Platform-independent and DBMS-dependent
JDBC API

• java.sql and javax.sql (“x” comes from extension)


• Query a DB through JDBC:
– Load the JDBC driver (this is a class): class loader needs the class to be loaded
– Establish a connection to the DBMS
– Create a statement
– Execute it => obtain a ResultSet
– Process the ResultSet object
– Close the connection
JDBC – Load the driver

try {
Class.forName("org.postgresql.Driver").newInstance();
} catch (InstantiationException|IllegalAccessException|ClassNotFoundException
e){
System.err.println("Can’t load driver. Verify CLASSPATH");
System.err.println(e.getMessage());
}
JDBC – Create a connection

Connection conn = null;


DriverManager.setLoginTimeout(60); // wait 1 min; optional: DB may be busy, good to set a higher
timeout
try {
String url = new StringBuilder()
.append("jdbc:")
.append(type) // “mysql” / “db2” / “mssql” / “oracle” / ...
.append("://")
.append(host)
.append(":")
.append(port)
.append("/")
.append(dbName)
.append("?user=")
.append(user)
.append("&password=")
.append(pw).toString();
return DriverManager.getConnection(url);
} catch (SQLException e) {
System.err.println("Cannot connect to the database: " + e.getMessage());
}


JDBC – Query result

Connection conn = connect(”postgresql", "localhost", 5432, "books", “pianas", "abc123");


if (conn == null) return;
Statement st = null;
ResultSet rs = null;
final String format = "%20s%20s%12s\n";
try {
st = createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = st.executeQuery("select * from authors");
boolean hasResults = rs.next();
if (hasResults) {
System.out.format(format, "Name", "Email", "Birthdate");
do {
System.out.format(format, rs.getString("name"), rs.getString("email"), rs.getDate("birthdate"));
} while (rs.next());
} else {
System.out.println("No results");
}
} catch (SQLException e) {
System.err.println("Cannot execute query: " + e.getMessage());
} finally {
if (rs != null) try { rs.close(); } catch (SQLException e) { }
if (st != null) try { st.close(); } catch (SQLException e) { }
try { conn.close(); } catch (SQLException e) { }
}
JDBC – Query result

Connection conn = connect(”postgresql", "localhost", 5432, "books", “pianas", "abc123");


if (conn == null) return;
Statement st = null;
ResultSet rs = null;
final String format = "%20s%20s%12s\n";
try {
st = createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = st.executeQuery("select * from authors"); // plain SQL statement
boolean hasResults = rs.next(); // position on the first line (initially it’s at -1)
if (hasResults) {
System.out.format(format, "Name", "Email", "Birthdate");
do {
System.out.format(format, rs.getString("name"), rs.getString("email"), rs.getDate("birthdate"));
} while (rs.next());
} else {
System.out.println("No results");
}
} catch (SQLException e) {
System.err.println("Cannot execute query: " + e.getMessage());
} finally {
if (rs != null) try { rs.close(); } catch (SQLException e) { }
if (st != null) try { st.close(); } catch (SQLException e) { }
try { conn.close(); } catch (SQLException e) { } // optional. We might reuse the same connection
}
JDBC – Update / Insert / Delete

Connection conn = connect(”postgresql", "localhost", 5432, "books", "pianas", "abc123");


if (conn == null)
return;

PreparedStatement ps = null;
try {
ps = conn.prepareStatement("insert into authors (name, email, about, birthdate) values (?, ?, ?, ?)");
ps.setString(1, "Sample name");
ps.setString(2, "sample.name@email.com");
ps.setString(3, "About sample author");
ps.setDate(4, java.sql.Date.valueOf("1982-10-23"));
ps.executeUpdate();
} catch (SQLException e) {
System.err.println("Cannot insert author: " + e.getMessage());
} finally {
if (ps != null) try { ps.close(); } catch (SQLException e) { }
}
PreparedStatement

• Before it’s executed, an SQL query has to be compiled


• This happens when the execution method is called
• In case there are multiple calls with the same query, but with different
parameters (e.g. for multiple inserts / updates), then compilation takes too
long
• => It’s better to pre-compile the query => a sort of SQL pattern which is
compiled, than each interrogation will add the values in the pattern
“placeholders”
• Example:
"insert into authors (name, email, about, birthdate) values (?, ?, ?, ?)"
• This is possible with the help of PreparedStatements
• “?” is the placeholder
• Can be used also for select statements:
“select * from authors where id=?”
• Also good for preventing SQL injections!
CallableStatement

• Used for calling Stored Procedures and retrieve their results


– These are DBMS-specific procedures written in languages like PL/SQL, TransactSQL, ...
• Much faster: only one call from Java to DBMS, while multiple statements and
queries are executed on the DBMS-side:

Connection conn = connect(”postgresql", "localhost", 5432, "books", "pianas",


"abc123");
if (conn == null)
return;
CallableStatement st = null;
try {
st = conn.prepareCall("{ CALL STORED_PROC_SAMPLE }");
st.registerOutputParameter(1, Types.VARCHAR); // returns a VARCHAR
st.execute();
String result = st.getString(1);
} catch (SQLException e) {
System.err.println("Cannot execute call: " + e.getMessage());
} finally {
if (st != null) try { st.close(); } catch (SQLException e) {}
}
ResultSet

• Contains the results of the query

• Has a virtual cursor attached


– It is positioned before the first row (-1)
– First call to next() will move it to the first result (if any => true, else => false)

• The cursor can be moved to various positions in the result set: first(),
last(), previous(), relative(int n), absolute(int n)

• Get updates while other programs are updating DB:


createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);

• Move only forward:


createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet

• Update the items from the ResultSet into DB:


createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
results.updateString("name", "Updated name"); results.updateRow();

• Number of items pre-fetched in the ResultSet:


statement.setFetchSize(1000); // control the number of fetched items

• Delete row from the resultSet:


results.deleteRow() // deletes the current row

• Insert a new row in the resultSet and in the DB:


results.moveToInsertRow(); // remember current position and goto insert row
results.updateString("name", "New Name");
results.updateString("email", "email@email.com");
results.insertRow(); // insert the row in the DB
results.moveToCurrentRow(); // go to previous position (before insert)
JDBC transaction support

• Remember in MySQL:
set autocommit = 0; …stmt… commit OR rollback;

Connection conn = connect(”postgresql", "localhost", 5432, "books", "pianas", "abc123");


if (conn == null)
return;
try {
conn.setAutocommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate("insert into authors values (1, ‘A1’,’B1’,’C1’,’1990-01-01’)");
stmt.executeUpdate("insert into authors values (2, ‘A2’,’B2’,’C2’,’1990-01-01’)");
stmt.executeUpdate("insert into authors values (3, ‘A3’,’B3’,’C3’,’1990-01-01’)");
conn.commit();
conn.setAutocommit(true);
// ... Other updates, queries, ...
} catch (SQLException e) {
//...
} finally {
try { conn.close(); } catch (SQLException e) { }
}
Bibliography

• http://www.sqlcourse.com/
• http://www.w3schools.com/sql/
• https://jdbc.postgresql.org/documentation/
documentation.html
• http://www.tutorialspoint.com/postgresql/
• http://www.oracle.com/technetwork/java/ja
vase/jdbc/index.html
• https://docs.oracle.com/javase/tutorial/jdbc
/basics/
• http://www.tutorialspoint.com/jdbc/

S-ar putea să vă placă și