software architecture 3 data access

82
Software Architecture 3 Data Access Haopeng Chen REliable, INtelligent and Scalable Systems Group (REINS) Shanghai Jiao Tong University Shanghai, China e-mail: [email protected] http://reins.se.sjtu.edu.cn/~chenhp

Upload: others

Post on 03-Nov-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Software Architecture 3 Data Access

Software Architecture 3Data Access

Haopeng Chen

REliable, INtelligent and Scalable Systems Group (REINS)

Shanghai Jiao Tong University

Shanghai, China

e-mail: [email protected]

http://reins.se.sjtu.edu.cn/~chenhp

Page 2: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsAgenda

• Access Database via JDBC/ODBC Reading

• Access Database via ORM Reading

• XML-based Data Representation

2

Page 3: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsJDBC Specification

• The JDBCTM API provides – programmatic access to relational data from the JavaTM programming

language.

• The JDBC API is part of the Java platform– which includes the JavaTM Standard Edition (Java SETM) and the JavaTM

Enterprise Edition (Java EETM).

• The JDBC 3.0 API is divided into two packages: – java.sql and javax.sql.

– Both packages are included in the J2SE and J2EE platforms.

3

Page 4: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsJDBC Overview

• Establishing Connection– The JDBC API defines the Connection interface to represent a connection

to an underlying data source.

• DriverManager or Datasource

• Executing SQL Statements and Manipulating Results– DatabaseMetadata

– Statement, PreparedStatement, and CallableStatement.

– ResultSet and RowSet

4

Page 5: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsEstablishing Connection

• To obtain a connection, the application may interact with either:– the DriverManager class working with one or more Driver

implementations

OR– a DataSource implementation

5

Page 6: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsEstablishing Connection

• DriverManager– registerDriver and getConnection

// Load the driver. This creates an instance of the driver

// and calls the registerDriver method to make acme.db.Driver available to clients.

Class.forName("acme.db.Driver");

// Set up arguments for the call to the getConnection method.

// The sub-protocol "odbc" in the driver URL indicates the

// use of the JDBC-ODBC bridge.

String url = "jdbc:odbc:DSN";

String user = "SomeUser";

String passwd = "SomePwd";

// Get a connection from the first driver in the DriverManager

// list that recognizes the URL "jdbc:odbc:DSN".

Connection con = DriverManager.getConnection(url, user, passwd);

6

Page 7: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsEstablishing Connection

• DataSource– A logical name is mapped to a DataSource object via a naming service

that uses the Java Naming and Directory Interface TM (JNDI).

7

Property Name Type Description

databaseName String name of a particular database on a server

dataSourceName String a data source name

description String description of this data source

networkProtocol String network protocol used to communicate with the server

password String a database password

portNumber int port number where a server is listening for requests

roleName String the initial SQL rolename

serverName String database server name

user String user’s account name

Page 8: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsEstablishing Connection

• DataSource– A logical name is mapped to a DataSource object via a naming service

that uses the Java Naming and Directory Interface TM (JNDI).

// Create a VendorDataSource object and set some properties

VendorDataSource vds = new VendorDataSource();

vds.setServerName("my_database_server");

vds.setDatabaseName("my_database");

vds.setDescription("data source for inventory and personnel");

// Use the JNDI API to register the new VendorDataSource object.

// Reference the root JNDI naming context and then bind the

// logical name "jdbc/AcmeDB" to the new VendorDataSource object.

Context ctx = new InitialContext();

ctx.bind("jdbc/AcmeDB", vds);

8

Page 9: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsEstablishing Connection

• DataSource– A logical name is mapped to a DataSource object via a naming service

that uses the Java Naming and Directory Interface TM (JNDI).

// Get the initial JNDI naming context

Context ctx = new InitialContext();

// Get the DataSource object associated with the logical name

// "jdbc/AcmeDB" and use it to obtain a database connection

DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB");

Connection con = ds.getConnection("user", "pwd");

9

Page 10: Software Architecture 3 Data Access

REliable, INtelligent & Scalable Systems

10

Java Naming and Directory Interface

Page 11: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsConcepts

• Name– A people-friendly identifier for identifying an object or a reference to an

object.

• Binding– The association of an atomic name with an object.

• Context– An object whose state is a set of bindings that have distinct atomic

names.

• InitialContext– The starting point for resolution of names for naming and directory

operations.

• ContextFactory– A specialization of an object factory. It accepts information about how to

create a context, such as a reference, and returns an instance of the context.

11

Page 12: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsGet InitialContext

• Hardcode - WeblogicHashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");

env.put(Context.PROVIDER_URL,"t3://localhost:7001");

InitialContext ctx = new InitialContext(env);

• jndi.properties - JBossjava.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

java.naming.provider.url=jnp://localhost:1099

12

Page 13: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsStatements

• Statement– defines methods for executing SQL statements that do not contain

parameter markers

• PreparedStatement– adds methods for setting input parameters

• CallableStatement– adds methods for retrieving output parameter values returned from

stored procedures

13

Page 14: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsStatement

// get a connection from the DataSource object ds

Connection conn = ds.getConnection(user, passwd);

// create two instances of Statement

Statement stmt1 = conn.createStatement();

Statement stmt2 = conn.createStatement();

// Setting ResultSet Characteristics

Statement stmt = conn.createStatement(

ResultSet.TYPE_SCROLL_INSENSITIVE,

ResultSet.CONCUR_UPDATABLE,

ResultSet.HOLD_CURSOR_OVER_COMMIT);

14

Page 15: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsStatement

// Executing Statement and return ResultSet

ResultSet rs = stmt.executeQuery(" select TITLE, AUTHOR, ISBN " +

"from BOOKLIST”);

while (rs.next()){

...

}

// Returning an Update Count

Statement stmt = conn.createStatement();

int rows = stmt.executeUpdate(" update STOCK set ORDER = ‘Y’ " +

"where SUPPLY = 0”);

if (rows > 0) {

...

}

15

Page 16: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsPreparedStatement

// Creating a PreparedStatement

Connection conn = ds.getConnection(user, passwd);

PreparedStatement ps = conn.prepareStatement(

“INSERT INTO BOOKLIST" +"(AUTHOR, TITLE, ISBN) VALUES (?, ?, ?)”);

// Setting Parameters

ps.setString(1, “Zamiatin, Evgenii”);

ps.setString(2, “We”);

ps.setLong(3, 0140185852);

// ParameterMetaDataPreparedStatement pstmt = conn.prepareStatement(

"SELECT * FROM BOOKLIST WHERE ISBN = ?");...ParameterMetaData pmd = pstmt.getParameterMetaData();int colType = pmd.getParameterType(1);...

16

Page 17: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsPreparedStatement

// ResultSetMetaData

PreparedStatement pstmt = conn.prepareStatement(

"SELECT * FROM CATALOG");

ResultSetMetaData rsmd = pstmt.getMetaData();

int colCount = rsmd.getColumnCount();

int colType;

String colLabel;

for (int i = 1; i <= colCount; i++) {

colType = rsmd.getColumnType(i);

colLabel = rsmd.getColumnLabel(i);

...

}

17

Page 18: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsCallableStatement

// Creating a CallableStatementCallableStatement cstmt = conn.prepareCall(“{? = call validate(?, ?)}”);

// Setting IN ParametersCallableStatement cstmt = con.prepareCall(

"{CALL PROC(?, "Literal_Value", ?)}");cstmt.setString(1, "First");cstmt.setString(2, "Third");

// Setting OUT ParamtersCallableStatement cstmt = conn.prepareCall(

“{CALL GET_NAME_AND_NUMBER(?, ?)}");cstmt.registerOutParameter(1, java.sql.Types.STRING);cstmt.registerOutParameter(2, java.sql.Types.FLOAT);cstmt.execute();

// Retrieve OUT parametersString name = cstmt.getString(1);float number = cstmt.getFloat(2);

18

Page 19: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsManipulate result

• ResultSet– Types

1. TYPE_FORWARD_ONLY

2. TYPE_SCROLL_INSENSITIVE

3. TYPE_SCROLL_SENSITIVE

– Concurrency

1. CONCUR_READ_ONLY

2. CONCUR_UPDATABLE

– Holdability

1. HOLD_CURSORS_OVER_COMMIT

2. CLOSE_CURSORS_AT_COMMIT

19

Page 20: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsManipulate result

• RowSet– A javax.sql.RowSet object encapsulates a set of rows that have been

retrieved from a tabular data source.// Set propertiesrset.setDataSourceName("jdbc/SomeDataSourceName");rset.setTransactionIsolation(

Connection.TRANSACTION_READ_COMMITTED);rset.setCommand("SELECT NAME, BREED, AGE FROM CANINE");

// Events listenersRowSetListener listener = ...;rset.addRowSetListener(listener);

– Rowsets can generate three different types of events:1. Cursor movement events2. Row change events 3. Rowset change events

20

Page 21: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsManipulate result

• RowSet// Set parameters

rset.setCommand("SELECT NAME, BREED, AGE FROM CANINE WHERE NAME = ?");

rset.setString(1, "spot");

rset.execute();

// iterate forward through the rowset

rset.beforeFirst();

while (rset.next()) {

System.out.println(rset.getString(1) + " " + rset.getFloat(2));

}

21

Page 22: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsODBC Specification

• ODBC is a specification for a database API. – This API is independent of any one DBMS or operating system; although

this manual uses C, the ODBC API is language-independent.

• The functions in the ODBC API are implemented by developers of DBMS-specific drivers. – Applications call the functions in these drivers to access data in a DBMS-

independent manner.

– A Driver Manager manages communication between applications and drivers.

• It is important to understand that ODBC is designed to expose database capabilities, not supplement them.

22

Page 23: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsODBC Architecture

• The ODBC architecture has four components:– Application Performs processing and calls ODBC functions to submit

SQL statements and retrieve results.

– Driver Manager Loads and unloads drivers on behalf of an application. Processes ODBC function calls or passes them to a driver.

– Driver Processes ODBC function calls, submits SQL requests to a specific data source, and returns results to the application. If necessary, the driver modifies an application's request so that the request conforms to syntax supported by the associated DBMS.

– Data Source Consists of the data the user wants to access and its associated operating system, DBMS, and network platform (if any) used to access the DBMS.

23

Page 24: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsBasic ODBC Application Steps

24

– Step 1: Connect to the Data Source

– Step 2: Initialize the Application

– Step 3: Build and Execute an SQL Statement

– Step 4a: Fetch the Results

– Step 4b: Fetch the Row Count

– Step 5: Commit the Transaction

– Step 6: Disconnect from the Data Source

Page 25: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsAccess DB with ODBC

string MyConString = "DRIVER={MySQL ODBC 3.51 Driver};" +

"SERVER=localhost;" + "DATABASE=inv;" +

"UID=root;" + "PASSWORD=831025;" + "OPTION=3";

OdbcConnection MyConnection = new OdbcConnection(MyConString);

MyConnection.Open();

string query = "insert into test values( 'hello', 'lucas', 'liu')";

OdbcCommand cmd = new OdbcCommand(query, MyConnection);

try{

cmd.ExecuteNonQuery();

}

catch(Exception ex){

Console.WriteLine("record duplicate.");

}finally{

cmd.Dispose();

}

25

Page 26: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsAccess DB with ODBC

string tmp1 = null;string tmp2 = null;string tmp3 = null;query = "select * from test ";OdbcCommand cmd2 = new OdbcCommand(query, MyConnection);OdbcDataReader reader = cmd2.ExecuteReader();while (reader.Read()){

tmp1 = reader[0].ToString();tmp2 = reader[1].ToString();tmp3 = reader[2].ToString();

}

OdbcDataAdapter oda = new OdbcDataAdapter("select * from customer ", MyConnection);DataSet ds = new DataSet();

oda.Fill(ds, "employee");DataGridView dgv = new DataGridView();dgv.DataSource = ds.Tables["employee"];MyConnection.Close();

26

Page 27: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsPros & Cons of JDBC/ODBC reading

• JDBC/ODBC reading

– Advantages:

• Good performance, especially for accessing massive data

• Take advantage of various functions provided by DBMS

• Use stored procedures to implement complex logics

– Disadvantages:

• Coupling with DBMS

• Coupling with data structure

• Programming is complicate

– How to avoid the disadvantages?

27

Page 28: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsO/R Mapping

• Working with both Object-Oriented software and Relational Databases can be – cumbersome and time consuming.

• Development costs are significantly higher due to – a paradigm mismatch between how data is represented in objects versus

relational databases.

• The term Object/Relational Mapping refers to – the technique of mapping data from an object model representation to a

relational data model representation (and visa versa)

28

Page 29: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsHibernate – first class

• Event.class

package org.hibernate.tutorial.domain; import java.util.Date;public class Event {

private Long id;private String title;private Date date;

public Event() {}public Long getId() { return id; }private void setId(Long id) { this.id = id; }public Date getDate() { return date; }public void setDate(Date date) { this.date = date; }public String getTitle() { return title; }public void setTitle(String title) { this.title = title; }

}

29

Page 30: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsHibernate – mapping

• Event.hbm.xml

<hibernate-mapping package="org.hibernate.tutorial.domain">

<class name="Event" table="EVENTS">

<id name="id" column="EVENT_ID">

<generator class="native"/>

</id>

<property name="date" type="timestamp"

column="EVENT_DATE"/>

<property name="title"/>

</class>

</hibernate-mapping>

30

Event Class EVENTS Table

id EVENT_ID

date EVENT_DATE

title TITLE

Page 31: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsHibernate – configuration

• hibernate.cfg.xml

<hibernate-configuration>

<session-factory>

<!-- Database connection settings >

<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>

<property name="connection.url">jdbc:hsqldb:hsql://localhost</property>

<property name="connection.username">sa</property>

<property name="connection.password"></property>

<!-- JDBC connection pool (use the built-in) -->

<property name="connection.pool_size">1</property>

<!-- SQL dialect -->

<property name="dialect">org.hibernate.dialect.HSQLDialect</property>

<!-- Enable Hibernate's automatic session context management -->

<property name="current_session_context_class">thread</property>

31

Page 32: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsHibernate – configuration

<!-- Disable the second-level cache -->

<property name="cache.provider_class">

org.hibernate.cache.internal.NoCacheProvider

</property>

<!-- Echo all executed SQL to stdout -->

<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->

<property name="hbm2ddl.auto">update</property>

<mapping resource="org/hibernate/tutorial/domain/Event.hbm.xml"/>

</session-factory>

</hibernate-configuration>

32

Page 33: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsHelper class

public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() {

try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); }

catch (Throwable ex) { // Make sure you log the exception, as it might be

System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex);

} } public static SessionFactory getSessionFactory() {

return sessionFactory; }

}

33

Page 34: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsLoading and storing objects

public class EventManager { public static void main(String[] args) {

EventManager mgr = new EventManager();if (args[0].equals("store"))

mgr.createAndStoreEvent("My Event", new Date()); HibernateUtil.getSessionFactory().close();

} private void createAndStoreEvent(String title, Date theDate) {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();session.beginTransaction(); Event theEvent = new Event();theEvent.setTitle(title);theEvent.setDate(theDate); session.save(theEvent); session.getTransaction().commit();

} }

34

Page 35: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsLoading and storing objects

if (args[0].equals("store")) mgr.createAndStoreEvent("My Event", new Date());

else if (args[0].equals("list")) { List events = mgr.listEvents(); for (int i = 0; i < events.size(); i++) {

Event theEvent = (Event) events.get(i); System.out.println( "Event: " + theEvent.getTitle() + " Time: "

+ theEvent.getDate() ); }

private List listEvents() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); List result = session.createQuery("from Event").list(); session.getTransaction().commit(); return result;

}

35

Page 36: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsPros and Cons of ORM

• ORM

– Advantages:

• Independent of DBMS

• Independent of data structure

• OOP

– Disadvantages:

• Impact on performance

• Can NOT utilize the extra functions in addition to standard functions

defined in specification.

• Mapping between O and R maybe complex.

• Can NOT invoke stored procedures.

36

Page 37: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsWhich one is better?

• JDBC/ODBC reading or ORM?

– Requirements Driven

– Requirement 1:

• To list all records about courses selection of a certain semester.

• It could be a big records set with over 150,000 records selected from

millions of records

– Requirement 2:

• To get the average age of all undergraduate students

– Requirement3:

• To ensure that the database could be moved from ORACLE to DB2

37

Page 38: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsMake a decision

• How to manipulate data from client ends?

– Online:

• Keep holding database connection

• Transfer data by references

• Real-time status of data

• Do harmful concurrency

– Offline:

• Release database connection after the data to be transferred

• Transfer data by values

• Encourage concurrency

• Could occur confliction between transactions

38

Page 39: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsMake a decision

• Shall we use stored procedures?

– Advantages:

• Processes are close to data

• Less number of invocations between clients and server

• Invariant can protect data from unauthenticated accesses

– Disadvantages:

• Poor portability

• Poor reusability

• Challenge for security of business logics

39

Page 40: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsIntroducing XML

• "The Extensible Markup Language (XML) has replaced Java, Design Patterns, and Object Technology as the software industry's solution to world hunger." – Half-jokingly stated in the preface of the book Essential XML by Don Box

et al. (Addison-Wesley Professional 2000)

40

Page 41: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsIntroducing XML

• A property file contains a set of name/value pairs, such asfontname=Times Roman fontsize=12 windowsize=400 200 color=0 50 100

• Consider the fontname/fontsize entries in the example. It would be more object oriented to have a single entry:font=Times Roman 12But then parsing the font description gets ugly

• Property files have a single flat hierarchytitle.fontname=Helvetica title.fontsize=36 body.fontname=Times Roman body.fontsize=12

41

Page 42: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsIntroducing XML

• Another shortcoming of the property file format is caused by the requirement that keys be unique.

menu.item.1=Times Roman

menu.item.2=Helvetica

menu.item.3=Goudy Old Style

• The XML format solves these problems – because it can express hierarchical structures

– and thus is more flexible than the flat table structure of a property file.

42

Page 43: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsIntroducing XML

<configuration>

<title>

<font>

<name>Helvetica</name>

<size>36</size>

</font>

</title>

<body>

<font>

<name>Times Roman</name>

<size>12</size>

</font>

</body>

43

<window>

<width>400</width>

<height>200</height>

</window>

<color>

<red>0</red>

<green>50</green>

<blue>100</blue>

</color>

<menu>

<item>Times Roman</item>

<item>Helvetica</item>

<item>Goudy Old Style</item>

</menu>

</configuration>

Page 44: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsIntroducing XML

• Even though XML and HTML have common roots, there are important differences between the two.– Unlike HTML, XML is case sensitive.

• For example, <H1> and <h1> are different XML tags

– In XML, you can never omit an end tag. In HTML, you can omit end tags if it is clear from the context where a paragraph or list item ends.

• such as </p> or </li> tags

– In XML, elements that have a single tag without a matching end tag must end in a /, as in <img src=“coffeecup.png”/>.

• That way, the parser knows not to look for a </img> tag

44

Page 45: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsIntroducing XML

• Even though XML and HTML have common roots, there are important differences between the two.– In XML, attribute values must be enclosed in quotation marks. In HTML,

quotation marks are optional.

• For example,<applet code=“MyApplet.class” width=300 height=300> is legal HTML but not legal XML.

• In XML, you have to use quotation marks: width=“300”

– In HTML, you can have attribute names without values, such as

• <input type=“radio” name=“language” value=“Java” checked>

– In XML, all attributes must have values, such as

• checked=“true” or checked=“checked”

45

Page 46: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsThe Structure of an XML Document

• An XML document should start with a header such as

<?xml version =“1.0”?>

or

<?xml version =“1.0” encoding=“UTF-8”?>

Strictly speaking, a header is optional, but it is highly recommended.

• The header can be followed by a document type definition (DTD), such as

<!DOCTYPE web-app PUBLIC

“-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

• DTDs are an important mechanism to ensure the correctness of a document, but they are not required.

46

Page 47: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsThe Structure of an XML Document

• Finally, the body of the XML document contains the root element, which can contain other elements.

• For example<?xml version="1.0"?> <!DOCTYPE configuration . . .> <configuration>

<title> <font>

<name>Helvetica</name> <size>36</size>

</font> </title>. . .

</configuration>• An element can contain child elements, text, or both.

47

Page 48: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsThe Structure of an XML Document

• XML elements can contain attributes, such as

<size unit="pt">36</size>

• There is some disagreement among XML designers about when to use elements and when to use attributes.

• For example, it would seem easier to describe a font as

<font name="Helvetica" size="36"/>

than

<font>

<name>Helvetica</name>

<size>36</size>

</font>

48

Page 49: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsThe Structure of an XML Document

• However, attributes are much less flexible.

• Suppose you want to add units to the size value. If you use attributes, then you must add the unit to the attribute value:

<font name="Helvetica" size="36 pt"/>

• Adding an attribute to the size element is much cleaner:

<font>

<name>Helvetica</name>

<size unit="pt">36</size>

</font>

49

Page 50: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document

• A parser is a program that – reads a file,

– confirms that the file has the correct format,

– breaks it up into the constituent elements,

– and lets a programmer access those elements.

• The Java library supplies two kinds of XML parsers:– Tree parsers such as the Document Object Model (DOM) parser that

read an XML document into a tree structure.

– Streaming parsers such as the Simple API for XML (SAX) parser that generate events as they read an XML document.

50

Page 51: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

• To read an XML document, you need a DocumentBuilder object, which you get from a DocumentBuilderFactory, like this:DocumentBuilderFactory factory =

DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();

• You can now read a document from a file:File f = . . .Document doc = builder.parse(f);

• Alternatively, you can use a URL:URL u = . . .Document doc = builder.parse(u);

• You can even specify an arbitrary input stream:InputStream in = . . .Document doc = builder.parse(in);

51

Page 52: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

• The Document object is an in-memory representation of the tree structure of the XML document.

52

Page 53: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

• You start analyzing the contents of a document by calling the getDocumentElement method. It returns the root element.

Element root = doc.getDocumentElement();

• For example, if you are processing a document

<?xml version="1.0"?>

<font>

. . .

</font>

then calling getDocumentElement returns the font element.

• The getTagName method returns the tag name of an element. – In the preceding example, root.getTagName() returns the string "font".

53

Page 54: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

• To get the element's children, use the getChildNodes method. – That method returns a collection of type NodeList.

– The item method gets the item with a given index,

– and the getLength method gives the total count of the items.

• Therefore, you can enumerate all children like this:

NodeList children = root.getChildNodes();

for (int i = 0; i < children.getLength(); i++)

{

Node child = children.item(i);

. . .

}

54

Page 55: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

• Be careful when analyzing the children.

• Suppose, for example, that you are processing the document

<font>

<name>Helvetica</name>

<size>36</size>

</font>

• You would expect the font element to have two children, but the parser reports five:– The whitespace between <font> and <name>

– The name element

– The whitespace between </name> and <size>

– The size element

– The whitespace between </size> and </font>

55

Page 56: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

56

Page 57: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

• If you expect only subelements, then you can ignore the whitespace:

for (int i = 0; i < children.getLength(); i++)

{

Node child = children.item(i);

if (child instanceof Element)

{

Element childElement = (Element) child;

. . .

}

}

Now you look at only two elements, with tag names name and size.

57

Page 58: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - DOM

• To enumerate the attributes of a node, call the getAttributes method. – It returns a NamedNodeMap object that contains Node objects describing

the attributes.

NamedNodeMap attributes = element.getAttributes();for (int i = 0; i < attributes.getLength(); i++){

Node attribute = attributes.item(i);String name = attribute.getNodeName();String value = attribute.getNodeValue();. . .

}

• Alternatively, if you know the name of an attribute, you can retrieve the corresponding value directly:String unit = element.getAttribute("unit");

58

Page 59: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - SAX

• The SAX parser reports events as it parses the components of the XML input, but it does not store the document in any way– it is up to the event handlers whether they want to build a data structure.

– In fact, the DOM parser is built on top of the SAX parser. It builds the DOM tree as it receives the parser events.

• The ContentHandler interface defines several callback methods that the parser executes as it parses the document. Here are the most important ones:– startElement and endElement are called each time a start tag or end tag

is encountered.

– characters is called whenever character data are encountered.

– startDocument and endDocument are called once each, at the start and the end of the document.

59

Page 60: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - SAX

• For example, when parsing the fragment

<font>

<name>Helvetica</name>

<size units="pt">36</size>

</font>

• The parser makes the following callbacks:– startElement, element name: font

– startElement, element name: name

– characters, content: Helvetica

– endElement, element name: name

– startElement, element name: size, attributes: units="pt"

– characters, content: 36

– endElement, element name: size

– endElement, element name: font

60

Page 61: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - SAX

• Here is how you get a SAX parser:SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();

• You can now process a document:parser.parse(source, handler);

• Here, – source can be a file, URL string, or input stream. – handler belongs to a subclass of DefaultHandler.

• The DefaultHandler class defines do-nothing methods for the four interfaces:– ContentHandler– DTDHandler– EntityResolver– ErrorHandler

61

Page 62: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsParsing an XML Document - SAX

DefaultHandler handler = newDefaultHandler(){

public void startElement(String namespaceURI, String lname, String qname, Attributes attrs)

throws SAXException{

if (lname.equalsIgnoreCase("a") && attrs != null){

for (int i = 0; i < attrs.getLength(); i++){

String aname = attrs.getLocalName(i);if (aname.equalsIgnoreCase("href"))

System.out.println(attrs.getValue(i));}

}}

};

62

Page 63: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsValidating XML Documents

• You also need to check whether the document contains the nodes that you expect.

• To specify the document structure– you can supply a DTD or an XML Schema definition.

– A DTD or schema contains rules that explain how a document should be formed, by specifying the legal child elements and attributes for each element.

63

Page 64: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsValidating XML Documents

• For example, a DTD might contain a rule:

<!ELEMENT font (name,size)>

This rule expresses that a font element must always have two children, which are name and size elements.

• The XML Schema language expresses the same constraint as

<xsd:element name="font">

<xsd:sequence>

<xsd:element name="name" type="xsd:string"/>

<xsd:element name="size" type="xsd:int"/>

</xsd:sequence>

</xsd:element>

64

Page 65: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsDocument Type Definitions

65

<!ELEMENT font (name,size)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT size (#PCDATA)>

<!ELEMENT chapter (intro,(heading,(para|image|table|note)+)+)>

<!ELEMENT para (#PCDATA|em|strong|code)*>

<!ATTLIST font style (plain|bold|italic|bold-italic) "plain">

<!ATTLIST size unit CDATA #IMPLIED>

Page 66: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsXML Schema

• To reference a Schema file in a document, add attributes to the root element, for example:<?xml version="1.0"?><configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="config.xsd">. . .</configuration>

• For example, here is an enumerated type:<xsd:simpleType name="StyleType">

<xsd:restriction base="xsd:string"><xsd:enumeration value="PLAIN" /><xsd:enumeration value="BOLD" /><xsd:enumeration value="ITALIC" /><xsd:enumeration value="BOLD_ITALIC" />

</xsd:restriction></xsd:simpleType>

66

Page 67: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsLocating Information with XPath

• The XPath language makes it simple to access tree nodes.

• For example, suppose you have this XML document:

<configuration>

. . .

<database>

<username>dbuser</username>

<password>secret</password>

. . .

</database>

</configuration>

• You can get the database user name by evaluating the XPathexpression

/configuration/database/username

67

Page 68: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsLocating Information with XPath

• That's a lot simpler than the plain DOM approach:– Get the document node.

– Enumerate its children.

– Locate the database element.

– Get its first child, the username element.

– Get its first child, a Text node.

– Get its data.

– /gridbag/row

– /gridbag/row[1]

– /gridbag/row[1]/cell[1]/@anchor

– /gridbag/row/cell/@anchor

– count(/gridbag/row)

68

Page 69: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsLocating Information with XPath

• Java SE 5.0 added an API to evaluate XPath expressions. You first create an XPath object from an XPathFactory:XPathFactory xpfactory = XPathFactory.newInstance();path = xpfactory.newXPath();

• You then call the evaluate method to evaluate XPath expressions:String username = path.evaluate("/configuration/database/username", doc);NodeList nodes = (NodeList) path.evaluate("/gridbag/row", doc, XPathConstants.NODESET);Node node = (Node) path.evaluate("/gridbag/row[1]", doc, XPathConstants.NODE);int count = ((Number) path.evaluate("count(/gridbag/row)", doc, XPathConstants.NUM- BER)).intValue();

result = path.evaluate(expression, node);

69

Page 70: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsUsing Namespace

• A namespace is identified by a Uniform Resource Identifier (URI), such as

http://www.w3.org/2001/XMLSchema

uuid:1c759aed-b748-475c-ab68-10679700c4f2

urn:com:books-r-us

• Why use HTTP URLs for namespace identifiers? It is easy to ensure that they are unique.

70

Page 71: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsUsing Namespace

• To specify the long names of namespace:

<element xmlns="namespaceURI">

children

</element>

• A child can provide its own namespace, for example:

<element xmlns="namespaceURI1">

<child xmlns="namespaceURI2">

grandchildren

</child>

more children

</element>

71

Page 72: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsGenerating XML Documents

• A better approach is – to build up a DOM tree with the contents of the document

– and then write out the tree contents.

Document doc = builder.newDocument();

• Use the createElement method of the Document class to construct the elements of your document.

Element rootElement = doc.createElement(rootName);

Element childElement = doc.createElement(childName);

• Use the createTextNode method to construct text nodes:

Text textNode = doc.createTextNode(textContents);

72

Page 73: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsGenerating XML Documents

• Add the root element to the document, and add the child nodes to their parents:

doc.appendChild(rootElement);

rootElement.appendChild(childElement);

childElement.appendChild(textNode);

• As you build up the DOM tree, you may also need to set element attributes. Simply call the setAttribute method of the Element class:

rootElement.setAttribute(name, value);

73

Page 74: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsGenerating XML Documents

• Somewhat curiously, the DOM API currently has no support for writing a DOM tree to an output stream.

• To overcome this limitation, we use the Extensible Stylesheet Language Transformations (XSLT) API.

Transformer t = TransformerFactory.newInstance().newTransformer();

t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, systemIdentifier);

t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, publicIdentifier);

t.setOutputProperty(OutputKeys.INDENT, "yes");

t.setOutputProperty(OutputKeys.METHOD, "xml");

t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

t.transform(new DOMSource(doc),

new StreamResult(new FileOutputStream(file)));

74

Page 75: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsXML Transformations

• The XSL Transformations (XSLT) mechanism allows you to – specify rules for transforming XML documents into other formats,

– such as plain text, XHTML, or any other XML format.

75

Page 76: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsXML Transformations

• Here is a typical example. <staff>

<employee><name>Carl Cracker</name><salary>75000</salary><hiredate year="1987" month="12" day="15"/>

</employee><employee>

<name>Harry Hacker</name><salary>50000</salary><hiredate year="1989" month="10" day="1"/>

</employee><employee>

<name>Tony Tester</name><salary>40000</salary><hiredate year="1990" month="3" day="15"/>

</employee></staff>

76

Page 77: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsXML Transformations

• The desired output is an HTML table:

<table border="1">

<tr>

<td>Carl Cracker</td><td>$75000.0</td><td>1987-12-15</td>

</tr>

<tr>

<td>Harry Hacker</td><td>$50000.0</td><td>1989-10-1</td>

</tr>

<tr>

<td>Tony Tester</td><td>$40000.0</td><td>1990-3-15</td>

</tr>

</table>

77

Page 78: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsXML Transformations

• A style sheet with transformation templates has this form:<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"><xsl:output method="html"/>template1template2. . .

</xsl:stylesheet>

• Here is a typical template for employee nodes:<xsl:template match="/staff/employee">

<tr><xsl:apply-templates/></tr></xsl:template>

78

Page 79: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsXML Transformations

• Here is a template for name nodes:

<xsl:template match="/staff/employee/name">

<td><xsl:apply-templates/></td>

</xsl:template>

• Here is an example for hiredate nodes. :

<xsl:template match="/staff/employee/hiredate">

<td><xsl:value-of select="@year"/>-<xsl:value-of

select="@month"/>-<xsl:value-of select="@day"/></td>

</xsl:template>

79

Page 80: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsXML Transformations

• It is extremely simple to generate XSL transformations in the Java platform.

File styleSheet = new File(filename);

StreamSource styleSource = new StreamSource(styleSheet);

Transformer t = TransformerFactory.newInstance().

newTransformer(styleSource);

t.transform(source, result);

80

Page 81: Software Architecture 3 Data Access

REliable, INtelligent & Scalable SystemsFrom

• Prentice.Hall.PTR: Core Java 2 Volume II Advanced Features,8th.Edition. Apri.2008

• JDBC™ 3.0 Specification Final Release, Jon Ellis & Linda Ho with Maydene Fisher

• JNDI ™ 1.2.1 Javadoc, http://java.sun.com/products/jndi/1.2/javadoc/

• Introduction to ODBC, http://msdn.microsoft.com/en-us/library/ms715408(v=vs.85).aspx

• HIBERNATE - Relational Persistence for Idiomatic Java, http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#preface

• http://www.cnblogs.com/xiaohaikong/archive/2009/08/13/1544478.html

81

Page 82: Software Architecture 3 Data Access

Thank You!