青山不改,綠水長流,愛java很久很久
          有什么好的東東拉來share一下 有什么好的建議拉來say一下
          posts - 5,comments - 3,trackbacks - 0
           

          介紹

          本文并不想介紹StrutsSpringHibernate的原理系統(tǒng)架構(gòu)等,本文地目的是通過一個較復(fù)雜地實例介紹如何整合StrutsSpringHibernate,網(wǎng)上現(xiàn)有的例子雖然也能達到目的,但功能都比較單一,復(fù)雜的例子時會有意想不到的麻煩。本文對讀者假設(shè)已經(jīng)具備了以上框架的基礎(chǔ)知識。以及那些已經(jīng)了解StrutsSpringHibernate的基本概念,但是還沒有親身在較復(fù)雜的項目中體驗StrutsSpringHibernate的開發(fā)人員。

          1 Struts

             雖然不打算過多介紹Struts的原理,但是大概介紹一下還是有必要的。Struts本身就是 MVC 在這里負責將用戶數(shù)據(jù)傳人業(yè)務(wù)層,以及 將業(yè)務(wù)層處理的結(jié)果返回給用戶,此系統(tǒng)屬于較簡單WEB應(yīng)用,采用了OpenSessionInView模式處理LazyLoad問題,這樣我們可以在用戶視圖中使用 getset方法來方便地獲取關(guān)聯(lián)對象。為了處理龐大的ActionActionForm問題,在此我門準備使用DynaActionForm (DynaValidatorForm)DispatchAction以及 動態(tài)驗證框架 來解決。及使用Tile來解決框架問題 。使用自定義標簽處理分頁和身份驗證問題。

          2 Spring

             Spring Framework最得以出名的是與Hibernate的無縫鏈接,雖然Spring Hibernate提供了90%以上的封裝,使我們不必去關(guān)心Session 的建立,關(guān)閉,以及事務(wù)使我們能夠?qū)P牡年P(guān)注業(yè)務(wù)邏輯。但是一些特殊情況如 有時需要Query以及Criteria 對象,分頁等,Spring不能給我們提供支持,總不能每次都在你的DAO上寫個HibernateCallBackup()吧?Spring的作用不是把Hibernate再封裝一層,而是讓你接觸不到HibernateAPI,而是幫助你管理好SessionTransaction

          在這里解決方法是:首先 寫一個IBase 的接口,和一個BaseDao的實現(xiàn)。在實現(xiàn)中仿照HibernateTemplate,將其功能一一實現(xiàn),同時考慮到Spring 未能支持的地方,我們不得已只好自己來管理Session,因此加入public Session openSession()public Query getQuery(String sql)public Criteria getCriteria(Class clazz),以及分頁的方法。 然后為每一個Entity 都建立繼承于以上類的IEntity,與EntityDao。這里可以根據(jù)需求對Entity加入特殊的方法實現(xiàn),如 StudentsDao.java 中加入類似用戶身份驗證等。以上就是數(shù)據(jù)訪問層。接下來在Service層中通過對dao的引用完成業(yè)務(wù)邏輯方法。在下面的例子中我們分別為學(xué)生模塊,教師模塊,管理員模塊構(gòu)建Service層,StudentsServiceImplTeachersServiceImplAdminServiceImpl

           

          3 Hibernate

           有了Spring的封裝,我們要對Hibernate做的就是正確實現(xiàn)對象關(guān)系的映射。由于此處處于系統(tǒng)的最底層,準確無誤的實現(xiàn)對象之間的關(guān)聯(lián)關(guān)系映射將起著至關(guān)重要的作用。

           總之,理解了StrutsSpringHibernate地原理以及之間的關(guān)系之后,剩下的工作就如同在以Spring為核心的Struts為表現(xiàn)的框架中堆積木。

          下圖可以更好的幫助我們理解StrutsSpringHibernate之間的關(guān)系。
          pic1.JPG

          案例簡述

          設(shè)計思路主要源于 大學(xué)選修課,該系統(tǒng)可以方便處理學(xué)生在課程選報,學(xué)分查詢,成績查詢,以及 成績發(fā)布等。

          系統(tǒng)以班級為核心,一門課程可以對應(yīng)多個班級,一名教師也可以帶不同的班級,學(xué)生可以選報不同課程所對應(yīng)的班級,班級自身有目前人數(shù),和最大人數(shù),以及上課時間,上課地點的屬性。

          學(xué)生在選報班級之后,班級的人數(shù)會自動加一,直到等于最大人數(shù)時,其他學(xué)生將會有人數(shù)已滿的錯誤提示。同理如果學(xué)生選擇了同一課程的不同班級,也將收到錯誤提示。學(xué)生有密碼,系別,學(xué)分,地址,電話等屬性。

          教師在系統(tǒng)中主要負責成績發(fā)布,教師可以對其所帶的班級的學(xué)生的成績修改,系統(tǒng)會以成績是否大于等于60來判斷學(xué)生是否通過考試,如果通過會將該課程的學(xué)分累加到學(xué)生學(xué)分,同樣如果教師二次修改了成績,而且小于60,系統(tǒng)會在學(xué)生學(xué)分上扣掉該課程的分數(shù)。

          課程在系統(tǒng)中具體體現(xiàn)為班級,自身帶有學(xué)分屬性。

          系有編號,名稱的屬性,同時可以作為聯(lián)系教師,課程,學(xué)生的橋梁。

           

          功能模塊

          l       身份驗證模塊: 根據(jù)用戶名,密碼,用戶類別 轉(zhuǎn)發(fā)用戶到不同的模塊。

          l       學(xué)生模塊: 查看課程,查看班級,選報課程,查看己選課程,成績查詢。

          l       教師模塊: 錄入成績

          l       管理員模塊:對學(xué)生,教師,課程,班級,系 增,刪,查,改。

           

          具體實踐

          代碼下載
          http://www.aygfsteel.com/Files/limq/StudentManger.rar
          1  
          對象關(guān)系映射:

          首先,將庫表映射為數(shù)據(jù)模型(SQL在源碼中查看),轉(zhuǎn)換后的數(shù)據(jù)模型如下圖:
          pic2.jpg

          由此我們可以看出一下關(guān)聯(lián)關(guān)系:

          1 Students Contact(聯(lián)系方式)一對一關(guān)系。

          2 Students History(選課歷史) 一對多關(guān)系

          3 Students Classes 多對多關(guān)系。

          4 Classes Classes_info 一對多關(guān)系。

          5 Classes Teachers 多對一關(guān)系。

          6 Classes Courses 多對一關(guān)系。

          7 Course Department(系) 多對一關(guān)系。

          8 Teachers Department 多對一關(guān)系。

          9 Students Department 多對一關(guān)系。

           

          Hibernate中將以上關(guān)系一一映射,如Students History 一對多關(guān)系

          Students.cfg.xm.

           

           1 <set name="history"
           2                  table="history" 
           3                  cascade="all"
           4                  inverse="true"
           5                  lazy="true"  >
           6                 <key  column="student_id"/> 
           7             <one-to-many class="limq.hibernate.vo.History"
           8                                     />
           9             set>
          10 

          同樣在History.cfg.xml中加入:

          1  <many-to-one name="student"
          2                   class="limq.hibernate.vo.Students"
          3                   column="student_id"  >    
          4      many-to-one>
          5 

          用過MyEclipse開發(fā)Hibernate的就知道,MyEclipse會幫助我們生成持久對象和抽象對象,我們要在 Students.java 中加入對History的引用

          private Set history=new HashSet();

           

               public Set getHistory() {

                  return history;

                }

           

              public void setHistory(Set history) {

                  this.history = history;

          }

          同時,在AbstractHistory.java 中刪除student_id 以及對應(yīng)的getset 方法,History.java 中加入

          private Students student;

          public Students getStudent() {

                  return student;

              }

            

           public void setStudent(Students student) {

                  this.student = student;

              }

          具體內(nèi)容請查看 源代碼。

          2 DAO 數(shù)據(jù)訪問層

          首先,編寫IBaseDaoBaseDao,其中IBaseDao代碼如下:

           

           1 package limq.hibernate.dao;
           2 
           3 import java.util.Collection;
           4 import java.util.List;
           5 import net.sf.hibernate.Criteria;
           6 import net.sf.hibernate.Query;
           7 import net.sf.hibernate.Session;
           8 import limq.exception.DaoException;
           9 
          10 public interface IBaseDao {
          11     
          12     public Session openSession();
          13     
          14     public  int getTotalCount( String hql) throws Exception;
          15     
          16     public Query getQuery(String sql) throws Exception;
          17     
          18     public Criteria getCriteria(Class clazz) throws Exception;
          19     
          20     public int getTotalPage(int totalCount,int pageSize);
          21     
          22     public void create(Object entity);
          23 
          24     public void update(Object entity);
          25 
          26     public void delete(Object entity) throws DaoException;
          27 
          28     public void deleteAll(Class clazz) throws DaoException;
          29 
          30     public void deleteAll(Collection entities) throws DaoException;
          31 
          32     public Object loadByKey(Class clazz, String keyName, Object keyValue);
          33 
          34     public List find(String queryString) throws DaoException;
          35 
          36     public List find(String queryString, Object param) throws DaoException;
          37 
          38     public List find(String queryString, Object[] params) throws DaoException;
          39 
          40 }
          41 


          BaseDao繼承org.springframework.orm.hibernate.support.HibernateDaoSupport

          實現(xiàn)以上的 定義的方法

          如:

           1 public void create(Object entity)  { 
           2         try { 
           3             getHibernateTemplate().save(entity); 
           4             
           5         } catch (Exception e) { 
           6             log.error("保存 " + entity.getClass().getName() + " 實例到數(shù)據(jù)庫失敗", e); 
           7            
           8         } 
           9     } 
          10     /** 
          11      * 獲得session        
          12      */ 
          13     public Session openSession() {
          14         return SessionFactoryUtils.getSession(getSessionFactory(), false);
          15     }
          16 
          17     /** 
          18      * 獲得Query對象       
          19      */ 
          20     public Query getQuery(String sql) throws Exception{
          21         Session session = this.openSession();
          22         Query query = session.createQuery(sql); 
          23     return query;
          24     }
          25     /** 
          26      * 獲得Criteria對象       
          27      */
          28     public Criteria getCriteria(Class clazz) throws Exception{
          29         
          30     Session session=this.openSession();
          31     Criteria criteria = session.createCriteria(clazz);
          32     return criteria;
          33     }
          34 

          可以看到,這里即充分利用了SpringHibernate的支持,還彌補了Spring的不足。最后分別為每個持久對象建立Interface,以及DAO,使其分別繼承IBaseDaoBaseDao

          IDepartmentDepartmentDao

          1 public interface IDepartment extends IBaseDao {}
          2 
          3 public class DepartmentDao extends BaseDao implements IBaseDao {}
          4 

           

          3 Service

           在這里需要認真思考每個業(yè)務(wù)邏輯所能用到的持久層對象和DAO,還要完成配置Spring框架, 首先我一起看看applications-service.xml

           

            1 xml version="1.0" encoding="UTF-8"?>
            2 DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
            3     "http://www.springframework.org/dtd/spring-beans.dtd">
            4 <beans>
            5   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            6     <property name="driverClassName">
            7       <value>com.mysql.jdbc.Drivervalue>
            8     property>
            9     <property name="url">
           10       <value>jdbc:mysql://localhost:3306/Studentvalue>
           11     property>
           12     <property name="username">
           13       <value>rootvalue>
           14     property>
           15     <property name="password">
           16       <value>value>
           17     property>
           18   bean>
           19   <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
           20     <property name="dataSource">
           21       <ref local="dataSource"/>
           22     property>
           23     <property name="mappingResources">
           24       <list>
           25         <value>limq/hibernate/vo/Admins.hbm.xmlvalue>
           26         <value>limq/hibernate/vo/Classes.hbm.xmlvalue>
           27         <value>limq/hibernate/vo/Courses.hbm.xmlvalue>
           28         <value>limq/hibernate/vo/Students.hbm.xmlvalue>
           29         <value>limq/hibernate/vo/ClassesInfo.hbm.xmlvalue>
           30         <value>limq/hibernate/vo/Contact.hbm.xmlvalue>
           31         <value>limq/hibernate/vo/Department.hbm.xmlvalue>
           32         <value>limq/hibernate/vo/History.hbm.xmlvalue>
           33         <value>limq/hibernate/vo/Teachers.hbm.xmlvalue>
           34       list>
           35     property>
           36     <property name="hibernateProperties">
           37       <props>
           38         <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialectprop>
           39         <prop key="hibernate.show_sql">trueprop>
           40       props>
           41     property>
           42   bean>
           43   <bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
           44     <property name="sessionFactory">
           45       <ref local="sessionFactory"/>
           46     property>
           47   bean>
           48   
           49   <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
           50     <property name="sessionFactory">
           51       <ref bean="sessionFactory"/>
           52     property>
           53   bean>
           54   <bean id="studentDaoTarget" class="limq.hibernate.dao.StudentsDao">
           55     <property name="sessionFactory">
           56       <ref bean="sessionFactory"/>
           57     property>
           58   bean>
           59   <bean id="teacherDaoTarget" class="limq.hibernate.dao.TeachersDao">
           60     <property name="sessionFactory">
           61       <ref bean="sessionFactory"/>
           62     property>
           63   bean>
           64   <bean id="courseDaoTarget" class="limq.hibernate.dao.CoursesDao">
           65     <property name="sessionFactory">
           66       <ref bean="sessionFactory"/>
           67     property>
           68   bean>
           69   <bean id="classDaoTarget" class="limq.hibernate.dao.ClassesDao">
           70     <property name="sessionFactory">
           71       <ref bean="sessionFactory"/>
           72     property>
           73   bean>
           74   <bean id="departmentDaoTarget" class="limq.hibernate.dao.DepartmentDao">
           75     <property name="sessionFactory">
           76       <ref bean="sessionFactory"/>
           77     property>
           78   bean>
           79   <bean id="adminDaoTarget" class="limq.hibernate.dao.AdminDao">
           80     <property name="sessionFactory">
           81       <ref bean="sessionFactory"/>
           82     property>
           83   bean>
           84   <bean id="studentDao" class="org.springframework.aop.framework.ProxyFactoryBean">
           85     <property name="proxyInterfaces">
           86       <value>limq.hibernate.dao.IStudentsvalue>
           87     property>
           88     <property name="interceptorNames">
           89       <list>
           90         <value>hibernateInterceptorvalue>
           91         <value>studentDaoTargetvalue>
           92       list>
           93     property>
           94   bean>
           95   <bean id="teacherDao" class="org.springframework.aop.framework.ProxyFactoryBean">
           96     <property name="proxyInterfaces">
           97       <value>limq.hibernate.dao.ITeachersvalue>
           98     property>
           99     <property name="interceptorNames">
          100       <list>
          101         <value>hibernateInterceptorvalue>
          102         <value>teacherDaoTargetvalue>
          103       list>
          104     property>
          105   bean>
          106   <bean id="courseDao" class="org.springframework.aop.framework.ProxyFactoryBean">
          107     <property name="proxyInterfaces">
          108       <value>limq.hibernate.dao.ICoursesvalue>
          109     property>
          110     <property name="interceptorNames">
          111       <list>
          112         <value>hibernateInterceptorvalue>
          113         <value>courseDaoTargetvalue>
          114       list>
          115     property>
          116   bean>
          117   <bean id="classDao" class="org.springframework.aop.framework.ProxyFactoryBean">
          118     <property name="proxyInterfaces">
          119       <value>limq.hibernate.dao.IClassesvalue>
          120     property>
          121     <property name="interceptorNames">
          122       <list>
          123         <value>hibernateInterceptorvalue>
          124         <value>classDaoTargetvalue>
          125       list>
          126     property>
          127   bean>
          128   <bean id="departmentDao" class="org.springframework.aop.framework.ProxyFactoryBean">
          129     <property name="proxyInterfaces">
          130       <value>limq.hibernate.dao.IDepartmentvalue>
          131     property>
          132     <property name="interceptorNames">
          133       <list>
          134         <value>hibernateInterceptorvalue>
          135         <value>departmentDaoTargetvalue>
          136       list>
          137     property>
          138   bean>
          139   <bean id="adminDao" class="org.springframework.aop.framework.ProxyFactoryBean">
          140     <property name="proxyInterfaces">
          141       <value>limq.hibernate.dao.IAdminvalue>
          142     property>
          143     <property name="interceptorNames">
          144       <list>
          145         <value>hibernateInterceptorvalue>
          146         <value>adminDaoTargetvalue>
          147       list>
          148     property>
          149   bean>
          150   
          151   <bean id="studentManagerTarget" class="limq.spring.service.StudentsServiceImpl">
          152     <property name="studentsDao">
          153       <ref bean="studentDao"/>
          154     property>
          155     <property name="coursesDao">
          156       <ref bean="courseDao"/>
          157     property>
          158     <property name="classesDao">
          159       <ref bean="classDao"/>
          160     property>
          161     <property name="departmentsdao">
          162       <ref bean="departmentDao"/>
          163     property>
          164   bean>
          165   <bean id="teacherManagerTarget" class="limq.spring.service.TeachersServiceImpl">
          166     <property name="teachersDao">
          167       <ref bean="teacherDao"/>
          168     property>
          169     <property name="coursesDao">
          170       <ref bean="courseDao"/>
          171     property>
          172     <property name="classesDao">
          173       <ref bean="classDao"/>
          174     property>
          175     <property name="studentsDao">
          176       <ref bean="studentDao"/>
          177     property>
          178   bean>
          179   <bean id="adminManagerTarget" class="limq.spring.service.AdminServiceImpl">
          180     <property name="adminDao">
          181       <ref bean="adminDao"/>
          182     property>
          183     <property name="teachersDao">
          184       <ref bean="teacherDao"/>
          185     property>
          186     <property name="coursesDao">
          187       <ref bean="courseDao"/>
          188     property>
          189     <property name="classesDao">
          190       <ref bean="classDao"/>
          191     property>
          192     <property name="studentsDao">
          193       <ref bean="studentDao"/>
          194     property>
          195     <property name="departmentsdao">
          196       <ref bean="departmentDao"/>
          197     property>
          198   bean>
          199   
          200   <bean id="studentManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          201     <property name="transactionManager">
          202       <ref bean="myTransactionManager"/>
          203     property>
          204     <property name="target">
          205       <ref bean="studentManagerTarget"/>
          206     property>
          207     <property name="transactionAttributes">
          208       <props>
          209         <prop key="get*">PROPAGATION_SUPPORTSprop>
          210         <prop key="*">PROPAGATION_REQUIREDprop>
          211       props>
          212     property>
          213   bean>
          214   <bean id="teacherManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          215     <property name="transactionManager">
          216       <ref bean="myTransactionManager"/>
          217     property>
          218     <property name="target">
          219       <ref bean="teacherManagerTarget"/>
          220     property>
          221     <property name="transactionAttributes">
          222       <props>
          223         <prop key="get*">PROPAGATION_SUPPORTSprop>
          224         <prop key="*">PROPAGATION_REQUIREDprop>
          225       props>
          226     property>
          227   bean>
          228   <bean id="adminManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          229     <property name="transactionManager">
          230       <ref bean="myTransactionManager"/>
          231     property>
          232     <property name="target">
          233       <ref bean="adminManagerTarget"/>
          234     property>
          235     <property name="transactionAttributes">
          236       <props>
          237         <prop key="get*">PROPAGATION_SUPPORTSprop>
          238         <prop key="*">PROPAGATION_REQUIREDprop>
          239       props>
          240     property>
          241   bean>
          242 beans>
          243 


          StudentsServiceImpl以為例,下圖演示了如何利用SpringIocHibernate的結(jié)合。

          可以看到分別將studentDao,classDao,coursesDao,departmentDao,注入studentManager.
          pic4.JPG

            1 IStudentsService.java
            2 public interface IStudentsService {
            3 
            4     public  boolean validate(String username,String pasword);  
            5     public Classes[] getClassesFromCourse(Courses courses);
            6     public  Department getDepFromID(Integer id);
            7     public   Courses getCourseFromID(Integer id);
            8     public   Classes getClassFromID(Integer id);
            9     public  Students getStudetFromName(String name);
           10     public  boolean ifEnrolSameCourse(Classes clazz,Students stu);
           11     public  void selectClasses(Students stu, Classes clazz,Date date);
           12     public  boolean ifMoreThanCap(Classes clazz);
           13     public void updateSudent(Students stu,Contact contact);
           14     public HashMap getCourse(PageInfo pageinfo) throws Exception;
           15     public HashMap getStudentHistory(PageInfo pageinfo,String stu_name) throws Exception;
           16  
           17 }
           18 
           19 實現(xiàn)StudentsServiceImpl.java
           20 public class StudentsServiceImpl implements IStudentsService {
           21 
           22     private Logger log = Logger.getLogger(this.getClass());
           23 
           24     private IStudents studentsDao;
           25 
           26     private ICourses coursesDao;
           27 
           28     private IClasses classesDao;
           29 
           30     private IDepartment departmentsdao;
           31 
           32     /**
           33      * 驗證用戶名密碼
           34      * 
           35      * @param username
           36      *            用戶名
           37      * @param password
           38      *            密碼
           39      */
           40 
           41     public boolean validate(String username, String password) {
           42 
           43         String password2 = studentsDao.getPasswordFromUsername(username);
           44         if (password.equals(password2))
           45             return true;
           46         else
           47             return false;
           48 
           49     }
           50 
           51     /**
           52      * 查找所有課程
           53      *  
           54      */
           55     public Courses[] getAllCourses() {
           56 
           57         List list = null;
           58         try {
           59 
           60             list = coursesDao.find("select c from Courses as c ");
           61         } catch (Exception e) {
           62         }
           63 
           64         return (Courses[]) list.toArray(new Courses[0]);
           65     }
           66 
           67     /**
           68      *  分頁顯示所有課程
           69      * 
           70      * @param pageinfo
           71      */
           72     public HashMap getCourse(PageInfo pageinfo) throws Exception {
           73 
           74         HashMap hp = new HashMap();
           75         String hsql = "select c from Courses as c order by c.id";
           76         Query query = coursesDao.getQuery(hsql);
           77         int totalCount = pageinfo.getTatalCount();
           78         int totalPage = pageinfo.getTotalpage();
           79         int start = pageinfo.getStart();
           80         totalCount = totalCount == -1 ? coursesDao.getTotalCount(hsql)
           81                 : totalCount;
           82         totalPage = totalPage == -1 ? coursesDao.getTotalPage(totalCount,
           83                 pageinfo.getPageSize()) : totalPage;
           84         query.setFirstResult(start);
           85         query.setMaxResults(pageinfo.getPageSize());
           86         List list = query.list();
           87         hp.put("courses", (Courses[]) list.toArray(new Courses[0]));
           88         hp.put("totalCount"new Integer(totalCount));
           89         hp.put("totalPage"new Integer(totalPage));
           90         return hp;
           91     }
           92     /**
           93      *  分頁顯示所有選課歷史
           94      * @param pageinfo 
           95      * @param stu_name
           96      */
           97     public HashMap getStudentHistory(PageInfo pageinfo, String stu_name)
           98             throws Exception {
           99         HashMap hp = new HashMap();
          100         Students stu = this.getStudetFromName(stu_name);
          101         Integer stu_id = stu.getId();
          102         Criteria criteria = coursesDao.getCriteria(History.class);
          103         criteria.createCriteria("student").add(Expression.eq("name", stu_name));
          104         int totalCount = pageinfo.getTatalCount();
          105         int totalPage = pageinfo.getTotalpage();
          106         int start = pageinfo.getStart();
          107         totalCount = totalCount == -1 ? criteria.list().size() : totalCount;
          108         totalPage = totalPage == -1 ? studentsDao.getTotalPage(totalCount,
          109         pageinfo.getPageSize()) : totalPage;
          110         criteria.setFirstResult(start);
          111         criteria.setMaxResults(pageinfo.getPageSize());
          112         criteria.addOrder(Order.asc("id"));
          113         List list = criteria.list();
          114         hp.put("history", (History[]) list.toArray(new History[0]));
          115         hp.put("totalCount"new Integer(totalCount));
          116         hp.put("totalPage"new Integer(totalPage));
          117         return hp;
          118     }
          119     /**
          120      * 根據(jù)課程查找班級
          121      * @param course
          122      *            課程實體
          123      * @return 返回該課程下所有班級
          124      */
          125     public Classes[] getClassesFromCourse(Courses course) {
          126         return coursesDao.getClassesFromCourse(course);
          127     }
          128 
          129     /**
          130      * 根據(jù)主鍵查找系
          131      * @param id
          132      *            主鍵ID
          133      */
          134     public Department getDepFromID(Integer id) {
          135         return (Department) departmentsdao
          136                 .loadByKey(Department.class"id", id);
          137     }
          138 
          139     /**
          140      * 根據(jù)主鍵查找課程
          141      * @param id
          142      *            主鍵ID
          143      */
          144     public Courses getCourseFromID(Integer id) {
          145         return (Courses) coursesDao.loadByKey(Courses.class"id", id);
          146     }
          147     /**
          148      * 根據(jù)主鍵查找班級
          149      * @param id
          150      *            主鍵ID
          151      */
          152     public Classes getClassFromID(Integer id) {
          153         return (Classes) classesDao.loadByKey(Classes.class"id", id);
          154     }
          155 
          156     /**
          157      * 根據(jù)姓名查找學(xué)生
          158      * @param name
          159      */
          160     public Students getStudetFromName(String name) {
          161         return (Students) studentsDao.loadByKey(Students.class"name", name);
          162     }
          163 
          164     /**
          165      * 檢查學(xué)生是否選報了同一課程的班級
          166      * @param clazz
          167      *            所選報的班級
          168      * @param stu
          169      *            學(xué)生實體
          170      * @return true 該生選報同一課程的班級
          171      * @return false 沒有報過該課程的班級,可以選報
          172      *  
          173      */
          174     public boolean ifEnrolSameCourse(Classes clazz, Students stu) {
          175 
          176         Courses cour = clazz.getCourse();
          177 
          178         Classes[] classes = (Classes[]) stu.getClasses()
          179                 .toArray(new Classes[0]);
          180         for (int i = 0; i < classes.length; i++) {
          181 
          182             Courses c1 = classes[i].getCourse();
          183 
          184             if (c1.getId().equals(cour.getId()))
          185                 return true;
          186         }
          187         return false;
          188     }
          189 
          190     /**
          191      * 檢查課程的目前人數(shù) 
          192      * @param clazz
          193      *            檢查班級人數(shù)是否已滿
          194      * @param clazz
          195      *            班級實體
          196      * @return true 班級人數(shù)已滿
          197      * @return false 班級人數(shù)未滿
          198      *  
          199      */
          200     public boolean ifMoreThanCap(Classes clazz) {
          201         Integer capacity = clazz.getCapacity();
          202         Integer maxcapacity = clazz.getMaxcapacity();
          203         if (capacity.intValue() < maxcapacity.intValue()) {
          204             clazz.setCapacity(Integer.valueOf(capacity.intValue() + 1));
          205             //classesDao.update(clazz);
          206             return false;
          207         } else
          208             return true;
          209 
          210     }
          211 
          212     /**
          213      * 數(shù)據(jù)庫插入選擇班級的記錄
          214      * @param stu
          215      *            學(xué)生
          216      * @param clazz
          217      *            所選擇的班級
          218      */
          219     public void selectClasses(Students stu, Classes clazz, Date date)
          220  {
          221         stu.getClasses().add(clazz);
          222         clazz.getStudents().add(stu);          
          223         History his = new History();
          224         his.setEnrolTime(date);
          225         his.setStudent(stu);
          226         his.setClasses(clazz);
          227         his.setScore(clazz.getCourse().getScore());
          228         his.setMarking(new Double(0));
          229         try{
          230         String cour_name=new String(clazz.getCourse().getName().getBytes("GBK"));       
          231         his.setCourseName(cour_name);
          232         }catch( java.io.UnsupportedEncodingException e){e.getStackTrace();}       
          233         stu.getHistory().add(his);
          234     }
          235 
          236     public void updateSudent(Students stu,Contact contact){
          237         
          238        studentsDao.update(stu);
          239        studentsDao.update(contact);
          240     
          241     }
          242     public IStudents getStudentsDao() {
          243         return studentsDao;
          244     }
          245     public void setStudentsDao(IStudents studentsDao) {
          246         this.studentsDao = studentsDao;
          247     }
          248     public IClasses getClassesDao() {
          249         return classesDao;
          250     }
          251     public void setClassesDao(IClasses classesDao) {
          252         this.classesDao = classesDao;
          253     }
          254     public ICourses getCoursesDao() {
          255         return coursesDao;
          256     }
          257     public void setCoursesDao(ICourses coursesDao) {
          258         this.coursesDao = coursesDao;
          259     }
          260     public IDepartment getDepartmentsdao() {
          261         return departmentsdao;
          262     }
          263     public void setDepartmentsdao(IDepartment departmentdao) {
          264         this.departmentsdao = departmentdao;
          265     }
          266 }
          267 
          268 


          4 UI

          這里我們選擇Struts,首先配置 web.xml

           1 xml version="1.0" encoding="UTF-8"?>
           2 <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
           3   <context-param>
           4     <param-name>contextConfigLocationparam-name>
           5     <param-value>/WEB-INF/classes/applications-service.xmlparam-value>
           6   context-param>
           7   <context-param>
           8     <param-name>log4jConfigLocationparam-name>
           9     <param-value>/WEB-INF/log4j.propertiesparam-value>
          10   context-param>
          11   <filter>
          12     <filter-name>hibernateFilterfilter-name>
          13     <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilterfilter-class>
          14   filter>
          15   <filter-mapping>
          16     <filter-name>hibernateFilterfilter-name>
          17     <url-pattern>/*url-pattern>
          18   filter-mapping>
          19   <filter>
          20     <filter-name>Set Character Encodingfilter-name>
          21     <filter-class>limq.struts.SetCharacterEncodingFilterfilter-class>
          22   filter>
          23   <filter-mapping>
          24     <filter-name>Set Character Encodingfilter-name>
          25     <url-pattern>/*url-pattern>
          26   filter-mapping>
          27   <servlet>
          28     <servlet-name>SpringContextServletservlet-name>
          29     <servlet-class>org.springframework.web.context.ContextLoaderServletservlet-class>
          30     <load-on-startup>1load-on-startup>
          31   servlet>
          32   <servlet>
          33     <servlet-name>actionservlet-name>
          34     <servlet-class>org.apache.struts.action.ActionServletservlet-class>
          35     <init-param>
          36       <param-name>configparam-name>
          37       <param-value>/WEB-INF/struts-config.xmlparam-value>
          38     init-param>
          39     <init-param>
          40       <param-name>debugparam-name>
          41       <param-value>3param-value>
          42     init-param>
          43     <init-param>
          44       <param-name>detailparam-name>
          45       <param-value>3param-value>
          46     init-param>
          47     <load-on-startup>0load-on-startup>
          48   servlet>
          49   <servlet-mapping>
          50     <servlet-name>actionservlet-name>
          51     <url-pattern>*.dourl-pattern>
          52   servlet-mapping>
          53 web-app>
          54 
          55 

          其中注意這幾句,

          1 <filter>
          2     <filter-name>hibernateFilterfilter-name>
          3 <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilterfilter-class>
          4   filter>
          5 <filter-mapping>
          6     <filter-name>hibernateFilterfilter-name>
          7     <url-pattern>/*url-pattern>
          8 filter-mapping>
          9 


          由于我們使用了lazy = "true"如果想在UI層使用實體對象關(guān)聯(lián)來獲得其他對象時就會有這樣的提示:

          org.hibernate.LazyInitializationException: failed to lazily initialize a collection

          Spring 中引入了 OpenSessionInView模式可以處理以上問題,即在web.xml中加入以上代碼。

           

           

          接下來建立抽象BaseAction,和 BaseDispatchAction,其中后者與前者相似目的為減少Action的數(shù)量

           1 abstract class BaseAction extends Action {
           2 
           3     private IStudentsService studentsService;
           4     private ITeachersService teachersSerivce;
           5     private IAdminService adminService;
           6     public void setServlet(ActionServlet actionServlet) {
           7         super.setServlet(actionServlet);
           8         ServletContext servletContext = actionServlet.getServletContext();
           9         WebApplicationContext wac = WebApplicationContextUtils
          10                 .getRequiredWebApplicationContext(servletContext);
          11 
          12         this.studentsService = (IStudentsService) wac.getBean("studentManager");
          13         this.adminService = (IAdminService) wac.getBean("adminManager");
          14         this.teachersSerivce = (ITeachersService) wac.getBean("teacherManager");
          15     }
          16     public IStudentsService getStudentsService() {
          17         return studentsService;
          18     }
          19     public ITeachersService getTeachersSerivce() {
          20         return teachersSerivce;
          21     }
          22     public void setTeachersSerivce(ITeachersService teachersSerivce) {
          23         this.teachersSerivce = teachersSerivce;
          24     }
          25     public IAdminService getAdminService() {
          26         return adminService;
          27     }
          28     public void setAdminService(IAdminService adminService) {
          29         this.adminService = adminService;
          30     }
          31 }
          32 


          BaseDispatchAction與之類似,請查看源碼。其他Action都從這兩個類繼承。

          以下就以查看課程下的班級為例演示StrutsSpring的使用:

           

           1 CoursesAction.java
           2     /** 
           3      * 查看課程下的班級 
           4      */ 
           5     public ActionForward viewClassFromCourse(ActionMapping mapping,
           6             ActionForm form, HttpServletRequest request,
           7             HttpServletResponse response) throws Exception {
           8         Integer cour_id = Integer.valueOf((request.getParameter("cour_id")));
           9         Courses cour = super.getStudentsService().getCourseFromID(cour_id);
          10         Classes[] clazz =(Classes[])cour.getClasses().toArray(new Classes[0]);
          11         request.setAttribute("clazz", clazz);
          12         return mapping.findForward("success");
          13 }
          14 

          這里從上一個頁面獲得課程編號 cour_id, 然后通過StudentsServiceImpl中的

          1 public Courses getCourseFromID(Integer id) {
          2         return (Courses) coursesDao.loadByKey(Courses.class"id", id);
          3 }
          4 

          方法查到Courses實例,利用CoursesClasses的關(guān)聯(lián)關(guān)系得到Classes[],在將其放入

          Request. 通過mapping.findForward("success"),轉(zhuǎn)發(fā)到

          select_course_Content.jsp


          CustomRequestProcessor.java 介紹

           1 public class CustomRequestProcessor extends RequestProcessor {
           2     protected boolean
           processPreprocess(HttpServletRequest request,
           3 
                      HttpServletResponse response) {
           4         boolean continueProcessing = true
          ;
           5         HttpSession session =
           request.getSession();
           6         String uri =
          request.getRequestURI();
           7         if ( session == null || session.getAttribute("userName"== null
           ) {
           8             continueProcessing = false
          ;  
           9         if(uri.endsWith("login.do")) return true
          ;    
          10         try
          {
          11             response.sendRedirect("/StudentManger/login.jsp"
           );
          12           }catch
          ( Exception ex ){
          13             log.error( "Problem sending redirect from processPreprocess()"
           );
          14 
                    }
          15 
                  }
          16         return
           continueProcessing;
          17 
              }
          18 
          }
          19 


          為了驗證用戶操作權(quán)限,這里擴展了Struts RequestProcessor來判斷Session如果SessionuserName都不空則程序繼續(xù),否則重定向到login.jsp。要想擴展RequestProcessor類,需在Struts的配置文件中加入

          1 <controller 
          2 contentType="text/html;charset=UTF-8"
          3 locale="true" 
          4 nocache="true" 
          5 processorClass="limq.struts.CustomRequestProcessor"/>
          6 

          呵呵,當然在正規(guī)使用時僅僅這樣驗證是不夠的。歡迎你把自己修改方法告訴我。

           

          4分頁處理:

          下面重點討論一下Hibernate的分頁處理方式。

          Hibernate 中處理查詢主要有 Query Criteria,分別以 HSQL或編程方式實現(xiàn),

          本例對這兩種方法都有相關(guān)處理。由于在Spring中無法直接使用QueryCriteria對象

          所以只有先從Spring那里借一個Session,等使用完了在還給Sping處理。讀者應(yīng)該還記得在BaseDao中有這樣的語句方便我們獲取Session及其他對象:

           

           1     public Query getQuery(String sql) throws Exception{
           2         Session session = this.openSession();
           3         Query query = session.createQuery(sql); 
           4     return query;
           5     }
           6    
           7     public Criteria getCriteria(Class clazz) throws Exception{
           8         
           9     Session session=this.openSession();
          10     Criteria criteria = session.createCriteria(clazz);
          11     return criteria;
          12     }
          13 

          Service層以查詢所有課程與學(xué)生選課記錄為例處理QueryCriteria

           1  StudentsServiceImpl.java
           2     public HashMap getCourse(PageInfo pageinfo) throws Exception {
           3 
           4         HashMap hp = new HashMap();
           5         String hsql = "select c from Courses as c order by c.id";
           6         Query query = coursesDao.getQuery(hsql);
           7         int totalCount = pageinfo.getTatalCount();
           8         int totalPage = pageinfo.getTotalpage();
           9         int start = pageinfo.getStart();
          10         totalCount = totalCount == -1 ? coursesDao.getTotalCount(hsql)
          11                 : totalCount;
          12         totalPage = totalPage == -1 ? coursesDao.getTotalPage(totalCount,
          13                 pageinfo.getPageSize()) : totalPage;
          14         query.setFirstResult(start);
          15         query.setMaxResults(pageinfo.getPageSize());
          16         List list = query.list();
          17         hp.put("courses", (Courses[]) list.toArray(new Courses[0]));
          18         hp.put("totalCount"new Integer(totalCount));
          19         hp.put("totalPage"new Integer(totalPage));
          20         return hp;
          21     }
          22    
          23     public HashMap getStudentHistory(PageInfo pageinfo, String stu_name)
          24             throws Exception {
          25         HashMap hp = new HashMap();
          26         Students stu = this.getStudetFromName(stu_name);
          27         Integer stu_id = stu.getId();
          28         Criteria criteria = coursesDao.getCriteria(History.class);
          29         criteria.createCriteria("student").add(Expression.eq("name", stu_name));
          30         int totalCount = pageinfo.getTatalCount();
          31         int totalPage = pageinfo.getTotalpage();
          32         int start = pageinfo.getStart();
          33         totalCount = totalCount == -1 ? criteria.list().size() : totalCount;
          34         totalPage = totalPage == -1 ? studentsDao.getTotalPage(totalCount,
          35         pageinfo.getPageSize()) : totalPage;
          36         criteria.setFirstResult(start);
          37         criteria.setMaxResults(pageinfo.getPageSize());
          38         criteria.addOrder(Order.asc("id"));
          39         List list = criteria.list();
          40         hp.put("history", (History[]) list.toArray(new History[0]));
          41         hp.put("totalCount"new Integer(totalCount));
          42         hp.put("totalPage"new Integer(totalPage));
          43         return hp;
          44     }
          45 PageIngfo.java
          46 public class PageInfo  {
          47     
          48     int pageNo=0;
          49     int totalpage=-1;
          50     int tatalCount=-1;
          51     int pageSize=0;
          52 int start=0;
          53 
          54 


          可以看到getCoursegetStudentHistory有很多相似之處,HibernateQueryCriteria提供了針對不同數(shù)據(jù)庫的解決分頁方法, Quey需要我們寫HSQL Criteria不但可以應(yīng)付帶有條件的查詢,還不用我們自己寫HSQLPageInfo是含有分頁信息的普通java類。

          再看看Struts是如何調(diào)用getStudentHistory 的,

           

           1 PageAction.java
           2 public class PageAction  extends BaseDispatchAction{
           3     public ActionForward execute(ActionMapping mapping,
           4              ActionForm form,
           5              HttpServletRequest request,
           6              HttpServletResponse response)
           7 throws Exception {
           8         String pageNo=request.getParameter("pageNo");
           9         String totalcount=request.getParameter("totalcount");
          10         String totalpage=request.getParameter("totalpage");
          11         int pagesize=2;//每頁的大小
          12         PageInfo page =new PageInfo();
          13         page.setPageSize(pagesize);
          14         HashMap hp=null;
          15         History[] historys = null;
          16         String stu_name=null;
          17         HttpSession session = request.getSession();
          18         stu_name = (String) session.getAttribute("userName"); 
          19         if(pageNo == null || totalcount == null || totalpage==null){
          20         //第一次發(fā)送請求
          21             page.setPageNo(1);           
          22             hp=super.getStudentsService().getStudentHistory(page,stu_name);
          23             page.setTatalCount(((Integer)hp.get("totalCount")).intValue());
          24             page.setTotalpage(((Integer)hp.get("totalPage")).intValue());      
          25         }else{
          26             page.setPageNo(Integer.parseInt(pageNo));
          27             page.setTatalCount(Integer.parseInt(totalcount));
          28             page.setTotalpage(Integer.parseInt(totalpage));
          29            hp=super.getStudentsService().getStudentHistory(page,stu_name);
          30            
          31         }
          32      historys =(History[]) hp.get("history");
          33      request.setAttribute("history",historys);
          34      request.setAttribute("pageinfo",page);    
          35         return mapping.findForward("success");
          36     }
          37 }
          38 


          stu_his_Content.jsp中避免代碼重復(fù)使用了自定義標志來處理分頁

           

           1 <%@ page contentType="text/html;charset=UTF-8" language="java"  %> 
           2 <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
           3 <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
           4 <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
           5 <%@ page import="limq.hibernate.vo.*"%>
           6 <%@ taglib uri="/WEB-INF/MyTag.tld" prefix="mytag"%>
           7 <%@ page import="limq.common.*"%>
           8 <html:html locale="true"> 
           9   <body>
          10   <%
          11   PageInfo pageinfo =(PageInfo) request.getAttribute("pageinfo");
          12   History[] historys = (History[])request.getAttribute("history");
          13   %>
          14 <table width="550" border="1" cellspacing="0" align="center" cellpadding="0">
          15   <tr>
          16     <td><bean:message key="class.id"/>td>
          17     <td><bean:message key="course.name"/>td>
          18     <td><bean:message key="enrol.time"/>td>
          19     <td><bean:message key="score"/>td>
          20     <td><bean:message key="marking"/>td>
          21   tr>
          22   <%
          23   for(int i=0;i<historys.length;i++){
          24   History  his=historys[i];
          25   %>
          26   <tr>
          27     <td><%=his.getClasses().getId()%>td>
          28     <td><%=his.getCourseName()%>td>
          29     <td><%=his.getEnrolTime()%>td>
          30     <td><%=his.getScore()%>td>
          31     <td><%=his.getMarking()%>td>
          32   tr>
          33   <%
          34   }
          35   %>
          36 table>
          37 <mytag:page pageinfo="<%=pageinfo%>" action="getHistory.do"/>
          38 body>
          39 html:html>
          40 


          標志處理類如下:

           1 PageTag.java
           2 
           3 public class PageTag extends SimpleTagSupport {
           4 
           5     private PageInfo pageinfo = null;
           6 private String action = null;
           7 
           8     public String getAction() {
           9         return action;}
          10     public void setAction(String action) {
          11         this.action = action;
          12     }
          13     public PageInfo getPageinfo() {
          14         return pageinfo;
          15     }
          16     public void setPageinfo(PageInfo pageinfo) {
          17         this.pageinfo = pageinfo;
          18     }
          19 
          20     public void doTag() throws JspException, IOException {
          21         JspWriter out = getJspContext().getOut();
          22 
          23         int totalpage = pageinfo.getTotalpage();
          24         int totalcount = pageinfo.getTatalCount();
          25         int pageNo = pageinfo.getPageNo();
          26         int addPageNo = pageNo + 1;
          27         int minPageNo = pageNo - 1;
          28 
          29         out.println(" "400\" align=\"center\"  cellPadding=\"0\" cellSpacing=\"0\"");
          30         out.print(" ");
          31         out.println(" " + totalcount + "條," + totalpage + "頁,當前"
          32                 + pageNo + "
          posted on 2007-07-03 17:26 Alex.xulei 閱讀(323) 評論(1)  編輯  收藏

          FeedBack:
          # re: Struts+Spring+Hibernate開發(fā)實例
          2007-07-04 07:39 | Very Good!
          請?zhí)峁┫螺d包,謝!  回復(fù)  更多評論
            

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 荣昌县| 烟台市| 德清县| 龙山县| 玛沁县| 福建省| 宣汉县| 弥渡县| 阿尔山市| 武穴市| 正阳县| 什邡市| 德阳市| 越西县| 北海市| 巨野县| 南昌县| 鸡泽县| 寻甸| 兴文县| 合江县| 长兴县| 简阳市| 龙游县| 怀安县| 资兴市| 稷山县| 汕尾市| 杨浦区| 罗定市| 伊宁市| 宁海县| 化州市| 当雄县| 华安县| 广州市| 大姚县| 左贡县| 高台县| 阿勒泰市| 平阳县|