SSH整合例子

时间:2022-02-06 15:30:38

三大框架:

Struts框架

1. params拦截器: 请求数据封装

2. 类型转换/数据处理

3. struts配置

4. 文件上传/下载/国际化处理

5. 数据效验/拦截器

6. Ognl表达式

7. 数据回显/模型驱动/防止表单重复提交

Hibernate框架

1. Api简介

2. 映射

多对一/一对多:   部门与员工

多对多/一对一

集合映射/组件映射/继承映射

3. Hibernate 缓存

4. 常用属性:inverse/lazy/cascade

5. 对象状态:临时/持久/游离

Spring框架

1) Spring IOC容器 【Inversion Of Control,即控制反转】

创建对象/处理对象依赖关系

2) Aop编程

3) Spring声明式事务管理

4) 框架整合

Spring与Struts

Spring与Hibernate

5)Spring对jdbc、hibernate操作的封装

JdbcTemplate (dataSource)/ HibernateTemplate(SessionFactory)

目标:

案例 【软件项目声明周期】

1. 需求分析

系统概述:

企业人事管理系统!

要求对员工信息进行维护;

后台系统先登陆,才能操作员工: 添加/修改/删除

没有登陆,只能查看列表,不能操作!

功能分类:

【管理员模块:】

注册/登陆

【员工模块】

1) 添加一个员工, 指定添加的部门

2) 对指定的员工信息修改

3) 删除选择员工

4)列表展示

2. 设计

2.1 系统设计

【系统架构师/技术经理】

主要做下面的事情,

1)
搭建系统框架结构

(基于mvc结构应用)

2)
确定项目的关键点/难点

3)
确定引用组件、公用类的版本

Struts2.3

Hibernate3.6

Spring3.2

2.2 数据库设计

管理员表:
t_admin

员工表:   t_employee

部门:     t_dept

3. 代码

步骤分析

编码顺序:

1)
设计数据库:  hib_demo

    建表: t_admin/t_employee/t_dept

2)
建立web项目、引入jar文件、准备环境

…..

3)
设计javabean、写映射

Admin.java   封装管理员

Employee.java  员工

Dept.java      部门

Admin.hbm.xml

Employee.hbm.xml

Dept.hbm.xml

4)
Dao设计接口

IAdminDao.java   
管理员模块

void  save(Admin admin);

Admin
findByAdmin(Admin  admin);

IDeptDao.java     
部门模块

List<Dept>
getAll();

Dept  findById(int 
id);

IEmployeeDao.java  
员工模块

Void  save(Employee  emp);

Void  update(Employee  emp);

Void  delete(int id);

Employee  findById(int id);

List<Employee>
getAll();

List<Employee>
getAll(String  employeeName);

5)
Dao接口实现

6)Service接口设计

IAdminService.java    管理员模块

void  register(Admin admin);

Admin
 login(Admin  admin);

7)Service接口实现

8)
Action实现

EmployeeAction.java   员工模块

AdminAction.java              管理员模块

9)jsp页面

Index.jsp/list.jsp  首页列表

http://localhost:8080/项目    首页列表

优化部分:

10)
用户登陆拦截器

UserInterceptor.java   检查是否登陆

只有登陆才能操作; 否则只能查看

11)
Dao 操作优化

BaseDao.java   所有dao的通用方法,dao都必须继承此类

(用到反射泛型)

实现步骤代码:

1) 设计数据库:  hib_demo 

CREATE TABLE t_admin(
  id INT PRIMARY KEY AUTO_INCREMENT,
  adminName  VARCHAR(),
  pwd   VARCHAR()
)
表: t_dept/ t_employee

2) 建立web项目、引入jar文件、准备环境

【struts相关jar】
commons-fileupload-.jar
commons-io-.jar
commons-lang3-3.1.jar
freemarker-.jar
javassist-.GA.jar
ognl-.jar
struts2-core-2.3.4.1.jar
xwork-core-2.3.4.1.jar

【hibernate 相关 jar】
antlr-.jar
commons-collections-3.1.jar
dom4j-.jar
hibernate3.jar
hibernate-jpa-.Final.jar
javassist-.GA.jar
jta-1.1.jar
slf4j-api-.jar

【Spring-core】
commons-logging-.jar
spring-beans-.RELEASE.jar
spring-context-.RELEASE.jar
spring-core-.RELEASE.jar
spring-expression-.RELEASE.jar

【Spring-web】
spring-web-.RELEASE.jar
struts2-spring-plugin-2.3.4.1.jar

【Spring-Aop】
aopalliance.jar
aspectjrt.jar
aspectjweaver.jar
spring-aop-.RELEASE.jar

【Spring-orm】
c3p0-0.9.1.2.jar
mysql-connector-java--bin.jar
spring-orm-.RELEASE.jar
spring-tx-.RELEASE.jar
spring-jdbc-.RELEASE.jar

3) 设计javabean、写映射

public class Admin {
    private int id;
    private String adminName;
    private String pwd;
}

Admin.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.entity">

    <class name="Admin" table="t_admin">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="adminName" length="20"></property>
        <property name="pwd" length="20"></property>
    </class>

</hibernate-mapping>
public class Dept {
    private int id;
    private String name;
}

Dept.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.entity">

    <class name="Dept" table="t_dept">
        <id name="id" column="deptId">
            <generator class="native"></generator>
        </id>
        <property name="name" column="deptName"></property>
    </class>

</hibernate-mapping>
public class Employee {
    private int id;
    private String empName;
    private double salary;
    private Dept dept;  

Employee.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.entity">

    <class name="Employee" table="t_employee">
        <id name="id" column="empId">
            <generator class="native"></generator>
        </id>
        <property name="empName"></property>
        <property name="salary"></property>
        <!-- 多对一 -->
        <many-to-one name="dept" column="dept_id" class="Dept" lazy="false"></many-to-one>
    </class>

</hibernate-mapping>

4) Dao接口设计

/**
 * 管理员模块dao接口
 */
public interface IAdminDao {
    //保存
    void save(Admin admin);
    //根据管理员信息查询
    Admin findByAdmin(Admin admin);
}
/**
 * 部门模块dao接口设计
 */
public interface IDeptDao {
    // 查询全部
    List<Dept> getAll();
    //根据主键查询
    Dept findById(int id);
}
/**
 * 员工模块dao接口设计
 */
public interface IEmployeeDao {
    //保存员工
    void save(Employee emp);
    // 更新员工信息
    void update(Employee emp);
    //根据主键删除
    void delete(int id);
    //根据主键查询
    Employee findById(int id);
    //查询全部
    List<Employee> getAll();
    //根据员工名称条件查询
    List<Employee> getAll(String employeeName);
}

5) Dao接口实现

public class AdminDao implements IAdminDao {

    // IOC容器(依赖)注入SessionFactory对象
    private SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public Admin findByAdmin(Admin admin) {
        return (Admin) sessionFactory.getCurrentSession()//
                .createQuery("from Admin where adminName=? and pwd=?")//
                .setString(, admin.getAdminName())//
                .setString(, admin.getPwd())//
                .uniqueResult();
    }

    @Override
    public void save(Admin admin) {
        sessionFactory.getCurrentSession().save(admin);
    }

}
public class DeptDao implements IDeptDao {

    // 容器注入
    private SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public Dept findById(int id) {
        return (Dept) sessionFactory.getCurrentSession().get(Dept.class, id);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Dept> getAll() {
        return sessionFactory.getCurrentSession().createQuery("from Dept").list();
    }

}
public class EmployeeDao implements IEmployeeDao {

    // 容器注入
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public void delete(int id) {
        // HQL查询区分大小写: 对象/对象属性严格区分大小写
        // 数据库关键字不区分
        sessionFactory.getCurrentSession()//
                .createQuery("delete from Employee where id=?")//
                .setParameter(, id)//
                .executeUpdate();
    }

    @Override
    public Employee findById(int id) {
        return (Employee) sessionFactory.getCurrentSession().get(Employee.class, id);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Employee> getAll() {
        return sessionFactory.getCurrentSession().createQuery("from Employee").list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Employee> getAll(String employeeName) {
        return sessionFactory.getCurrentSession()//
            .createQuery("from Employee where empName like ?")//
            .setParameter(, "%" +employeeName + "%")//
            .list();
    }

    @Override
    public void save(Employee emp) {
        sessionFactory.getCurrentSession().save(emp);
    }

    @Override
    public void update(Employee emp) {
        sessionFactory.getCurrentSession().update(emp);
    }

}

6) Service接口设计

。。。

7) Service接口实现

。。。

8) Action实现

/**
 * 员工模块控制器开发:
 * 1. 员工列表展示
 * 2. 添加员工
 * 3. 修改员工信息
 * 5. 删除
 */
public class EmployeeAction extends ActionSupport implements ModelDriven<Employee>, RequestAware{

    /*******一、封装数据********/
    private Employee employee = new Employee();   // 【模型驱动】
    // 封装请求的部门id(下拉列表的实际的值)
    private int deptId;
    public void setEmployee(Employee employee) {
        this.employee = employee;
    }
    public Employee getEmployee() {
        return employee;
    }
    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }
    public int getDeptId() {
        return deptId;
    }

    @Override
    public Employee getModel() {
        return employee;   // 返回实例化后的对象
    }

    /*******二、注入员工Service********/
    private IEmployeeService employeeService;
    public void setEmployeeService(IEmployeeService employeeService) {
        this.employeeService = employeeService;
    }
    // 部门Service
    private IDeptService deptService;
    public void setDeptService(IDeptService deptService) {
        this.deptService = deptService;
    }

    /**
     * 1. 员工列表展示
     */
    public String list() {
        // 查询所有员工
        List<Employee> listEmp = employeeService.getAll();
        // 保存到request
        request.put("listEmp", listEmp);
        return "list";
    }

    /**
     * 2. 添加员工 - 进入添加页面
     */
    public String viewAdd(){
        // 查询所有部门信息, 保存到request
        List<Dept> listDept = deptService.getAll();
        request.put("listDept", listDept);
        return "add";
    }

    /**
     * 2. 添加员工 - 添加员工数据
     */
    public String save(){

        // 先根据部门主键查询
        Dept dept = deptService.findById(deptId);
        // 设置到员工对象中
        employee.setDept(dept);

        // 调用Service,保存员工
        employeeService.save(employee);
        return "listAction";  // 重定向到Action
    }

    /**
     *  3. 修改员工信息 - 进入修改视图
     */
    public String viewUpdate(){
        // 获取要修改的记录的id
        int id = employee.getId();

        // 1. 根据员工的主键查询  (lazy="false")
        Employee emp = employeeService.findById(id);  // 已经有部门信息
        // 2. 查询所有的部门
        List<Dept> listDept =  deptService.getAll();

        // 数据回显
        ValueStack vs = ActionContext.getContext().getValueStack();
        vs.pop();// 移除栈顶元素
        vs.push(emp); // 入栈

        // 保存
        request.put("listDept", listDept);

        return "edit";
    }

    /**
     *  4. 修改员工信息 - 确认修改
     */
    public String update() {

        //1. 先根据部门id, 查询部门对象; 再设置到员工属性中
        Dept dept = deptService.findById(deptId);
        employee.setDept(dept);

        //2. 更新员工
        employeeService.update(employee);

        return "listAction";  // 重定向到列表
    }

    /**
     *  5. 修改员工信息 - 删除
     */
    public String delete(){
        // 获取要删除员工的主键
        int empId = employee.getId();
        // 调用service删除
        employeeService.delete(empId);
        return "listAction";
    }

    // 接收框架运行时候传入的代表request对象的map
    private Map<String, Object> request;
    @Override
    public void setRequest(Map<String, Object> request) {
        this.request = request;
    }
}

=================================配置文件==========================

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- struts2配置 -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Spring配置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:bean.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <package name="emp" extends="struts-default">

        <!-- 全局视图 -->
        <global-results>
            <result name="success">/index.jsp</result>

            <!-- 错误视图配置 -->
            <result name="null">/error/null.jsp</result>
            <result name="error">/error/error.jsp</result>
        </global-results>

        <!-- 全局异常 -->
        <global-exception-mappings>
            <!-- result 会取找全局视图的名称 -->
            <exception-mapping result="null" exception="java.lang.NullPointerException"></exception-mapping>
            <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
        </global-exception-mappings>

        <!-- Ation实例交给spring容器创建 -->
        <action name="emp_*" class="employeeAction" method="{1}">

            <!-- 列表展示 -->
            <result name="list">/WEB-INF/list.jsp</result>

            <!-- 进入添加页面视图 -->
            <result name="add">/WEB-INF/add.jsp</result>

            <!-- 添加成功,进入列表 (防止刷新就多一条记录问题,所以用重定向) -->
            <result name="listAction" type="redirectAction">emp_list</result>

            <!-- 进入修改页面 -->
            <result name="edit">/WEB-INF/edit.jsp</result>

        </action>
    </package>

</struts>

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 引入其他配置文件 -->
    <import resource="config/bean-base.xml"/>
    <import resource="config/bean-dao.xml"/>
    <import resource="config/bean-service.xml"/>
    <import resource="config/bean-action.xml"/>
</beans>  

bean-base.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 1. 连接池实例 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hib_demo"></property>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
        <property name="initialPoolSize" value="3"></property>
        <property name="maxPoolSize" value="6"></property>
    </bean>

    <!-- 2. Spring管理SessionFactory 【全部配置都写到spring中】 -->
    <!-- # 注入DataSource、 注入常用配置属性、映射配置属性 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                 <prop key="hibernate.show_sql">true</prop>
                 <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <property name="mappingLocations">
            <list>
                <value>classpath:cn/itcast/entity/*.hbm.xml</value>
            </list>
        </property>
    </bean>

    <!-- 3. 事务相关配置 -->
    <!-- 3.1 事务管理器类 -->
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <!-- 3.2 事务增强(如何管理事务)-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" read-only="false"/>
        </tx:attributes>
    </tx:advice>

    <!-- 3.3 Aop配置 = 切入点表达式(拦截目标对象,生成代理)  + 事务增强应用-->
    <aop:config>
        <aop:pointcut expression="execution(* cn.itcast.service.impl.*.*(..))" id="pt"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
    </aop:config>
</beans>     

bean-dao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- Dao 注入 SessionFactory -->

    <bean id="adminDao" class="cn.itcast.dao.impl.AdminDao">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <bean id="deptDao" class="cn.itcast.dao.impl.DeptDao">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <bean id="employeeDao" class="cn.itcast.dao.impl.EmployeeDao">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
</beans>     

bean-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- Service 需要注入 Dao -->

    <bean id="adminService" class="cn.itcast.service.impl.AdminService">
        <property name="adminDao" ref="adminDao"></property>
    </bean>

    <bean id="deptService" class="cn.itcast.service.impl.DeptService">
         <property name="deptDao" ref="deptDao"></property>
    </bean>

    <bean id="employeeService" class="cn.itcast.service.impl.EmployeeService">
        <property name="employeeDao" ref="employeeDao"></property>
    </bean>
</beans>     

bean-action.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- Action中需要注入Service -->

    <!-- 1. 员工管理模块 -->
    <bean id="employeeAction" class="cn.itcast.action.EmployeeAction">
        <property name="employeeService" ref="employeeService"></property>
        <property name="deptService" ref="deptService"></property>
    </bean>
</beans>