Struts Database

Preview:

Citation preview

1

AccessingDatabase in

Struts Application

2

Sang Shin

sang.shin@sun.comwww.javapassion.com

Java™ Technology EvangelistSun Microsystems, Inc.

3

Disclaimer & Acknowledgments● Even though Sang Shin is a full-time employees of Sun

Microsystems, the contents here are created as their own personal endeavor and thus does not reflect any official stance of Sun Microsystems.

● Sun Microsystems is not responsible for any inaccuracies in the contents.

● Acknowledgments: – Some slides are created from the contents of “Jakarta Struts Cookbook”

written by Bill Siggelkow and published by O'Reilly

4

Revision History● 09/18/2005: version 1: created by Sang Shin ● Things to do– Contents on performance tuning, debugging still

need to be added

5

Agenda● Accessing Data Sources from an Action (ch

10.1)● Displaying relational data (ch 10.2)● Mapping SQL data to Java objects through

iBATIS SQL maps (ch 10.3)● Integrating Struts with Hibernate (ch 10.4)

6

Accessing Data Source froman Action

(Not Recommended)

7

Caution First● Database access logic belong to business

logic (Model) not inside Action– Action class should be just a thin layer to Model– All the database access code should be encapsulated

behind the business API classes (using DAO pattern)– Action shouldn't know what persistent layer you are using

(or even if there is a persistence layer)– Ideally action passes a key or search string to business

API and gets back a bean or collection of beans– Reuse of the business logic in other environment is

possible– Unit testing the business logic outside Struts possible

8

However, Struts provides DataSource manager● Struts DataSource manager is configured as

an element in struts-config.xml● Can be used to deploy any connection pool

that implements the javax.sql.DataSource interface

9

Example in struts-config.xml<data-sources> <!-- configuration for commons BasicDataSource --> <data-source type="org.apache.commons.dbcp.BasicDataSource"> <set-property property="driverClassName" value="org.postgresql.Driver" /> <set-property property="url" value="jdbc:postgresql://localhost/mydatabase" /> <set-property property="username" value="me" /> <set-property property="password" value="test" /> <set-property property="maxActive" value="10" /> <set-property property="maxWait" value="5000" /> <set-property property="defaultAutoCommit" value="false" /> <set-property property="defaultReadOnly" value="false" /> <set-property property="validationQuery" value="SELECT COUNT(*) FROM market" /> </data-source></data-sources>

10

Example: Action Classpublic ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{ javax.sql.DataSource dataSource; java.sql.Connection myConnection; try { dataSource = getDataSource(request); myConnection = dataSource.getConnection(); // do what you wish with myConnection } catch (SQLException sqle) { getServlet().log("Connection.process", sqle); } finally { //enclose this in a finally block to make sure the connection is closed try { myConnection.close(); } catch (SQLException e) { getServlet().log("Connection.close", e); } }}

11

Displaying RelationalDatabase using

RowSetDynaClass

12

RowSetDynaClass● From Apache Commons– org.apach.commons.beanutils.RowSetDynaClass

● Used when you want to display data from a relational database, but your don't know the structure of the data

● Maps a JDBC result set – rows and columns retrieved from a relational database – to a JavaBean which can be accessed on a JSP page

13

Example: UserDao.java public class UserDao {

public RowSetDynaClass getUsersRowSet() throws Exception { Connection conn = null; Statement stmt = null; ResultSet rs = null; RowSetDynaClass rowSet = null; try { conn = getConnection(); stmt = conn.createStatement(); rs = stmt.executeQuery("select * from users"); rowSet = new RowSetDynaClass(rs); } finally { if (conn != null) conn.close(); } return rowSet;}

private Connection getConnection() throws Exception { Class.forName("com.mysql.jdbc.Driver"); return DriverManager.getConnection("jdbc:mysql://localhost/test");}

14

Example: ViewUserAction.java public class ViewUsersAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { UserDao dao = new UserDao(); RowSetDynaClass rowSet = dao.getUsersRowSet(); request.setAttribute("rowSet", rowSet); return mapping.findForward("success"); }}

● Notice that the Action class is exposed to database access logic – this is not as clean it can be. If you want to use different persistence technique later on, you have to change Action class.

15

Example: ViewUser.jsp <body> <h3>Using RowSetDynaClass</h3> <bean:define id="cols" name="rowSet" property="dynaProperties"/> <table border="2"> <tr> <logic:iterate id="col" name="cols"> <th><bean:write name="col" property="name"/></th> </logic:iterate> </tr> <logic:iterate id="row" name="rowSet" property="rows" > <tr> <logic:iterate id="col" name="cols"> <td> <bean:write name="row" property="<%=((DynaProperty)col).getName()%>"/> </td> </logic:iterate> </tr> </logic:iterate> </table></body></html>

16

Example: Result

17

Mapping SQL Datato Java Objects through

iBATIS SQL maps

18

What is iBATIS?● Provides a framework for mapping SQL

statements and results to Java objects– Excellent middle-ground solution between vanilla

JDBC and full-blown O/R mapper● Supports– Data mapping– Caching– Transactions

● iBATIS DAO framework● http://www.ibatis.com

19

What is SQL Map?● Specify how Java objects map to the inputs

and outputs of an SQL statement– The inputs take the form of parameters bound to an

SQL where clause● Lets y ou map object properties to statement parameters

– For outputs, Java objects map to the result set● sqlMapConfig.xml file

20

iBATIS: sqlMapConfig.properties● IBATIS reads database connection settings

from this file● Example for MySQL

driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost/testusername=sangpassword=sangpassword

21

Example: sqlMapConfig.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com/DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd"><sqlMapConfig> <properties resource="sqlMapConfig.properties"/> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="${driver}"/> <property name="JDBC.ConnectionURL" value="${url}"/> <property name="JDBC.Username" value="${username}"/> <property name="JDBC.Password" value="${password}"/> </dataSource> </transactionManager> <sqlMap resource="UserSqlMap.xml"/></sqlMapConfig>

22

Example: UserSqlMap.xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE sqlMap PUBLIC "-//iBATIS.com/DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"><sqlMap namespace="UserSqlMap"> <select id="getAllUsers" resultClass="com.oreilly.strutsckbk.ch10.User"> SELECT user_name as username, first_name as firstName, last_name as lastName FROM users </select> </sqlMap>

● The <select> element defines how a SELECT maps to a Java class

● When the query is executed, iBATIS will return a collection of Java objects of the type specified by the resultClass attribute

23

Example: User.javapackage com.oreilly.strutsckbk.ch10;

public class User { public String getUsername() { return username; } public void setUsername(String username) { this.username = username; }

public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; }

24

Example: MyUserDao.javapublic class MyUserDao {

private static final SqlMapClient sqlMapClient; static { try { Reader reader =

Resources.getResourceAsReader("sqlMapConfig.xml"); sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Unable to create iBATIS sql map

client.", e); } }

public List getAllUsers() throws SQLException { return sqlMapClient.queryForList("getAllUsers", null); }}

25

Example: ViewMyUsersAction.javapublic class ViewMyUsersAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { MyUserDao dao = new MyUserDao(); List users = dao.getAllUsers(); request.setAttribute("users", users); return mapping.findForward("success"); }}

● Notice the usage of business service class, MyUserDao● Database access logic is hidden from Action class● Even better approach would have been the usage of an

interface rather than a class

26

Example: view_my_users.jsp<body> <h3>Using iBATIS</h3> <table border="2"> <tr> <th>Username</th> <th>First Name</th> <th>Last Name</th> </tr> <logic:iterate id="user" name="users"> <tr> <td> <bean:write name="user" property="username"/> </td> <td> <bean:write name="user" property="firstName"/> </td> <td> <bean:write name="user" property="lastName"/> </td> </tr> </logic:iterate> </table>

27

Example: Result

28

Passion!

Recommended