??xml version="1.0" encoding="utf-8" standalone="yes"?>
源程序下?/a>
至于Hibernate, Structs, MySQL的具体用法我׃说了,你可以看源程序来查看详细内容.我们来看看分应用的相关内容.
架构上和Spring JPetStore没多区? 只是没用Spring框架所以Structs中的UserdisplayAction中必new出各个对象ƈ完成它们之间的关? q就是Spring IOC可自动完成的功能. 它也是三?表现?Structs), 业务?POJO), 数据?Hibernate讉KMySQL). 同样业务层通过DAO接口(UserDAO)来访问数据库, 讉K数据库的通过Hibernate(在UserDAOImpl中实?. q一ơ分要在业务层中来实现, 业务层同样向表现层提供一个Facada(门面, UserManager接口), 来访问业? 在UserManagerImpl中通过调用UserDAO来访问数? 调用POJO来实现分功? 看以下关键代?
先看POJO的分布类?
Page.java
package org.flyware.util.page;
public class Page {
private boolean hasPrePage;
private boolean hasNextPage;
private int everyPage;
private int totalPage;
private int currentPage;
private int beginIndex;
public Page(){
}
public Page(int everyPage){
this.everyPage = everyPage;
}
/** The whole constructor */
public Page(boolean hasPrePage, boolean hasNextPage,
int everyPage, int totalPage,
int currentPage, int beginIndex) {
this.hasPrePage = hasPrePage;
this.hasNextPage = hasNextPage;
this.everyPage = everyPage;
this.totalPage = totalPage;
this.currentPage = currentPage;
this.beginIndex = beginIndex;
}
......
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
}
PageUtil.java(用来构造Page实例 相当于page工厂)
package org.flyware.util.page;
public class PageUtil {
private static final Log logger = LogFactory.getLog(PageUtil.class);
public static Page createPage(Page page, int totalRecords){
return createPage(page.getEveryPage(), page.getCurrentPage(), totalRecords);
}
public static Page createPage(int everyPage, int currentPage, int totalRecords){
everyPage = getEveryPage(everyPage);
currentPage = getCurrentPage(currentPage);
int beginIndex = getBeginIndex(everyPage, currentPage);
int totalPage = getTotalPage(everyPage, totalRecords);
boolean hasNextPage = hasNextPage(currentPage, totalPage);
boolean hasPrePage = hasPrePage(currentPage);
return new Page(hasPrePage, hasNextPage,
everyPage, totalPage,
currentPage, beginIndex);
}
private static int getEveryPage(int everyPage){
return everyPage == 0 ? 10 : everyPage;
}
private static int getCurrentPage(int currentPage){
return currentPage == 0 ? 1 : currentPage;
}
private static int getBeginIndex(int everyPage, int currentPage){
return (currentPage - 1) * everyPage;
}
private static int getTotalPage(int everyPage, int totalRecords){
int totalPage = 0;
if(totalRecords % everyPage == 0)
totalPage = totalRecords / everyPage;
else
totalPage = totalRecords / everyPage + 1 ;
return totalPage;
}
private static boolean hasPrePage(int currentPage){
return currentPage == 1 ? false : true;
}
private static boolean hasNextPage(int currentPage, int totalPage){
return currentPage == totalPage || totalPage == 0 ? false : true;
}
}
业务实现c?UserManaerImpl.java
package com.linan.service.impl;
public class UserManagerImpl implements UserManager {
private UserDAO userDAO;
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
//提供业务Ҏ
public Result listUser(Page page) throws HibernateException,
ObjectNotFoundException {
int totalRecords = userDAO.getUserCount();
if(totalRecords == 0)
throw new ObjectNotFoundException("userNotExist", null);
page = PageUtil.createPage(page, totalRecords);
List users = userDAO.getUserByPage(page);
return new Result(page, users);
}
}
DAO数据讉K实现c?UserDAOImpl.java
package com.linan.dao.impl;
public class UserDAOImpl implements UserDAO {
...........
public List getUserByPage(Page page) throws HibernateException {
String querySentence = "FROM user in class com.linan.bo.Userlist";
Query query = getSession().createQuery(querySentence);
//实现分页功能
query.setFirstResult(page.getBeginIndex())
.setMaxResults(page.getEveryPage());
return query.list();
}
}
表现层Structs中的Action UserdisplayAction.java
package com.linan.struts.action;
public class UserdisplayAction extends Action {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
Page page=new Page();
UserManagerImpl userManager=new UserManagerImpl();
UserDAOImpl userDAO=new UserDAOImpl();
userManager.setUserDAO(userDAO);
//掉用业务代理完成分页
Result result=userManager.listUser(page);
List list=result.getContent();
HttpSession session=request.getSession();
session.setAttribute("list",list);
return mapping.findForward("displayGo");
}
}
先从数据讉K层说起吧, 他用iBATIS框架来访问数据库,?.\spring-jpetstore\samples\jpetstore\db目录下有它的各种数据库的schema有hsql, mysql, oracle, postges你用拿一U数据库是通过..\spring-jpetstore\samples\jpetstore\war\WEB-INF下的jdbc.properties来配|的.默认的是hsql数据?
# Properties file with JDBC-related settings.
# Applied by PropertyPlaceholderConfigurer from "dataAccessContext-local.xml".
# Targeted at system administrators, to avoid touching the context XML files.
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost:9002
jdbc.username=sa
jdbc.password=
要改为用mysql只要改ؓ:
#jdbc.driverClassName=org.hsqldb.jdbcDriver
#jdbc.url=jdbc:hsqldb:hsql://localhost:9002
#jdbc.username=sa
#jdbc.password=
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/jpetstore
jdbc.username=root
jdbc.password=
卛_.业务层能q?..jpetstore.dao包下的接口来讉K....jpetstore.dao.ibatis包从而通过iBATIS框架讉K数据库中的数据的部䆾代码如下:
package org.springframework.samples.jpetstore.dao;
public interface AccountDao {
Account getAccount(String username, String password) throws DataAccessException;
...........
}
package org.springframework.samples.jpetstore.dao.ibatis;
public class SqlMapAccountDao extends SqlMapDaoSupport implements AccountDao {
public Account getAccount(String username, String password) throws DataAccessException {
Account account = new Account();
account.setUsername(username);
account.setPassword(password);
return (Account) getSqlMapTemplate().executeQueryForObject("getAccountByUsernameAndPassword", account);
}
..............
}
Account.xml
<mapped-statement name="getAccountByUsernameAndPassword" result-map="result">
select
SIGNON.USERNAME as USERID,
ACCOUNT.EMAIL,
ACCOUNT.FIRSTNAME,
ACCOUNT.LASTNAME,
ACCOUNT.STATUS,
ACCOUNT.ADDR1,
ACCOUNT.ADDR2,
ACCOUNT.CITY,
..
from ACCOUNT, PROFILE, SIGNON, BANNERDATA
where ACCOUNT.USERID = #username#
and SIGNON.PASSWORD = #password#
and SIGNON.USERNAME = ACCOUNT.USERID
and PROFILE.USERID = ACCOUNT.USERID
and PROFILE.FAVCATEGORY = BANNERDATA.FAVCATEGORY
</mapped-statement>
然后C业务? 业务层ؓ表达层提供服?操纵数据层来完成业务逻辑比如从数据库中读出客启信息传l表辑ֱ 向数据库中插入订单等.业务层还要完成对数据库操作的完整?正确性即事务理. 此应用是通过Spring的AOP来完成无需~程实现如下:
dataAccessContex-local.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
<!-- Transaction manager for a single JDBC DataSource -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>org/springframework/samples/jpetstore/Hibernate/Account.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- (see dataAccessContext-jta.xml for an alternative) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!-- SqlMap setup for iBATIS Database Layer -->
<bean id="sqlMap" class="org.springframework.orm.ibatis.SqlMapFactoryBean">
<property name="configLocation"><value>WEB-INF/sql-map-config.xml</value></property>
</bean>
<!-- ========================= DAO DEFINITIONS: IBATIS IMPLEMENTATIONS ========================= -->
<bean id="accountDao" class="org.springframework.samples.jpetstore.dao.hibdaoimp.AccountDaoImp">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
................
</beans>
applicationContex.xml
<bean id="petStoreTarget" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
<property name="accountDao"><ref bean="accountDao"/></property>
<property name="categoryDao"><ref bean="categoryDao"/></property>
<property name="productDao"><ref bean="productDao"/></property>
<property name="itemDao"><ref bean="itemDao"/></property>
<property name="orderDao"><ref bean="orderDao"/></property>
</bean>
<!-- Transactional proxy for the JPetStore primary business object -->
<bean id="petStore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref local="petStoreTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
从上面的配置代码我们可看到通过Spring的IOC完成?font color="#ff0033">org.springframework.samples.jpetstore.domain.logic.PetStoreImpl{类的注? 通过AOP?/font>org.springframework.transaction.interceptor.TransactionProxyFactoryBean来完成事务代?br />业务层通过一个门?facada)PetStoreFacade.java接口来ؓ表达层提供服?
package org.springframework.samples.jpetstore.domain.logic;
public interface PetStoreFacade {
Account getAccount(String username);
Account getAccount(String username, String password);
void insertAccount(Account account);
void updateAccount(Account account);
..........
}
用PetStoreImp.java来实?
package org.springframework.samples.jpetstore.domain.logic;
public class PetStoreImpl implements PetStoreFacade, OrderService {
private AccountDao accountDao;
.........
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
public Account getAccount(String username) {
return this.accountDao.getAccount(username);
}
public Account getAccount(String username, String password) {
return this.accountDao.getAccount(username, password);
}
public void insertAccount(Account account) {
this.accountDao.insertAccount(account);
}
.......
}
表达层这里介lStructs,Structs中通过PetStoreFacade接口来访问业务层:
package org.springframework.samples.jpetstore.web.struts;
public abstract class BaseAction extends Action {
private PetStoreFacade petStore;
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
ServletContext servletContext = actionServlet.getServletContext();
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
this.petStore = (PetStoreFacade) wac.getBean("petStore");
}
protected PetStoreFacade getPetStore() {
return petStore;
}
}
public class SignonAction extends BaseAction {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
AccountActionForm acctForm = (AccountActionForm) form;
String username = acctForm.getUsername();
String password = acctForm.getPassword();
Account account = getPetStore().getAccount(username, password);
.....
return mapping.findForward("success");
}
Structs框架通过struct-config.xml文来控制相关映射转发?
struct-config.xml
<action path="/signon" type="org.springframework.samples.jpetstore.web.struts.SignonAction"
name="accountForm" scope="request"
validate="false">
<forward name="success" path="/index.jsp"/>
</action>
关于jsp׃在多说了下面再来看一下它的web.xml文g:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dataAccessContext-local.xml /WEB-INF/applicationContext.xml
</param-value>
</context-param>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
q有关于q程机制有Caucho的Hessian(一个借助HTTP的二q制协议) Burlap(一个基于XML的借助HTTP的传输协?, Apache Axis提供的JAX-RPC(ZSOAP的借助HTTP传输的web serverice), q有ZRMI的远E调?
想了解更多还是自已细看里面的代码?
Ll关注Spring JPetStore(? 在其上实现自已的Sunlight Netstore
借助?..\spring-jpetstore\samples\jpetstore\db\hsqldb\manager.bat)看到的hsql数据库中的数?br />
发布搞定下面对它做一些简要的分析!
LSpring JPetStore(? JPetStore的分?/a>
一 开发环境的搭徏
1 软g安装
1.1 安装数据库管理系lSQL Server2000
1.2 安装JDK1.4(例:安装在C:\jdk1.4)
JDK可到http://www.sun.com/download/index.jsp?cat=Application%20Development&tab=3&subcat=SDKs%20(Software%20Development%20Kits) 下蝲
1.3 安装JSP服务器Tomcat5.0(例:安装在C:\tomcat5.0)
Tomcat可到http://jakarta.apache.org/site/downloads/downloads_tomcat-5.html下蝲
(如果下蝲的是压羃包则解压后就可用不用安装Q接着以下讄环境变量)
1Q? 安装好要讄环境变量
步骤Q右L的电?>属?>高->环境变量?如果已有变量名则~辑Q如果还没有则新?
catalina_home=Tomcat安装路径 Q例Q?catalina_home=C:\tomcat5.0Q?br />catalina_base = Tomcat安装路径 Q例Q?catalina_base=C:\tomcat5.0Q?br />classpath= .;JDK安装路径\lib;%classpath% (? classpath=.;C:\jdk1.4\lib;)
java_home= JDK安装路径 (? java_home=c:\jdk1.4)
1.5 试服务器安装是否成?br />启动服务?双击c:\tomcat5.0\bin\startup.bat文g)Q启动浏览器在地址栏中输入Q?a href="http://localhost:8080/">http://localhost:8080/
Q?br /><%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>login.html</title>
<script language="javascript" src="../share/com.js"></script>
<script language="javaScript" >
<!--
function checkstr()
{
if(form.username.value=="")
{alert("用户名不能ؓI!");
return false;
}
if(form.password.value=="")
{alert("密码不能为空Q?);
return false;}
else {
form.submit();
}
}
-->
</script>
</head>
<body>
<table width="1000" border="0" cellspacing="0" cellpadding="0">
<tr>
<td ><form name="form" method="post" action="logincheck.jsp">
<table width="563" height="100" border="0" bordercolor="#FF9900">
<tr>
<td width="148" align="center"> </td>
<td width="121" height="35" align="center"> 用户名:</td>
<td width="280" align="left" >
<input name="username" type="text" maxlength="13" value="linan"></td>
</tr>
<tr>
<td align="center"> </td>
<td align="center">?amp;nbsp; 码:</td>
<td align="left">
<input name="password" type="password" maxlength="15" value="linan"></td>
</tr>
<tr align="center" valign="bottom">
<td height="32" colspan="3"><input name="login" type="button" value="登陆" onClick="checkstr()">
<input name="button" type="button" onClick="reg()" value="注册"></td>
</tr>
</table>
</form></td>
</tr>
</table>
</body>
</html>
2 logincheck.jsp
<%@ page contentType="text/html; charset=gb2312" language="java" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<html>
<head>
<title>logincheck.jsp</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<%@ page import="java.sql.*"%>
<body>
<%
String username=(String)request.getParameter("username");
String password=(String)request.getParameter("password");
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection("jdbc:odbc:login","","");
String sqls="select * from usertest where username='"+username+"' and password='"+password+"'";
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(sqls);
int k=0;
if(rs.next()){
k=k+1;
}
if(k>0)
response.sendRedirect("ok.htm");
else
response.sendRedirect("login.html");
con.close();
}catch(Exception e){
out.println(e.toString());
}
%>
</body>
</html>
3 ok.htm
<%@ page contentType="text/html; charset=gb2312" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>ok</title>
</head>
<body>
<p>成功登陆Q?lt;/p>
</body>
</html>
?建立数据?br />1 建立数据库login建立表usertest
create database test
CREATE TABLE usertest (
[userid] [int] IDENTITY (1, 1) NOT NULL ,
[username] [char] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[password] [char] (10) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
insert into usertest values('linan','linan');
2.配置ODBC数据源(用JDBC-ODBC讉K数据库容易成功开发时可用Q?br /> 开?>讄->控制面版->理工具->ODBC数据?>d->SQL Server->(名称Qlogin(不能是其它的否则接不上数据库) 服务器:(127.0.0.1))->下一?>Q用windowsNT认证Q?>下一?>(更改默认的数据库为test))->下一?>完成
?一切搞定下面测?br />启动服务?双击c:\tomcat5.0\bin\startup.bat文g)Q启动浏览器在地址栏中输入Q?a href="http://localhost:8080/login\login.jsp">http://localhost:8080/login\login.jsp(如果用户名与数据库中的相同则登陆成功Q默认ؓuser=name“linan?password=”linan?