本系统包括了两个功能模块,分别是部门管理和员工管理两个功能模块。
通过这次的SSH管理系统让我更深一步的了解了这三大框架。
在做这个系统之前呢,老师出了一篇《基于SSH实现员工管理系统之框架整合篇》,如果有基础不明白的地方可以参考(视频里讲的很详细),下面就开始介绍与总结了....
注释
:下面介绍的内容括号中的基本是属性
或者含义
。
若有错误,望指正!~
一、界面展示
................................................走起.............................................
.........................................图1.登录的主界面...................................
.........................................图2.登录验证界面...................................
.........................................图3.登录后主界面...................................
.........................................图4.部门管理界面...................................
.........................................图5.部门编辑界面...................................
.........................................图6.部门添加界面...................................
.........................................图7.员工管理界面...................................
.........................................图8.员工编辑界面...................................
这以上都是视图层的界面,是通过html转换成jsp而来,界面是在老师的用意下精简了不少的,没有一些华丽的东西,主要是为了实现主要功能的。
二、
实践总结:
本系统使用的是SSH三大框架更好的体现出了MVC分层
的一个思想,这个mvc学到现在我想也不必多说了,代码分工明确
,让我想到了软工学到的一句话“高内聚,低耦合....
”,系统中的包有domain(实体),dao(与数据库互动,此处是指hibernate
框架),service(实体类的业务逻辑接口),action(跳转)。
①准备工作:需求分析,这是无论拿到什么项目都应该先做的事情,你需要知道从何入手,既然用到三大框架,那么第一件事情该做的就是引入框架所需的jar包(这里没用maven去实现依赖引入,会maven的同学也可以用maven,毕竟方便许多
,jar包是和老师上一篇所用的jar包的一样直接导入到lib下即可),接下来就是创建实体和对应的映射文件。先说实体,先创建的实体是部门(部门id(did)
,部门名字(dname)
,部门描述(ddes)
,员工集合(Employees)
),这里我想说一下建立员工集合这点,代码如下:
//员工的集合
private Set<Employee> Employees = new HashSet<Employee>() ;
//为什么这里用到的是Set<Employee>而不是
HashSet <Employee> Employees = new HashSet<Employee>() ;
//解释一下这里,因为我回答猿问的过程中发现有人写hashset集合的时候这么干。。。结果导致hibernate直接报内部错误
//其实理由很简单的啊TAT:set是接口,不能实例化,所以不能有Set s = new Set();只能实例化接口的实现类,比如HashSet。。还有ArrayList也是一个道理。。
员工(员工id(eid),员工名字(ename),性别(sex),生日(birthday)......,所属部门),这里也是员工对应的所属部门代码如下:
//所属的部门,直接私有化把Department引入即可
private Department department;
配置映射文件:这次的hibernate配置我们并没有配置hibernate.cfg.xml,因为采用的是整合,直接把hibernate交给spring去管理,在spring的配置文件中去注入,代码如下:
<!-- 配置hibernate的相关属性 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 配置hibernate的属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 加载hibernate中的映射文件 -->
<property name="mappingResources">
<list>
<value>com/imooc/employee/domain/Department.hbm.xml</value>
<value>com/imooc/employee/domain/Employee.hbm.xml</value>
</list>
</property>
</bean>
直接把sessionFactory交给Spring来管理,其中加载映射文件即可。至此,完成第一部分。
②员工管理登录模块:从这里开始就体现出了MVC的思想,可谓是一环扣一环,环环相扣啊,在Action中创建出登录的执行方法,此方法调用业务层的类(这还得调用业务层的实现类,因为业务层是接口
),然后又从业务层调用DAO层类的方法(这里和业务层同理
),最后在DAO层的实现类里去编写底层代码,代码如下:
//这是通过调用了hibernate的模板实现了查找用户名和密码,并且返回
String hql = "from Employee where username = ? and password = ?";
List<Employee> list = this.getHibernateTemplate().find(hql, employee.getUsername(),employee.getPassword());
if(list.size()>0){
return list.get(0);
}
//要问我hibernate模板从哪里来,那么这个员工接口的实现类当然必
须继承HibernateDaoSupport啦。。
验证方法的代码:
//调用业务层的类,这里用到了Struts2的配置跳转返回的字符串是INPUT
Employee existEmployee = employeeService.login(employee);
if(existEmployee == null){
//用户名不存在
this.addActionError("您输入的用户名或者密码错误!");
return INPUT;
}
第二部分完。
③员工管理和部门管理:这部分和登录的思想是一样的都是一环扣一环的,通过Action调用Service的实现类,在调用Dao的实现类,也就是说根据业务需求,像数据库的增删改查都在Dao的实现类层去写
,而且简单的语句利用了hibernate的模板非常容易解决,比如下面这种代码:
//DAO中保存员工的方法
@Override
public void save(Employee employee) {
this.getHibernateTemplate().save(employee);
}
//就是一句话的事儿!
说白了重要的还是整个调用的思想,脑海中要有一个流程图。。。具体实现方法跟着老师走肯定没有问题的。我在这里就不多说了,下面说重点。
三、
项目中遇到的问题:
问题永远是重点
(--------------我,说的。。。(开个玩笑
))
1.关于hibernate中关系映射的问题
①关系映射分两种,一种是一对多,一种是多对一,像本系统中,两个实体相互都对应了,一个部门对应了多个员工,多个员工呢,对应了一个部门,那么问题来了。。。在最后的级联修改方法中,我修改部门名称,那么部门所对应的员工信息会被修改吗?
(这里有点绕,举个桃子,栗子太小了
,比如有个部门是研发部,而张三,李四,王五都是这个部的,那我在部门管理中修改了这个部门名字叫研发部123,对应的员工管理信息中的这三个人的信息也会随之修改吗?)
答案是否定的。。。。为什么?因为在两个映射配置文件中相互关联了,必须有一段放弃维护权才可以,比如在部门里的映射文件中,让它放弃一对多这个能力,才能在修改的时候关联修改,那么代码如下:
<!-- 关联关系映射 -->inverse就是是否放弃维护权的变量名
<set name="employees" cascade="delete" inverse="true">
<key column="dno"/>
<one-to-many class="com.imooc.employee.domain.Employee"/>
</set>
②级联删除
想级联删除必须要先查询再删除,否则删不了,代码如下:
//删除部门的执行方法
public String delete(){
department = departmentService.findById(department.getDid());
departmentService.delete(department);
return "deleteSuccess";
}
2.Action类中继承的模型驱动与自己手动创建的list集合问题
这里employee这个模型驱动本来就在栈中,所以不用手动保存
,而你创建的list是需要手动保存到栈中去的
,代码如下:
//查询所有的部门,将你创建的list保存到栈中
List<Department> list = departmentService.findAll();
ActionContext.getContext().getValueStack().set("list", list);
return "editSuccess";
3.关于JSP中struts2的标签库
在JSP中,既然你用到了SSH框架,就需要用Struts2所提供的S标签,用了这个才能将你页面上的东西传进去,敲代码的时候我的一个低级错误就是有一个文本框没用s标签,结果通过数据库显示在web页面上的时候死活没有回显数据,就这一个小小的马虎点浪费了我好长时间来找错。。既然说到回显,不得不说一下下面这个式子:
value="%{model.ename}"等...//这个是设置回显,直接让
你在数据库中有的值在页面上显示,然后password是默认不会显的
<s:textfield name="dname" value="%{model.dname}" />
4.登录安全问题
这点也是老师最后视频中说的,就是说如果我在地址栏直接输入后端的访问地址,跳过登录界面,也是能进去的,这点需要拦截器发挥作用。。。我研究了下struts2的拦截器,结果代码写出来把正确的用户名登录也拦截了。。可能还是哪里有问题,慢慢在研究下吧。。
四、
SSH总结:
①首先SSH架构:domain层就是对应的数据库表的实体类。Dao层是使用了Hibernate连接数据库、操作数据库(增删改查)。Service层:引用对应的Dao数据库操作,在这里可以编写自己需要的代码(比如简单的判断)。Action层:引用对应的Service层,在这里结合Struts2的配置文件,跳转到指定的页面,当然也能接受页面传递的请求数据,也可以做些计算处理。以上的Hibernate,Struts2,都需要注入到Spring的配置文件中,Spring把这些联系起来,成为一个整体。
②Hibernate优点,缺点
(1) 对象/关系数据库映射(ORM)
它使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的思想,完全的面向对象思想。
(2) 它没有侵入性,即所谓的轻量级框架。
(3) 简洁的HQL编程(底层的select查询语句非常简洁)。
Hibernate缺点:
(1) Hibernate的弱势就在于批量处理。
(2) 对单一对象简单的增删查改,适合于Hibernate,而对于批量的修改,删除,不适合用Hibernate,这也是OR框架的弱点;要使用数据库的特定优化机制的时候,不适合用(这条我很赞同,这条是参考网上的)。
③Struts2优点:
(1)具有丰富的Tag可以用,Struts的标签库,如能灵活运用,能大大提高开发效率。
(2)实现MVC模式,结构清晰,是开发者只关注业务逻辑的实现。
(3)面向切面编程的思想在Strut2中也有了很好的体现。最重要的体现就是拦截器的使用。拦截器就是一个一个的小功能单位,用户可以将这些拦截器合并成一个大的拦截器,这个合成的拦截器就像单独的拦截器一样,只要将它配置到一个、Action中就可以。
④Spring:
在SSH框假中spring充当了管理容器的角色。
(1)Spring的Ioc(控制反转和依赖注入)
控制反转:就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。
依赖注入:组件之间的依赖关系由容器在运行期决定 ,由容器动态的将某种依赖关系注入到组件之中。
(2)Spring容器控制所有Action对象和业务逻辑类的生命周期,由与上层不再控制下层的生命周期,层与层之间实现了完全脱耦,使程序运行起来效率更高,维护起来也方便。
(3)使用Spring的第二个好处(AOP应用):
事务
的处理:Spring容器集成了TransactionTemplate
(在xml文件中配置到了事务模板),它封装了所有对事务处理的功能,包括异常时事务回滚,操作成功时数据提交等复杂业务功能。这都是由Spring容器来管理,大大减少了程序员的代码量,也对事务有了很好的管理控制。而Spring对SessionFactory配置也进行了整合,不需要在通过hibernate.cfg.xml来对SessionaFactory进行设定(就像我前面所说
)。这样的话就可以很好的利用Sping对事务管理强大功能。避免了每次对数据操作都要现获得Session实例来启动事务/提交/回滚事务还有繁琐的Try/Catch操作。这些也就是Spring中的AOP(面向切面编程)机制很好的应用。一方面使开发业务逻辑更清晰、专业分工更加容易进行。另一方面就是应用Spirng AOP隔离降低了程序的耦合性使我们可以在不同的应用中将各个切面结合起来使用大大提高了代码重用度
。
以上就是我本次的收获与总结,希望在下次的项目中继续进步成长。。
最后个人感觉:
再有基础知识的前提上,个人认为做项目是学习进步最快的方式。。因为一个项目是可以把很全的知识点全部概括进来的。
最后的最后来条格言:
`真正的才智是刚毅的志向。!!!` —— 拿破仑
------------------------------time_is_everything
----------------------------
共同学习,写下你的评论
评论加载中...
作者其他优质文章