View
695
Download
1
Category
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