Вы находитесь на странице: 1из 28

Accessing

Database in
Struts Application

1
Sang Shin
sang.shin@sun.com
www.javapassion.com
Java™ Technology Evangelist
Sun Microsystems, Inc.
2
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

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

4
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)

5
Accessing Data Source
froman Action
(Not Recommended)

6
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
7
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

8
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>

9
Example: Action Class
public 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);
}
} 10
}
Displaying Relational
Database using
RowSetDynaClass

11
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

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

14
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> 15
Example: Result

16
Mapping SQL Data
to Java Objects through
iBATIS SQL maps

17
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
18
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

19
iBATIS: sqlMapConfig.properties
● IBATIS reads database connection settings
from this file
● Example for MySQL
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/test
username=sang
password=sangpassword

20
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>

21
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

22
Example: User.java
package 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; 23
Example: MyUserDao.java
public 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);
}
}
24
Example: ViewMyUsersAction.java
public 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

25
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> 26
Example: Result

27
Passion!

28

Вам также может понравиться