28
1 Accessing Database in Struts Application

Struts Database

Embed Size (px)

Citation preview

Page 1: Struts Database

1

AccessingDatabase in

Struts Application

Page 2: Struts Database

2

Sang Shin

[email protected]

Java™ Technology EvangelistSun Microsystems, Inc.

Page 3: Struts Database

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

Page 4: Struts Database

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

Page 5: Struts Database

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)

Page 6: Struts Database

6

Accessing Data Source froman Action

(Not Recommended)

Page 7: Struts Database

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

Page 8: Struts Database

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

Page 9: Struts Database

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>

Page 10: Struts Database

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); } }}

Page 11: Struts Database

11

Displaying RelationalDatabase using

RowSetDynaClass

Page 12: Struts Database

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

Page 13: Struts Database

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");}

Page 14: Struts Database

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.

Page 15: Struts Database

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>

Page 16: Struts Database

16

Example: Result

Page 17: Struts Database

17

Mapping SQL Datato Java Objects through

iBATIS SQL maps

Page 18: Struts Database

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

Page 19: Struts Database

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

Page 20: Struts Database

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

Page 21: Struts Database

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>

Page 22: Struts Database

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

Page 23: Struts Database

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; }

Page 24: Struts Database

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); }}

Page 25: Struts Database

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

Page 26: Struts Database

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>

Page 27: Struts Database

27

Example: Result

Page 28: Struts Database

28

Passion!