E N D
Struts Petstore Struts University Series
Abstract Struts has always shipped with a simple example application. But for many teams, MailReader is a bit too simple. Struts Petstore is a full-featured, production-grade Struts application inspired by the infamous Java Pet Store. Struts Petstore uses a professional architecture that hooks up to Apache iBATIS for data access. Let's have a look ...
A little background • Sun creates J2EE Pet Store • Demonstrates patterns • Microsoft creates .NET Pet Shop • Demonstrates performance • Clinton Begin creates JPetStore • Demonstrates iBATIS
iBATIS and Struts • iBATIS • Data mapping framework for SQL • Compares to Hibernate and OJB • Struts • Web application framework • Compares to WebWork and Tapestry • Clinton Begin • Inventor of iBATIS and author of JPetStore
The Purpose of JPetStore • Clinton Begin wrote JPetstore to show • Java is easy • Java is low cost • Java is highly productive • Java enables choice • Java enables change
The Purpose of JPetStore • Clinton Begin wrote JPetstore to show • Java is easy • Java is low cost • Java is highly productive • Java enables choice • Java enables change • iBATIS is cool
Advantages without Tradeoffs • JPetStore uses superior design and architecture • Clearly defined application layers • Uses known best practices and patterns • Avoids known worst practices • No stored procedures • No SQL embedded in Java code • No HTML in the database • No generated code
Presentation • Model View Controller Pattern • Well know and proven (GOF) • Simple and maintainable • Apache Struts • Freely available, open source • Based on JavaBeans
Domain • JavaBeans • Components with properties and behavior • Plug into presentation and persistence layers • Compatible with many frameworks • GUI tools available (IDEs, et cetera) • Logic Classes • None/Verb separation • More maintainable than prior versions
Persistence • Data Access Objects • “Pluggable” persistance components • Proven abstract factory pattern (GoF) • Improves maintainability and flexibility • SQL Maps • Reduces/eliminates repetive JDBC code • Improves performance with caching • Portable across many databases • Based on JavaBeans
Link to a category query JavaServer Page: <html:link page="/shop/viewCategory.shtml?categoryId=DOGS"> Struts Config: <action path="/shop/viewCategory" type="com.ibatis.struts.BeanAction" name="catalogBean" scope="session" validate="false" > <forward name="success" path="/catalog/Category.jsp"/> </action>
CatalogBean public String viewCategory() { if (categoryId != null) { productList = catalogService.getProductListByCategory(categoryId); category = catalogService.getCategory(categoryId); } return "success"; }
CatalogService public PaginatedList getProductListByCategory(String categoryId) { return queryForPaginatedList("getProductListByCategory", categoryId, PAGE_SIZE); } public Category getCategory(String categoryId) { return (Category) queryForObject("getCategory", categoryId); }
SqlMaps <select id="getCategoryList" resultMap="categoryResult"> select CATID, NAME, DESCN from CATEGORY </select> <select id="getCategory" resultMap="categoryResult" parameterClass="string"> select CATID, NAME, DESCN from CATEGORY where CATID = #value# </select>
ResultMap <resultMap id="categoryResult" class="category"> <result property="categoryId" column="CATID"/> <result property="name" column="NAME"/> <result property="description" column="DESCN"/> </resultMap>
Cache Model <cacheModel id="oneDayCategory" type="LRU"> <flushInterval hours="24"/> </cacheModel>
Cache Model <cacheModel id="oneDayCategory" type="LRU"> <flushInterval hours="24"/> <flushOnExecute statement="insertCategory"/> </cacheModel>
Dynamic SQL <select id="getCategoryList" resultMap="categoryResult"> select CATID, NAME, DESCN from CATEGORY </select> <select id="getCategory" resultMap="categoryResult" parameterClass="string"> select CATID, NAME, DESCN from CATEGORY where CATID = #value# </select>
Dynamic SQL <select id="getCategory" resultMap="categoryResult" parameterClass="string"> select CATID, NAME, DESCN from CATEGORY <dynamic prepend="WHERE"> <isParameterPresent> where CATID = #value# </isParameterPresent> </dynamic> </select>