struts+spring+hibernate
来源:互联网 发布:c语言 预处理指令 编辑:程序博客网 时间:2024/04/29 14:28
Struts+Spring+Hibernate开发实例一 介绍本文并不想介绍Struts,Spring,Hibernate的原理系统架构等,本文地目的是通过一个较复杂地实例介绍如何整合Struts,Spring,Hibernate,网上现有的例子虽然也能达到目的,但功能都比较单一,复杂的例子时会有意想不到的麻烦。本文对读者假设已经具备了以上框架的基础知识。以及那些已经了解Struts,Spring,Hibernate的基本概念,但是还没有亲身在较复杂的项目中体验Struts+Spring+Hibernate的开发人员。 1 Struts 虽然不打算过多介绍Struts的原理,但是大概介绍一下还是有必要的。Struts本身就是 MVC 在这里负责将用户数据传人业务层,以及 将业务层处理的结果返回给用户,此系统属于较简单WEB应用,采用了OpenSessionInView模式处理LazyLoad问题,这样我们可以在用户视图中使用 get,set方法来方便地获取关联对象。为了处理庞大的Action和ActionForm问题,在此我门准备使用DynaActionForm (DynaValidatorForm)和DispatchAction以及 动态验证框架 来解决。及使用Tile来解决框架问题 。使用自定义标签处理分页和身份验证问题。 2 Spring Spring Framework最得以出名的是与Hibernate的无缝链接,虽然Spring 对Hibernate提供了90%以上的封装,使我们不必去关心Session 的建立,关闭,以及事务使我们能够专心的关注业务逻辑。但是一些特殊情况如 有时需要Query以及Criteria 对象,分页等,Spring不能给我们提供支持,总不能每次都在你的DAO上写个HibernateCallBackup()吧?Spring的作用不是把Hibernate再封装一层,而是让你接触不到Hibernate的API,而是帮助你管理好Session和Transaction。 在这里解决方法是:首先 写一个IBase 的接口,和一个BaseDao的实现。在实现中仿照HibernateTemplate,将其功能一一实现,同时考虑到Spring 未能支持的地方,我们不得已只好自己来管理Session,因此加入public Session openSession(),public Query getQuery(String sql),public Criteria getCriteria(Class clazz),以及分页的方法。 然后为每一个Entity 都建立继承于以上类的IEntity,与EntityDao。这里可以根据需求对Entity加入特殊的方法实现,如 在 StudentsDao.java 中加入类似用户身份验证等。以上就是数据访问层。接下来在Service层中通过对dao的引用完成业务逻辑方法。在下面的例子中我们分别为学生模块,教师模块,管理员模块构建Service层,StudentsServiceImpl,TeachersServiceImpl,AdminServiceImpl。 3 Hibernate 有了Spring的封装,我们要对Hibernate做的就是正确实现对象关系的映射。由于此处处于系统的最底层,准确无误的实现对象之间的关联关系映射将起着至关重要的作用。 总之,理解了Struts,Spring,Hibernate地原理以及之间的关系之后,剩下的工作就如同在以Spring为核心的Struts为表现的框架中堆积木。 二 案例简述: 设计思路主要源于 大学选修课,该系统可以方便处理学生在课程选报,学分查询,成绩查询,以及 成绩发布等。 系统以班级为核心,一门课程可以对应多个班级,一名教师也可以带不同的班级,学生可以选报不同课程所对应的班级,班级自身有目前人数,和最大人数,以及上课时间,上课地点的属性。 学生在选报班级之后,班级的人数会自动加一,直到等于最大人数时,其他学生将会有人数已满的错误提示。同理如果学生选择了同一课程的不同班级,也将收到错误提示。学生有密码,系别,学分,地址,电话等属性。 教师在系统中主要负责成绩发布,教师可以对其所带的班级的学生的成绩修改,系统会以成绩是否大于等于60来判断学生是否通过考试,如果通过会将该课程的学分累加到学生学分,同样如果教师二次修改了成绩,而且小于60,系统会在学生学分上扣掉该课程的分数。 课程在系统中具体体现为班级,自身带有学分属性。 系有编号,名称的属性,同时可以作为联系教师,课程,学生的桥梁。 功能模块 l 身份验证模块: 根据用户名,密码,用户类别 转发用户到不同的模块。 l 学生模块: 查看课程,查看班级,选报课程,查看己选课程,成绩查询。 l 教师模块: 录入成绩 l 管理员模块:对学生,教师,课程,班级,系 增,删,查,改。 三 具体实践 代码下载 首先,将库表映射为数据模型(SQL在源码中查看),转换后的数据模型如下图: 由此我们可以看出一下关联关系: 1 Students 和 Contact(联系方式)一对一关系。 2 Students 和 History(选课历史) 一对多关系 3 Students 和 Classes 多对多关系。 4 Classes 和 Classes_info 一对多关系。 5 Classes 和 Teachers 多对一关系。 6 Classes 和 Courses 多对一关系。 7 Course 和 Department(系) 多对一关系。 8 Teachers 和 Department 多对一关系。 9 Students 和 Department 多对一关系。
在Hibernate中将以上关系一一映射,如Students 和 History 一对多关系 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 < SPAN>set> 10 同样在History.cfg.xml中加入: 1 <many-to-one name="student" 2 class="limq.hibernate.vo.Students" 3 column="student_id" > 4 < SPAN>many-to-one> 5 用过MyEclipse开发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 以及对应的get,set 方法,History.java 中加入 private Students student; public Students getStudent() { return student; }
public void setStudent(Students student) { this.student = student; } 具体内容请查看 源代码。 2 DAO 数据访问层 首先,编写IBaseDao与BaseDao,其中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 实现以上的 定义的方法 如: 1 public void create(Object entity) { 2 try { 3 getHibernateTemplate().save(entity); 4 5 } catch (Exception e) { 6 log.error("保存 " + entity.getClass().getName() + " 实例到数据库失败", 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 可以看到,这里即充分利用了Spring对Hibernate的支持,还弥补了Spring的不足。最后分别为每个持久对象建立Interface,以及DAO,使其分别继承IBaseDao与BaseDao。 如IDepartment,DepartmentDao 1 public interface IDepartment extends IBaseDao {} 2 3 public class DepartmentDao extends BaseDao implements IBaseDao {} 4
3 Service 层 在这里需要认真思考每个业务逻辑所能用到的持久层对象和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.Driver< SPAN>value> 8 < SPAN>property> 9 <property name="url"> 10 <value>jdbc:mysql://localhost:3306/Student< SPAN>value> 11 < SPAN>property> 12 <property name="username"> 13 <value>root< SPAN>value> 14 < SPAN>property> 15 <property name="password"> 16 <value>< SPAN>value> 17 < SPAN>property> 18 < SPAN>bean> 19 <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> 20 <property name="dataSource"> 21 <ref local="dataSource"/> 22 < SPAN>property> 23 <property name="mappingResources"> 24 <list> 25 <value>limq/hibernate/vo/Admins.hbm.xml< SPAN>value> 26 <value>limq/hibernate/vo/Classes.hbm.xml< SPAN>value> 27 <value>limq/hibernate/vo/Courses.hbm.xml< SPAN>value> 28 <value>limq/hibernate/vo/Students.hbm.xml< SPAN>value> 29 <value>limq/hibernate/vo/ClassesInfo.hbm.xml< SPAN>value> 30 <value>limq/hibernate/vo/Contact.hbm.xml< SPAN>value> 31 <value>limq/hibernate/vo/Department.hbm.xml< SPAN>value> 32 <value>limq/hibernate/vo/History.hbm.xml< SPAN>value> 33 <value>limq/hibernate/vo/Teachers.hbm.xml< SPAN>value> 34 < SPAN>list> 35 < SPAN>property> 36 <property name="hibernateProperties"> 37 <props> 38 <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect< SPAN>prop> 39 <prop key="hibernate.show_sql">true< SPAN>prop> 40 < SPAN>props> 41 < SPAN>property> 42 < SPAN>bean> 43 <bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> 44 <property name="sessionFactory"> 45 <ref local="sessionFactory"/> 46 < SPAN>property> 47 < SPAN>bean> 48 49 <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor"> 50 <property name="sessionFactory"> 51 <ref bean="sessionFactory"/> 52 < SPAN>property> 53 < SPAN>bean> 54 <bean id="studentDaoTarget" class="limq.hibernate.dao.StudentsDao"> 55 <property name="sessionFactory"> 56 <ref bean="sessionFactory"/> 57 < SPAN>property> 58 < SPAN>bean> 59 <bean id="teacherDaoTarget" class="limq.hibernate.dao.TeachersDao"> 60 <property name="sessionFactory"> 61 <ref bean="sessionFactory"/> 62 < SPAN>property> 63 < SPAN>bean> 64 <bean id="courseDaoTarget" class="limq.hibernate.dao.CoursesDao"> 65 <property name="sessionFactory"> 66 <ref bean="sessionFactory"/> 67 < SPAN>property> 68 < SPAN>bean> 69 <bean id="classDaoTarget" class="limq.hibernate.dao.ClassesDao"> 70 <property name="sessionFactory"> 71 <ref bean="sessionFactory"/> 72 < SPAN>property> 73 < SPAN>bean> 74 <bean id="departmentDaoTarget" class="limq.hibernate.dao.DepartmentDao"> 75 <property name="sessionFactory"> 76 <ref bean="sessionFactory"/> 77 < SPAN>property> 78 < SPAN>bean> 79 <bean id="adminDaoTarget" class="limq.hibernate.dao.AdminDao"> 80 <property name="sessionFactory"> 81 <ref bean="sessionFactory"/> 82 < SPAN>property> 83 < SPAN>bean> 84 <bean id="studentDao" class="org.springframework.aop.framework.ProxyFactoryBean"> 85 <property name="proxyInterfaces"> 86 <value>limq.hibernate.dao.IStudents< SPAN>value> 87 < SPAN>property> 88 <property name="interceptorNames"> 89 <list> 90 <value>hibernateInterceptor< SPAN>value> 91 <value>studentDaoTarget< SPAN>value> 92 < SPAN>list> 93 < SPAN>property> 94 < SPAN>bean> 95 <bean id="teacherDao" class="org.springframework.aop.framework.ProxyFactoryBean"> 96 <property name="proxyInterfaces"> 97 <value>limq.hibernate.dao.ITeachers< SPAN>value> 98 < SPAN>property> 99 <property name="interceptorNames"> 100 <list> 101 <value>hibernateInterceptor< SPAN>value> 102 <value>teacherDaoTarget< SPAN>value> 103 < SPAN>list> 104 < SPAN>property> 105 < SPAN>bean> 106 <bean id="courseDao" class="org.springframework.aop.framework.ProxyFactoryBean"> 107 <property name="proxyInterfaces"> 108 <value>limq.hibernate.dao.ICourses< SPAN>value> 109 < SPAN>property> 110 <property name="interceptorNames"> 111 <list> 112 <value>hibernateInterceptor< SPAN>value> 113 <value>courseDaoTarget< SPAN>value> 114 < SPAN>list> 115 < SPAN>property> 116 < SPAN>bean> 117 <bean id="classDao" class="org.springframework.aop.framework.ProxyFactoryBean"> 118 <property name="proxyInterfaces"> 119 <value>limq.hibernate.dao.IClasses< SPAN>value> 120 < SPAN>property> 121 <property name="interceptorNames"> 122 <list> 123 <value>hibernateInterceptor< SPAN>value> 124 <value>classDaoTarget< SPAN>value> 125 < SPAN>list> 126 < SPAN>property> 127 < SPAN>bean> 128 <bean id="departmentDao" class="org.springframework.aop.framework.ProxyFactoryBean"> 129 <property name="proxyInterfaces"> 130 <value>limq.hibernate.dao.IDepartment< SPAN>value> 131 < SPAN>property> 132 <property name="interceptorNames"> 133 <list> 134 <value>hibernateInterceptor< SPAN>value> 135 <value>departmentDaoTarget< SPAN>value> 136 < SPAN>list> 137 < SPAN>property> 138 < SPAN>bean> 139 <bean id="adminDao" class="org.springframework.aop.framework.ProxyFactoryBean"> 140 <property name="proxyInterfaces"> 141 <value>limq.hibernate.dao.IAdmin< SPAN>value> 142 < SPAN>property> 143 <property name="interceptorNames"> 144 <list> 145 <value>hibernateInterceptor< SPAN>value> 146 <value>adminDaoTarget< SPAN>value> 147 < SPAN>list> 148 < SPAN>property> 149 < SPAN>bean> 150 151 <bean id="studentManagerTarget" class="limq.spring.service.StudentsServiceImpl"> 152 <property name="studentsDao"> 153 <ref bean="studentDao"/> 154 < SPAN>property> 155 <property name="coursesDao"> 156 <ref bean="courseDao"/> 157 < SPAN>property> 158 <property name="classesDao"> 159 <ref bean="classDao"/> 160 < SPAN>property> 161 <property name="departmentsdao"> 162 <ref bean="departmentDao"/> 163 < SPAN>property> 164 < SPAN>bean> 165 <bean id="teacherManagerTarget" class="limq.spring.service.TeachersServiceImpl"> 166 <property name="teachersDao"> 167 <ref bean="teacherDao"/> 168 < SPAN>property> 169 <property name="coursesDao"> 170 <ref bean="courseDao"/> 171 < SPAN>property> 172 <property name="classesDao"> 173 <ref bean="classDao"/> 174 < SPAN>property> 175 <property name="studentsDao"> 176 <ref bean="studentDao"/> 177 < SPAN>property> 178 < SPAN>bean> 179 <bean id="adminManagerTarget" class="limq.spring.service.AdminServiceImpl"> 180 <property name="adminDao"> 181 <ref bean="adminDao"/> 182 < SPAN>property> 183 <property name="teachersDao"> 184 <ref bean="teacherDao"/> 185 < SPAN>property> 186 <property name="coursesDao"> 187 <ref bean="courseDao"/> 188 < SPAN>property> 189 <property name="classesDao"> 190 <ref bean="classDao"/> 191 < SPAN>property> 192 <property name="studentsDao"> 193 <ref bean="studentDao"/> 194 < SPAN>property> 195 <property name="departmentsdao"> 196 <ref bean="departmentDao"/> 197 < SPAN>property> 198 < SPAN>bean> 199 200 <bean id="studentManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 201 <property name="transactionManager"> 202 <ref bean="myTransactionManager"/> 203 < SPAN>property> 204 <property name="target"> 205 <ref bean="studentManagerTarget"/> 206 < SPAN>property> 207 <property name="transactionAttributes"> 208 <props> 209 <prop key="get*">PROPAGATION_SUPPORTS< SPAN>prop> 210 <prop key="*">PROPAGATION_REQUIRED< SPAN>prop> 211 < SPAN>props> 212 < SPAN>property> 213 < SPAN>bean> 214 <bean id="teacherManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 215 <property name="transactionManager"> 216 <ref bean="myTransactionManager"/> 217 < SPAN>property> 218 <property name="target"> 219 <ref bean="teacherManagerTarget"/> 220 < SPAN>property> 221 <property name="transactionAttributes"> 222 <props> 223 <prop key="get*">PROPAGATION_SUPPORTS< SPAN>prop> 224 <prop key="*">PROPAGATION_REQUIRED< SPAN>prop> 225 < SPAN>props> 226 < SPAN>property> 227 < SPAN>bean> 228 <bean id="adminManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 229 <property name="transactionManager"> 230 <ref bean="myTransactionManager"/> 231 < SPAN>property> 232 <property name="target"> 233 <ref bean="adminManagerTarget"/> 234 < SPAN>property> 235 <property name="transactionAttributes"> 236 <props> 237 <prop key="get*">PROPAGATION_SUPPORTS< SPAN>prop> 238 <prop key="*">PROPAGATION_REQUIRED< SPAN>prop> 239 < SPAN>props> 240 < SPAN>property> 241 < SPAN>bean> 242 < SPAN>beans> 243 以StudentsServiceImpl以为例,下图演示了如何利用Spring的Ioc与Hibernate的结合。 可以看到分别将studentDao,classDao,coursesDao,departmentDao,注入studentManager. 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 实现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 * 根据课程查找班级 121 * @param course 122 * 课程实体 123 * @return 返回该课程下所有班级 124 */ 125 public Classes[] getClassesFromCourse(Courses course) { 126 return coursesDao.getClassesFromCourse(course); 127 } 128 129 /** 130 * 根据主键查找系 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 * 根据主键查找课程 141 * @param id 142 * 主键ID 143 */ 144 public Courses getCourseFromID(Integer id) { 145 return (Courses) coursesDao.loadByKey(Courses.class, "id", id); 146 } 147 /** 148 * 根据主键查找班级 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 * 根据姓名查找学生 158 * @param name 159 */ 160 public Students getStudetFromName(String name) { 161 return (Students) studentsDao.loadByKey(Students.class, "name", name); 162 } 163 164 /** 165 * 检查学生是否选报了同一课程的班级 166 * @param clazz 167 * 所选报的班级 168 * @param stu 169 * 学生实体 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 * 检查课程的目前人数 192 * @param clazz 193 * 检查班级人数是否已满 194 * @param clazz 195 * 班级实体 196 * @return true 班级人数已满 197 * @return false 班级人数未满 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 * 数据库插入选择班级的记录 214 * @param stu 215 * 学生 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>contextConfigLocation< SPAN>param-name> 5 <param-value>/WEB-INF/classes/applications-service.xml< SPAN>param-value> 6 < SPAN>context-param> 7 <context-param> 8 <param-name>log4jConfigLocation< SPAN>param-name> 9 <param-value>/WEB-INF/log4j.properties< SPAN>param-value> 10 < SPAN>context-param> 11 <filter> 12 <filter-name>hibernateFilter< SPAN>filter-name> 13 <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter< SPAN>filter-class> 14 < SPAN>filter> 15 <filter-mapping> 16 <filter-name>hibernateFilter< SPAN>filter-name> 17 <url-pattern>/*< SPAN>url-pattern> 18 < SPAN>filter-mapping> 19 <filter> 20 <filter-name>Set Character Encoding< SPAN>filter-name> 21 <filter-class>limq.struts.SetCharacterEncodingFilter< SPAN>filter-class> 22 < SPAN>filter> 23 <filter-mapping> 24 <filter-name>Set Character Encoding< SPAN>filter-name> 25 <url-pattern>/*< SPAN>url-pattern> 26 < SPAN>filter-mapping> 27 <servlet> 28 <servlet-name>SpringContextServlet< SPAN>servlet-name> 29 <servlet-class>org.springframework.web.context.ContextLoaderServlet< SPAN>servlet-class> 30 <load-on-startup>1< SPAN>load-on-startup> 31 < SPAN>servlet> 32 <servlet> 33 <servlet-name>action< SPAN>servlet-name> 34 <servlet-class>org.apache.struts.action.ActionServlet< SPAN>servlet-class> 35 <init-param> 36 <param-name>config< SPAN>param-name> 37 <param-value>/WEB-INF/struts-config.xml< SPAN>param-value> 38 < SPAN>init-param> 39 <init-param> 40 <param-name>debug< SPAN>param-name> 41 <param-value>3< SPAN>param-value> 42 < SPAN>init-param> 43 <init-param> 44 <param-name>detail< SPAN>param-name> 45 <param-value>3< SPAN>param-value> 46 < SPAN>init-param> 47 <load-on-startup>0< SPAN>load-on-startup> 48 < SPAN>servlet> 49 <servlet-mapping> 50 <servlet-name>action< SPAN>servlet-name> 51 <url-pattern>*.do< SPAN>url-pattern> 52 < SPAN>servlet-mapping> 53 < SPAN>web-app> 54 55 其中注意这几句, 1 <filter> 2 <filter-name>hibernateFilter< SPAN>filter-name> 3 <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter< SPAN>filter-class> 4 < SPAN>filter> 5 <filter-mapping> 6 <filter-name>hibernateFilter< SPAN>filter-name> 7 <url-pattern>/*< SPAN>url-pattern> 8 < SPAN>filter-mapping> 9 由于我们使用了lazy = "true",如果想在UI层使用实体对象关联来获得其他对象时就会有这样的提示: org.hibernate.LazyInitializationException: failed to lazily initialize a collection Spring 中引入了 OpenSessionInView模式可以处理以上问题,即在web.xml中加入以上代码。 接下来建立抽象BaseAction,和 BaseDispatchAction,其中后者与前者相似目的为减少Action的数量 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都从这两个类继承。 以下就以查看课程下的班级为例演示Struts与Spring的使用: 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实例,利用Courses和Classes的关联关系得到Classes[],在将其放入 Request. 通过mapping.findForward("success"),转发到 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 为了验证用户操作权限,这里扩展了Struts 的RequestProcessor来判断Session如果Session和userName都不空则程序继续,否则重定向到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 呵呵,当然在正规使用时仅仅这样验证是不够的。欢迎你把自己修改方法告诉我。
4分页处理: 下面重点讨论一下Hibernate的分页处理方式。 Hibernate 中处理查询主要有 Query ,Criteria,分别以 HSQL或编程方式实现, 本例对这两种方法都有相关处理。由于在Spring中无法直接使用Query和Criteria对象 所以只有先从Spring那里借一个Session,等使用完了在还给Sping处理。读者应该还记得在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层以查询所有课程与学生选课记录为例处理Query与Criteria: 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 可以看到getCourse和getStudentHistory有很多相似之处,Hibernate为Query和Criteria提供了针对不同数据库的解决分页方法, Quey需要我们写HSQL, Criteria不但可以应付带有条件的查询,还不用我们自己写HSQL,PageInfo是含有分页信息的普通java类。 再看看Struts是如何调用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 //第一次发送请求 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中避免代码重复使用了自定义标志来处理分页 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"/>< SPAN>td> 17 <td><bean:message key="course.name"/>< SPAN>td> 18 <td><bean:message key="enrol.time"/>< SPAN>td> 19 <td><bean:message key="score"/>< SPAN>td> 20 <td><bean:message key="marking"/>< SPAN>td> 21 < SPAN>tr> 22 <% 23 for(int i=0;i<historys.length;i++){ 24 History his=historys[i]; 25 %> 26 <tr> 27 <td><%=his.getClasses().getId()%>< SPAN>td> 28 <td><%=his.getCourseName()%>< SPAN>td> 29 <td><%=his.getEnrolTime()%>< SPAN>td> 30 <td><%=his.getScore()%>< SPAN>td> 31 <td><%=his.getMarking()%>< SPAN>td> 32 < SPAN>tr> 33 <% 34 } 35 %> 36 < SPAN>table> 37 <mytag:page pageinfo="<%=pageinfo%>" action="getHistory.do"/> 38 < SPAN>body> 39 < SPAN>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(""); 66 67 } 68 69 } 70
1 数据库:MYSQL 4.1 (或以上版本)4.1直接支持Unicode,以下版本支持的不好。 2 驱动: MySQL JDBC Driver的 3 在数据库中做如下设定 4 在建立表时同样加上ENGINE=MyISAM DEFAULT CHARSET=gbk 1CREATE TABLE `students` ( 2 `id` int(20) NOT NULL default '0', 3 `name` varchar(20) NOT NULL default '', 4 `department_id` int(11) default NULL, 5 `password` varchar(20) default NULL, 6 `score` double(15,3) default NULL, 7 PRIMARY KEY (`id`) 8) ENGINE=MyISAM DEFAULT CHARSET=gbk 9 5 配置hibernate.cfg.xml 1 <property name="connection.url">jdbc:mysql://localhost:3306/Student< SPAN>property> 2 <property name="dialect">net.sf.hibernate.dialect.MySQLDialect< SPAN>property> 3 <property name="connection.password">< SPAN>property> 4 <property name="connection.driver_class">com.mysql.jdbc.Driver< SPAN>property> 5 robbin: MySQL JDBC Driver的 MySQL JDBC Driver 6 开发工具介绍 MyEclipse 3.8 首先添加用户库,如下图将Struts,Spring,Hibernate 的库添加到用户库中 如果出现环境问题可能你的Struts包有问题,请到http://struts.apache.org/download.cgi下载struts-1.2.7-lib.zip 。 具体使用参考http://www.laliluna.de/struts-hibernate-integration-tutorial-en.html 总结 本文至此已将Struts+Sprng+Hibernate的大致思路以及本人所遇到的难点,重点介绍完了。 其中管理员我只完成了对学生的部分,其他功能大同小异,有兴趣的读者不妨动手试试。最后建议初学者不要直接使用Spring对Hibernate的封装,而是从Hibernate学起,先要学会自己管理Session,Transaction,然后在用Spring,这样理解会更深刻。同时如果你有好的建议,或问题请联系我
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
公司公章在哪刻
刻公章多长时间
分公司有公章吗
增刻公章
刻公章的费用
刻公章需要什么材料
刻公章证明
开刻公章店
哪能刻公章
加刻公章
公章可以自己刻吗
公司公章可以刻几个
私人刻公章
公司刻章流程
刻制印章申请
手刻印章
刻印章教程
学刻印章
自刻印章
刻印章制作
纂刻印章图片
仿刻印章
专业刻印章
末世崛起之刻刻帝
在线刻印
哪里能刻印章
哪有刻印章的
如何刻印章
手工刻印章多少钱
脐带刻印章
刻印章多钱
刻印章电话
刻印章用什么料好
刻印章教学
刻印章的地方
新刻印章
刻印章设备
刻印章什么石头好
刻印章证明
橡皮印章
刻公章在什么地方
|