Java Course 13: JDBC & Logging

23
JDBC & Logging JDBC & Logging Anton Keks 2011 Java course - IAG0040 Java course - IAG0040

description

Lecture 13 from the IAG0040 Java course in TTÜ. See the accompanying source code written during the lectures: https://github.com/angryziber/java-course

Transcript of Java Course 13: JDBC & Logging

Page 1: Java Course 13: JDBC & Logging

JDBC & LoggingJDBC & Logging

Anton Keks 2011

Java course - IAG0040Java course - IAG0040

Page 2: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 22

Java course - IAG0040Anton Keks

JDBCJDBC

● Java DataBase Connectivity– The API for DB access from Java– Oriented towards relational databases– java.sql package– JDBC is DB vendor neutral

● Versions– Exists since Java 1.1– Java 1.4 & 1.5 ships with JDBC 3– Java 1.6 introduced JDBC 4

Page 3: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 33

Java course - IAG0040Anton Keks

JDBC driversJDBC drivers

● java.sql.Driver - the driver side of the JDBC layer is the part that interfaces with the actual database, and therefore is generally written by database vendors

● Most developers only need to know how to install and use drivers. The JDBC Driver API defines a set of interfaces which have to be implemented by a vendor

Page 4: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 44

Java course - IAG0040Anton Keks

JDBC driver typesJDBC driver types

● Type 1 use a bridge technology to connect a Java client to ODBC system. The JDBC-ODBC bridge from Sun is one example of a Type 1 driver

● Type 2 use native code library to access a database, wrapping a thin layer of Java around the native library, e.g. Oracle OCI driver

● Type 3 drivers define a generic network protocol that interfaces with a piece of custom middleware. The middleware component might use any other type of driver to provide the actual database access.

● Type 4 drivers are implemented entirely in Java. They understand database-specific networking protocols and can access the database directly without any additional software.

Page 5: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 55

Java course - IAG0040Anton Keks

JDBC driver summaryJDBC driver summary

Type 1ODBC bridge

Type 2Native API

Type 3Network

Type 4Pure Java

ODBCdiver

Native API

Middlewareserver

DB

Page 6: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 66

Java course - IAG0040Anton Keks

JDBC API basicsJDBC API basics

ResultSet

PreparedStatementStatement CallableStatement

Connection

DriverManager

Concrete Driver

Concrete DB

Oracle, MySQL,PostgreSQL, HSQLDB, etc

Application

Page 7: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 77

Java course - IAG0040Anton Keks

JDBC basic usageJDBC basic usage● Load the driver (was needed before JDBC 4)

– Class.forName(“driverClassName”);

– System property -Djdbc.drivers=driverClassName

● Use DriverManager to create connection– DriverManager.getConnection(url, user, password);

● Create statement for execution– connection.createStatement();

● Execute the query and get a ResultSet– statement.executeQuery(sql);

● Iterate over ResultSet: rs.next() and rs.getXXX()

● Free resources with close() methods

Page 8: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 88

Java course - IAG0040Anton Keks

ConnectionConnection

● java.sql.Connection● Represents an open connection to the DB● Obtained via a DriverManager

– DriverManager.getConnection(url, user, password)

● URL starts with jdbc:– The exact format depends on the vendor– jdbc:mysql://server:port/dbname– jdbc:hsqldb:mem:dbname– jdbc:oracle:thin:@server:port:sid

Page 9: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 99

Java course - IAG0040Anton Keks

Statement & PreparedStatementStatement & PreparedStatement

● java.sql.Statement– for execution of simple statements without

parameters– s = conn.createStatement();s.execute(“CREATE TABLE ..”);

● java.sql.PreparedStatement– for execution of parametrized statements via

'parameter binding'– s = conn.prepareStatement(“SELECT .. WHERE ID = ?”)s.setInt(1, value); ResultSet rs = s.executeQuery();

– allows for reuse of pre-compiled statements

Page 10: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1010

Java course - IAG0040Anton Keks

ResultSetResultSet

● java.sql.ResultSet– represents result of a SQL query, containing

multiple rows, similar to an Iterator– ResultSet rs = s.executeQuery(“SELECT ...”);while (rs.next()) {

rs.getString(1); or rs.getString(“COLUMN”);}rs.close();

– cursor movement by default is ResultSet.TYPE_FORWARD_ONLY

● Some drivers may support bidirectional movement

Page 11: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1111

Java course - IAG0040Anton Keks

CallableStatementCallableStatement

● java.sql.CallableStatement– extends PreparedStatement– intended for calling stored procedures in the DB– allows reading of OUT parameters instead of

getting a ResultSet– s = conn.prepareCall(“{call SOME_PROC(?, ?, ?)}”);s.setString(1, “some value”);s.registerOutParameter(2, Types.VARCHAR);s.registerOutParameter(3, Types.NUMERIC);

s.execute();String result1 = s.getString(2);int result2 = s.getInt(3);

Page 12: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1212

Java course - IAG0040Anton Keks

Resourse ManagementResourse Management

● All DB objects have the close() method– higher-level DB objects automatically close the

lower-level ones– conn.close() will close all underlying statements

● Don't forget proper closing– same pattern applies as with java.io– it is a good idea to put close() into a finally block!

Page 13: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1313

Java course - IAG0040Anton Keks

MetadataMetadata

● DatabaseMetaData, ResultSetMetaData, ParameterMetaData– Metadata provides additional information about

the respective DB objects– Can be used for discovering of DB structure and

other 'advanced' or non-standard code– DatabaseMetaData metadata = conn.getMetaData();String name = metadata.getDatabaseProductName();

– ResultSet rs = s.executeQuery(“SELECT ...”);ResultSetMetaData metadata = rs.getMetaData();int columns = metadata.getColumnCount();

Page 14: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1414

Java course - IAG0040Anton Keks

TransactionsTransactions

● Connection auto-commit is ON by default– Use conn.setAutoCommit(false) to control

transactions manually● Transaction control

– connection.commit() persists the changes– connection.rollback() cancels the changes– connection.setSavepoint() bookmarks transactions– exact behaviour depends on the concrete DB

Page 15: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1515

Java course - IAG0040Anton Keks

DataSourceDataSource

● java.sql.DataSource– a bean-style alternative to DriverManager– implemented by a DB vendor

● Is usually initialized in a vendor-specific way in the application container– provides getConnection() method

● Spring Framework and Commons-DBCP have useful implementations, e.g. for connection pooling

Page 16: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1616

Java course - IAG0040Anton Keks

Data Access PatternsData Access Patterns

● Define where to put the JDBC-related code in an application

● In general:– Isolate and encapsulate JDBC code– Very few classes should know where the data

comes from– Pass data around as domain objects, not ResultSets

or a mix of Strings or primitive types

Page 17: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1717

Java course - IAG0040Anton Keks

Active Domain Object PatternActive Domain Object Pattern

● aka ActiveRecord● Wraps a row in a table or view, encapsulates

DB access, and adds domain logic– JDBC only used internally, not visible from the

outside– Person person = Person.create();person.setName(“John Doe”);person.save();

– Person person = Person.load(“John Doe”);

Page 18: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1818

Java course - IAG0040Anton Keks

Data Accessor PatternData Accessor Pattern

● aka Data Access Object (DAO)● Encapsulates physical data access in a single

component, exposing logical operations– Application code maintains knowledge about the

underlying data model, but is decoupled from the data access possibilities

– Domain objects know nothing about the DB– PersonAccessor dao = new JDBCPersonAccessor();Person person = dao.loadPerson(“John Doe”);person.setName(“John Smith”);dao.save(person);

Page 19: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 1919

Java course - IAG0040Anton Keks

TestingTesting● Clear separation of DB access logic from

business logic makes testing and maintenance a lot easier

● All JDBC interfaces can be easily mocked– Connection conn = createMock(Connection.class);

● Sometimes it is wise to test the full-cycle– Use in-memory database, e.g. HSQLDB– Initialize the data there and substitute DB

connection with the fake in-memory one– DBUnit can help with that

Page 20: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 2020

Java course - IAG0040Anton Keks

LoggingLogging● When writing more complex applications, you need logging in

your code

– you don't want to show low-level crash info to end-users

– debugging of bugs on production is usually not possible

● There are many possibilities to implement logging:

– System.out / System.err or other java.io classes – usually primitive and not flexible solution

– java.util.logging, e.g. Logger class – logging API included in Java since 1.4, configurable and extensible

– Log4J – very popular de-facto standard framework, very powerful, has a very good API

– Jakarta commons-logging – the facade for different logging APIs

Page 21: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 2121

Java course - IAG0040Anton Keks

java.util.loggingjava.util.logging

● Logger LOG = Logger.getLogger(this.getClass().getName());

– Loggers have hierarchical structure ('.' separated), it is a good idea to use full class name as a logger name

– Logger often used as a static member (for convenience)

● Loggers can be used for logging information with various levels

– SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST

– LOG.severe(“We have a problem!”);

– LOG.log(Level.SEVERE, “We have a problem”, exception);

● java.util.logging is configurable

– by default it uses $JAVA_HOME/jre/lib/logging.properties

– specific file is specified with sys. property java.util.logging.config.file

Page 22: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 2222

Java course - IAG0040Anton Keks

java.util.logging (cont)java.util.logging (cont)● Logger is used to produce LogRecords

– every LogRecord has a specified logging Level

– every Logger may have its own Level assigned

– or they inherit Level from their parent

● LogRecords are passed to one or more Handlers

– e.g. ConsoleHandler, FileHandler, MemoryHandler, SocketHandler, etc

– every handler writes logs greater or equal to their assigned Level

● Formatters are used for formatting of LogRecords

– SimpleFormatter or XMLFormatter

● a LogRecord is written only if its Level is greater than of its Logger's and if there is a Handler configured to write at this Level

● Filters may be used for more fine-grained control of what should be logged

Page 23: Java Course 13: JDBC & Logging

Lecture 13Lecture 13Slide Slide 2323

Java course - IAG0040Anton Keks

Log4J (org.apache.log4j)Log4J (org.apache.log4j)

● Logger LOG = Logger.getLogger(this.getClass());

– Loggers have hierarchical structure ('.' separated), same as util.logging

● Loggers can be used for logging information with various levels

– FATAL, ERROR, WARN, INFO, DEBUG are default levels

– LOG.error(“We have a problem!”, exception);

● Log4J is fully configurable with external files

– there is no default configuration

– it automatically looks for log4j.xml or log4j.properties in classpath

– can be overriden with log4j.configuration system property

– every named logger can have its own configuration

– different appenders can be used for writing the actual data