首页   >   代码编程

SSH框架基础整合搭建图文教程

SSH框架(struts + spring + hibernate),在spring没有出现之前用的非常多,最近整理以前的笔记,看到很早之前写的三大框架案例,重新整理了一下,来写一篇SSH框架的基础搭建教程,方便自己回忆,也帮助刚入行的新人们学习,由于是很早的笔记,框架的版本也稍微落后了一些,但是一些核心的理念还是没怎么变化,这里就懒得升级版本了。

数据库表见resources目录下的wolff.sql文件,项目结构也很简单,传统的MVC模式,struts充当控制器,spring负责容器的管理和事务托管,主要利用了它的ioc来解耦,hibernate提供orm映射机制,方便数据库操作,简化sql操作。

版本信息如下:

Struts版本:2.3.20

Spring版本:4.1.5.RELEASE

Hibernate版本:4.3.8.Final

工程目录如下:

SSH框架基础整合搭建图文教程

结构没什么多说的,配置文件中一些难理解的地方,当时我都加上了注释,这次也没什么过多改动,力求言简意赅!

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
         version="3.0">

    <!-- spring配置 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- 可以自己指定配置文件位置 -->
        <param-value>classpath:applicationContext.xml</param-value>
        <!-- <param-value>/WEB-INF/applicationContext.xml</param-value> -->
    </context-param>

    <!-- struts配置 -->
    <filter>
        <filter-name>struts</filter-name>
        <!--不同版本中配置的不一样,低版本中,filter-class配置就不是这个class类-->
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>*.action</url-pattern>
        <!-- <url-pattern>/*</url-pattern> -->
    </filter-mapping>

    <!-- 默认页面 -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

这里需要注意一下filter的配置中的注释,filter-class需要注意版本信息,不同版本配置的是不一样的。

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>

    <!-- 打开DMI动态方法,2.3.15之前默认true,之后默认false -->
    <!-- DMI用法: test!add.action -->
    <!-- <constant name="struts.enable.DynamicMethodInvocation" value="true" /> -->

    <!-- struts2的action必须放在一个指定的包空间下定义 -->
    <package name="default" extends="struts-default">
        <!-- 声明全局的返回结果 -->
        <global-results>
            <result name="fail">/error.jsp</result>
        </global-results>

        <!-- 这里action标签需要放到最下面,不然会报错 -->
        <!-- DMI动态方法:闪瞎双眼的时刻即将到来,在2.3.15之后已经默认为false关闭,需要自己手动打开,不然一个劲儿404,官方表明此种方法有漏洞,推荐使用通配符方式 -->
        <action name="test1" class="com.ssh.controller.StudentController">
            <result name="success">/index.jsp</result>
            <!-- 重定向 -->
            <!-- <result name="redirect" type="redirectAction">test1!showlist.action</result> -->
        </action>

        <!-- 指定method:每个用到的方法都需要为其配置一个action,比较麻烦 -->
        <action name="test2" class="com.ssh.controller.StudentController" method="list">
            <result name="success">/index.jsp</result>
        </action>

        <!-- 通配符:官方推荐使用,如school_list,就是访问controller中的list方法 -->
        <!-- {1}表示通配符的第一个,可以有多个,并且在result标签中也可以使用 -->
        <action name="school_*" class="com.ssh.controller.SchoolController" method="{1}">
            <!-- <result name="{1}">/{1}.jsp</result> -->
            <result name="list">/school_list.jsp</result>
            <result name="add">/school_maintain.jsp</result>
            <result name="update">/school_maintain.jsp</result>
            <result name="refresh" type="redirectAction">school_list.action</result>
        </action>

        <action name="student_*" class="com.ssh.controller.StudentController" method="{1}">
            <result name="list">/student_list.jsp</result>
            <result name="add">/student_maintain.jsp</result>
            <result name="update">/student_maintain.jsp</result>
            <result name="refresh" type="redirectAction">student_list.action</result>
        </action>

        <action name="book_*" class="com.ssh.controller.BookController" method="{1}">
            <result name="list">/book_list.jsp</result>
            <result name="add">/book_maintain.jsp</result>
            <result name="update">/book_maintain.jsp</result>
            <result name="refresh" type="redirectAction">book_list.action</result>
        </action>
    </package>
</struts> 

截止到我当时做笔记的时候,struts总共有三种映射方式:

一对一映射:比较常见,每一个请求都需要在struts.xml中配置一个action,是早期的方式,非常麻烦;

DMI动态映射:利用感叹号动态映射,如:test!a.action就代表TestController中的a请求,官方不推荐使用;

通配符映射:利用花括号{}的方式进行匹配,不太好描述,大家看我上面配置文件中的注释;

applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 	http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

    <!--配置数据源,可以选择c3p0、druid等,这里直接使用spring的DataSource数据源-->
    <!--也可以选择在hibernate.cfg.xml中配置数据源,在这里为了事务的方便管理,将数据源交给spring管理-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true"/>
        <property name="username" value="test"/>
        <property name="password" value="111111"/>
    </bean>

    <!--hibernate的session工厂相关配置-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <!--指定数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置jdbc属性-->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.autoReconnect">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
        <!-- 引入映射文件,有两种方式:-->
        <!-- 1、直接将配置文件写在spring配置中 -->
        <!--
        <property name="mappingResources">
            <list>
                <value>sqlmap/Book.hbm.xml</value>
                <value>sqlmap/School.hbm.xml</value>
                <value>sqlmap/Student.hbm.xml</value>
            </list>
        </property>
        -->
        <!-- 2、引用外部配置文件,在hibernate配置文件中统一配置 -->
        <property name="configLocations">
           <list>
               <value>classpath:hibernate.cfg.xml</value>
           </list>
       </property>
    </bean>

    <!-- 事务管理 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 模板,作为公用,调用是只需要加上parent属性指向这里,不然每个bean中都需要加上这些配置 -->
    <bean id="transactionalTemplate" abstract="true"
          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!-- 引入事务管理器 -->
        <property name="transactionManager" ref="transactionManager"/>
        <!-- 配置事务的传播属性 -->
        <property name="transactionAttributes">
            <props>
                <!-- 事务管理的方法、方式 -->
                <!-- 例如:add开头的方法 -->
                <!-- <prop key="add*">PROPAGATION_REQUIRED</prop> -->
                <!-- PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启。 -->
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

    <!-- dao中注意,需要使用parent将相应的事务管理引入进来,因为每个dao都写一遍是不现实的,所以抽出公用 -->
    <!-- 使用xml方式注入时,这里的dao不是用接口方式不行? -->
    <bean id="schoolDao" parent="transactionalTemplate">
        <property name="target">
            <bean class="com.ssh.dao.impl.SchoolDaoImpl">
                <property name="sessionFactory" ref="sessionFactory"/>
            </bean>
        </property>
    </bean>
    <bean id="studentDao" parent="transactionalTemplate">
        <property name="target">
            <bean class="com.ssh.dao.impl.StudentDaoImpl">
                <property name="sessionFactory" ref="sessionFactory"/>
            </bean>
        </property>
    </bean>
    <bean id="bookDao" parent="transactionalTemplate">
        <property name="target">
            <bean class="com.ssh.dao.impl.BookDaoImpl">
                <property name="sessionFactory" ref="sessionFactory"/>
            </bean>
        </property>
    </bean>

    <!-- service中注意,需要使用property将相应的dao变量引入进来,否则注入为空 -->

    <bean id="schoolService" class="com.ssh.service.impl.SchoolServiceImpl">
        <property name="schoolDao" ref="schoolDao"/>
    </bean>
    <bean id="studentService" class="com.ssh.service.impl.StudentServiceImpl">
        <property name="studentDao" ref="studentDao"/>
    </bean>
    <bean id="bookService" class="com.ssh.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>

相对于SpringMVC来说,就是只保留了bean管理和事务两块二配置,也没什么多说的,配置方式跟现在也都一模一样。

hibernate.cfg.xml:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- 如果没有直接在spring配置文件中集成相关映射文件,就需要在这里配置好,然后再引入到spring中 -->
<hibernate-configuration>

    <session-factory>

<!--        如果么有使用spring托管数据源,就可以在这里进行配置-->

<!--        &lt;!&ndash; 指定连接数据库所用的驱动 &ndash;&gt;-->
<!--        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>-->
<!--        &lt;!&ndash; 指定连接数据库的url,hibernate连接的数据库名 &ndash;&gt;-->
<!--        <property name="connection.url">jdbc:mysql://localhost/数据库名</property>-->
<!--        &lt;!&ndash; 指定连接数据库的用户名 &ndash;&gt;-->
<!--        <property name="connection.username">root</property>-->
<!--        &lt;!&ndash; 指定连接数据库的密码 &ndash;&gt;-->
<!--        <property name="connection.password">32147</property>-->
<!--        &lt;!&ndash; 指定数据库方言 &ndash;&gt;-->
<!--        <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>-->
<!--        &lt;!&ndash; 根据需要自动创建数据表 &ndash;&gt;-->
<!--        <property name="hbm2ddl.auto">update</property>-->
<!--        &lt;!&ndash; 显示Hibernate持久化操作所生成的SQL &ndash;&gt;-->
<!--        <property name="show_sql">true</property>-->
<!--        &lt;!&ndash; 将SQL脚本进行格式化后再输出 &ndash;&gt;-->
<!--        <property name="hibernate.format_sql">true</property>-->

<!--        下面是使用c3p0数据库进行数据源配置的样例-->

<!--        &lt;!&ndash; 指定连接池里最大连接数 &ndash;&gt;-->
<!--        <property name="hibernate.c3p0.max_size">20</property>-->
<!--        &lt;!&ndash; 指定连接池里最小连接数 &ndash;&gt;-->
<!--        <property name="hibernate.c3p0.min_size">1</property>-->
<!--        &lt;!&ndash; 指定连接池里连接的超时时长 &ndash;&gt;-->
<!--        <property name="hibernate.c3p0.timeout">5000</property>-->
<!--        &lt;!&ndash; 指定连接池里最大缓存多少个Statement对象 &ndash;&gt;-->
<!--        <property name="hibernate.c3p0.max_statements">100</property>-->
<!--        <property name="hibernate.c3p0.idle_test_period">3000</property>-->
<!--        <property name="hibernate.c3p0.acquire_increment">2</property>-->
<!--        <property name="hibernate.c3p0.validate">true</property>-->

        <!-- 配置映射文件 -->
        <mapping resource="sqlmap/School.hbm.xml"/>
        <mapping resource="sqlmap/Student.hbm.xml"/>
        <mapping resource="sqlmap/Book.hbm.xml"/>
    </session-factory>

</hibernate-configuration>

再看一个hibernate的映射文件:

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

<hibernate-mapping>
    <class name="com.ssh.entity.Student" table="students">
        <id name="id" type="java.lang.Integer">
            <!-- scale表示小数位 -->
            <column name="id" precision="10" scale="0"/>
            <!-- 如果是oracle,则需要指定自增序列 -->
            <!-- class表示ID的属性,自增、关联另外表的主键等,在有对应关系时使用 -->
            <!-- <generator class="sequence">-->
            <!--     <param name="sequence">ZZ_STUDENTS</param>-->
            <!-- </generator>-->
            <!--
                主键生成策略:
                1. identity : 主键自增.由数据库来维护主键值,录入时不需要指定主键值
                2. sequence : Oracle中的主键生成策略
                3. increment : 主键自增,由hibernate来维护,每次查询时会先查询数据库中的最大值,然后在最大值的基础上+1
                4. hilo : 高低位算法,主键自增,由hibernate维护,开发时不使用
                5. native : hilo+sequence+identity自动三选一
                6. uuid : 产生随机字符串作为主键,主键类型必须为string类型
                7. assigned : 自然主键生成策略
             -->
        </id>
        <property name="name" type="java.lang.String">
            <column name="student_name" length="50"/>
        </property>
        <property name="sex" type="java.lang.String">
            <column name="student_sex" length="5"/>
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="student_age" precision="5" scale="0"/>
        </property>
        <property name="birthday" type="java.util.Date">
            <column name="student_birthday"/>
        </property>
        <property name="hobby" type="java.lang.String">
            <column name="student_hobby" length="100"/>
        </property>
        <!-- 与学校对应的关系 -->
        <!-- property-ref属性指定关联类的属性名,若不指定,默认关联主键 -->
        <!-- 外键一对一,相当于多对一的一种(注意加上unique='true'的限制保证唯一),严格意义上的一对一,是要求两个表主键都相同 -->
        <!-- 注意lazy表示延迟加载,false表示立即加载,但是这里不加会报错 -->
        <many-to-one name="school" column="school_id" unique="true" lazy="false"/>
    </class>
</hibernate-mapping>

注意:表之间的对应关系是重点,一对多、多对一这种,一定要先将关系捋清楚,哪个是主哪个是从,找好关联的点在哪里。

由于代码中的注释写的比较齐全,这里不再过多赘述了,案例比较简单,就是CRUD,运行效果图:

SSH框架基础整合搭建图文教程

SSH_CONFIG.rar

下载次数: 49

QQ群Ⅰ: 686430774 (已满)

QQ群Ⅱ: 718410762 (已满)

QQ群Ⅲ: 638620451 (已满)

QQ群Ⅳ: 474195684

如果文章有帮到你,可以考虑请博主喝杯咖啡!

分享到:

欢迎分享本文,转载请注明出处!

作者:不忘初心

发布时间:2019-04-25

永久地址:https://www.jiweichengzhu.com/article/d063714d7af04f699cd6779b498ae96d

评论