手把手教你如何玩转SSH框架的整合(Spring+SpringMVC+Hibernate)

      在一个新项目来的时候,需求确认是非常关键的,其次就是环境搭建,依据什么样的需求来搭建什么样的环境,这样才对系统有更好的性能。然而,在一个公司里面,搭建环境现在很多都是采取公司自定义的框架来生成代码,而开发人员就只需知道编写相应代码就可以了,对于底层的环境搭建根本就不需要过多的了解。其实,这是一个非常不好的事情,因为有很多时候,对于底层的东西也是需要了解的,只有对框架的构架有了一个大体的认识,然后对自己的编码和优化才会有更好的效率。另外,在很多人学习新技术的过程中,都只为了求快速学习,而忘记了很多根本的问题,大体一知半解,这也是一个弊端,等真正用的时候,就发现一堆的问题,然后疯狂的百度找配置内容,这不仅花时间而且做的事情都是“应试学习”模式。。所以,为了很多人,能够快速的掌握一下框架的整合,就把目前来说,企业用到的比较流行的框架的知识来进行整合。(另外,如果想知道Spring+SpringMVC+Mybatis 及其Strus2 + Spring+Hibernate的整合可以看看我另外的两篇文章,都记录得非常的明细了)

    OK,不多说,就用实际的代码及其步骤来手把手教大家如何进行整合框架。(其实,只要了解了,每个框架是干嘛的,就很好整合了)

github项目源码地址https://github.com/qq496616246/SSHWebStructure

如果你想看其他的环境搭建,那么请参考我的其余博文。

手把手教你阿里云服务器(Ubuntu系统)如何部署Web开发环境
地址:https://blog.csdn.net/cs_hnu_scw/article/details/79125582
手把手教你如何玩转SSH(Spring+Strus2+Hibernate)
地址:https://blog.csdn.net/cs_hnu_scw/article/details/77888051
手把手教你如何玩转SSH(Spring+SpringMVC+Hibernate)
地址:https://blog.csdn.net/cs_hnu_scw/article/details/78849772
手把手教你如何玩转SSM框架搭建(Maven版本)
地址:https://blog.csdn.net/cs_hnu_scw/article/details/80709822
手把手教你如何玩转SSM框架整合(非Maven版本)
地址:https://blog.csdn.net/cs_hnu_scw/article/details/78157672
手把手教你如何玩转SpringBoot整合Mybatis(mapper.xml方式开发)
地址:https://blog.csdn.net/cs_hnu_scw/article/details/80693248
手把手教你如何玩转SpringBoot整合MyBatis(mybatis全注解开发和热部署及其JSP配置详解)
地址:https://blog.csdn.net/cs_hnu_scw/article/details/78961232

第一步:导包

    咳咳,别看这个工作简单,然而蕴含的内容就是很多的,因为包如果导错了,那么后期构建的时候,你就会出现很多莫名其妙的问题,所以包一定要注意。首先,要保证包的版本最好处于相近的版本,而别一个是用3.+的,而又出现2+的,因为很多框架,对于版本3和2的,都进行了很大的革新,所以一定要注意这个问题。(现在很多项目都是通过Maven来包依赖管理的了,虽然Maven是一个非常重要的革命的内容,但是,我觉得,不管如何,我们还是需要对底层的内容进行了解会比较好)

大体的如下:


如果需要的话,就从网盘中进行获取,如果失效了,就在CSDN私信给我就好了。

链接:https://pan.baidu.com/s/1miR7KTU 密码:kzio

第二步:搭建Hibernate环境

   为什么是选择首先搭建Hibernate呢?其实是有原因的,因为Hibernate是不需要Web环境就可以搭建,那么也就是意味着,我们可以搭建好了,就先进行测试,这样是不是对于整个环境的搭建就更加有安全性了呢?记住,千万不要一次性的将所有内容都整合后,然后进行直接运行,而应该搭建好一个,然后就单独进行测试。。。

(1)导包-----这个在第一步就已经做好,所以不需要多处理,直接跳过

(2)编写实体类文件------也就是常说的JavaBean和pojo

比如,我这就写一个简单的实体类:(注意:要实现实体的默认构造方法,一定要,这样是为了保证,如果你有其他的构造方法,那么默认的就不会实现,那么到后期产生对象的时候就会出现问题,所以不管如何,最好都手动实现吧

package com.hnu.scw.model;
import org.springframework.stereotype.Component;
/**
 * @author scw
 * @create 2017-12-19 15:14
 * @desc
 **/
public class Person {
    private Long id ;
    private String name;
    private String sex;
    public Person(){    

    }
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

(3)编写实体对应的hibernate映射文件--------------简单点说,就是写对应实体对应的数据库表(当然,如果后面用注解的形式,当然就可以直接在实体上面进行操作)

比如,对应上面的实体,就写了一个下面的这个映射文件。注意:命名以:实体类名+hbm+.xml,这样的形式来,很清晰。所以这里就为Person.hbm.xml

<?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属性为类的全名
             table 表名  默认值:类名
             catalog 数据库的名字
     -->
    <class name="com.hnu.scw.model.Person">
        <id name="id" length="5">
            <generator class="increment"></generator>
        </id>
        <property name="name" length="20"></property>
        <property name="sex" length="20"></property>
    </class>
</hibernate-mapping>

(4)编写Hibernate配置文件---------简单点说,就是配置Hibernate的环境,一般命名就是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">
<hibernate-configuration>
    <!-- 一个sessionFactory代表数据库的一个连接 -->
    <session-factory>
        <!-- 链接数据库的用户名 -->
        <property name="connection.username">***(自己数据库名)**</property>
        <!-- 链接数据库的密码 -->
        <property name="connection.password">**(自己数据库密码)*******</property>
        <!-- 链接数据库的驱动 -->
        <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <!-- 链接数据库的url -->
        <property name="connection.url">
            jdbc:mysql://localhost:3306/hibernatesql
        </property>
        <!--
            方言
            告诉hibernate用什么样的数据库
        -->
        <property name="dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
        <!--
            validate 加载hibernate时,验证数据库的结构  默认值
            update  加载hibernate时,检查数据库,如果表不存在,则创建,如果存在,则更新
            create  每次加载hiberante,都会创建表
            create-drop  每次加载hiberante,创建,卸载hiberante时,销毁
        -->
        <property name="hbm2ddl.auto">update</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <mapping resource="com/hnu/scw/model/Person.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>
(5)搭建完成,进行测试------------------确保,hibernate环境搭建成功
 @Test
    //单独测试hibernate
    public void fun1(){
        Configuration conf = new Configuration().configure();
        SessionFactory sf = conf.buildSessionFactory();
        Session session = sf.openSession();
        Transaction tx = session.beginTransaction();
        //-------------------------------------------------
        Person u = new Person();
        u.setName("hibernate");
        u.setSex("中");
        session.save(u);
        //-------------------------------------------------
        tx.commit();
        session.close();
        sf.close();
    }

第三步:Spring环境的整合搭建

(1)我们知道,hibernate的需要sessionFactory对象来进行session和query对象及其transaction事务的,所以,首先第一步,就是通过Spring容器来获取sessionFactory。

(2)编写Spring容器的配置文件,一般命名applicationContext.xml

(3)通过Sprng容器获取sessionFactory-----------这个有两种方法,具体代码如下:

<!--配置sessionFactory(方法一)-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
    </bean>

<!--配置sessionFactory(方法二),一般都是采取这种方式,比较简单-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="hibernateProperties">
            <props>
		<!--  必选配置 -->
		<prop key="hibernate.connection.driver_class" >com.mysql.jdbc.Driver</prop>
		<prop key="hibernate.connection.url" >jdbc:mysql:///数据库名</prop>
		<prop key="hibernate.connection.username" >数据库账号</prop>
		<prop key="hibernate.connection.password" >数据库密码</prop> -->
		<prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>

                <!--三个可选的hibernate配置内容-->
                <prop key="hibernate.show_sql" >true</prop>
                <prop key="hibernate.format_sql" >true</prop>
                <prop key="hibernate.hbm2ddl.auto" >update</prop>
            </props>
        </property>
        <!-- 配置实体扫描,引入orm元数据,指定orm元数据所在的包路径,spring会自动读取包中的所有配置 -->
        <property name="mappingDirectoryLocations" value="classpath:com/hnu/scw/model" ></property>
    </bean>
(4)测试sessionFactory是否创建成功------------编写单元测试

代码如下:

package com.hnu.scw.test;
import com.hnu.scw.model.Person;
import com.hnu.scw.service.PersonService;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;

/**
 * @author Administrator
 * @create 2017-12-19 17:55
 * @desc
 **/
@RunWith(SpringJUnit4ClassRunner.class)                     /注意这两个地方,
@ContextConfiguration("classpath:applicationContext.xml")   /注意这两个地方,
public class ProjectTest {
    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    /**
     * 单独测试spring容器产生sessionFactory
     */
    @Test
    public void fun2(){
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        Person u = new Person();
        u.setName("hibernate33333333333");
        u.setSex("中");
        session.save(u);
        tx.commit();
        session.close();
    } 
}
(5)Spring容器配置中,编写properties文件扫描----------主要是为了能够读取properties文件的数据内容,方便一点

代码如下:

 <!-- 读取db.properties文件 -->
    <context:property-placeholder location="classpath:dbapplication.properties" />
(6)配置数据库信息--------------其实就是将hibernate中原来的内容,复制到这里就可以了,这样就可以通过Spring容器来进行管理数据源

代码如下:(这里数据源是用的c3p0,当然还可以用阿里的druid)

 <!-- 配置数据库配置,配置c3p0连接池 -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property>
        <property name="driverClass" value="${jdbc.driverClass}" ></property>
        <property name="user" value="${jdbc.user}" ></property>
        <property name="password" value="${jdbc.password}" ></property>
    </bean>
(7)将sessionFactoy与数据源进行整合-----------如果不这样的话,就直接用(3)的方法也可以,建议的话,还是用这样吧。看起来方便
代码如下:
 <!--配置sessionFactory(方法二),一般都是采取这种方式,比较简单-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!--引入数据库配置信息dataSource-->
        <property name="dataSource" >
            <ref bean="dataSource"/>
        </property>
        <property name="hibernateProperties">
            <props>
                <!--三个可选的hibernate配置内容-->
                <prop key="hibernate.show_sql" >true</prop>
                <prop key="hibernate.format_sql" >true</prop>
                <prop key="hibernate.hbm2ddl.auto" >update</prop>
            </props>
        </property>
        <!-- 配置实体扫描,引入orm元数据,指定orm元数据所在的包路径,spring会自动读取包中的所有配置 -->
        <property name="mappingDirectoryLocations" value="classpath:com/hnu/scw/model" ></property>
    </bean>	

在说一个非常重要的地方,如果在开发过程中,不想通过一个实体类对应一个Hibernate映射文件的方法的话,那么就通过注释的形式来进行就可以了,这样的话可以省去很多的实体对应xml的配置,所以,在开发过程中,就看项目组是要怎么的一个需求。所以,(7)的步骤还可以是如下代码:(反正我习惯这样的开发了!!!啊哈哈哈哈)

 <!--配置sessionFactory(方法二),一般都是采取这种方式,比较简单-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!--引入数据库配置信息dataSource-->
        <property name="dataSource" >
            <ref bean="dataSource"/>
        </property>
        <property name="hibernateProperties">
            <props>
                <!--三个可选的hibernate配置内容-->
                <prop key="hibernate.show_sql" >true</prop>
                <prop key="hibernate.format_sql" >true</prop>
                <prop key="hibernate.hbm2ddl.auto" >update</prop>
            </props>
        </property>
        <!--扫描对应对应包下的实体类(重点的重点)-->
        <property name="packagesToScan">
            <list>
                <value>com.hnu.scw.model</value>
            </list>
        </property>
        <!-- 配置实体扫描,引入orm元数据,指定orm元数据所在的包路径,spring会自动读取包中的所有配置 -->
        <!--<property name="mappingDirectoryLocations" value="classpath:com/hnu/scw/model" ></property>-->
    </bean>
有没有发现,通过这样的方式的话,其实在第二步中对于hibernate的配置都已经在Spring容器中实现了,所以就相当于可以省略Hibernate的那些配置了,这就是Spring的一个强大的地方。当然,这个的前提是需要进行注解的形式开发。所以对应的实体中,就应该以下面的形式进行编写,而不是单独对实体写映射文件。
package com.hnu.scw.model;
import org.springframework.stereotype.Component;
import javax.persistence.*;
/**
 * @author scw
 * @create 2017-12-19 15:14
 * @desc
 **/
@Entity
@Table(name = "person")
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id ;
    @Column(name = "name")
    private String name;
    @Column(name = "sex")
    private String sex;
    public Person(){

    }
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}
注意:这个地方的代码,主要是为了衔接上(7)的内容,当然这个开发是可以放到配置完Spring之后再进行的(可以与在Hibernate配置步骤中的不用注解形式配置实体的代码进行比较一下哦!!!!)

(8)配置事务---------------这个就不用说好处了吧。。就是为了数据库操作的安全

代码如下:

<!--配置hibernate事务-->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
(9)配置切面通知----------也就是为了指定哪些方法需要具体的什么事务操作

代码如下:

<!--配置切面通知-->
    <tx:advice id="tx" transaction-manager="transactionManager">
        <tx:attributes>
            <!--根据service中的方法名来自定义配置信息,一般的都默认配置为如下信息
            isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"
            -->
            <tx:method name="save*"/>
            <tx:method name="insert*"/>
            <tx:method name="update*"/>
            <tx:method name="delete*"/>
        </tx:attributes>
    </tx:advice>
(10)织入切面管理-----------通俗简单点说,就是将什么层的什么方法需要事务处理进行绑定。
代码如下:
 <!--织入切面管理service中事务-->
    <aop:config >
        <aop:pointcut id="perform" expression="execution(* com.hnu.scw.service.*.*(..))"/>
        <aop:advisor advice-ref="tx" pointcut-ref="perform"/>
    </aop:config>
(11)如果想通过注解来进行事务的配置的话,那么就是如下的代码,这样的话,(9)和(10)就可以不要写了
<!-- 开启注解事务,一般使用xml进行配置会比较好些,也就是下面的方法-->
    <!--<tx:annotation-driven transaction-manager="transactionManager" />-->
(12)编写注解标签的扫描----------这个一般的话,放在最前面也可以,而这放在最后来说,是因为,一般的时候,我们先搭环境,那么service和dao层都还没有,所以,

这里就最后来考虑这个内容。

代码如下:

<!--配置bean,通过xml的形式,这个实际开发中不会这样,因为这样的话,比较实现setXXX()方法才可以注入,一般都是扫描-->
    <!--<bean id="personDao" class="com.hnu.scw.daoimp.PersonDaoImp">
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
        <!–
        上面的这个等价于下面的配置,看个人爱好吧
        <property name="sessionFactory" ref="sessionFactory"> </property>
        –>
    </bean>
    <bean id="personService" class="com.hnu.scw.service.imp.PersonServiceImp1">
        <property name="personDao">
            <ref bean="personDao"/>
        </property>
    </bean>-->
    <!--配置bean扫描-->
    <context:component-scan base-package="com.hnu.scw" ></context:component-scan>
(13) 配置完成,最后的代码就如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       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-4.2.xsd
							http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
							http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
							http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">

    <!-- 读取db.properties文件 -->
    <context:property-placeholder location="classpath:dbapplication.properties" />
    <!--配置bean,通过xml的形式,这个实际开发中不会这样,因为这样的话,比较实现setXXX()方法才可以注入,一般都是扫描-->
    <!--<bean id="personDao" class="com.hnu.scw.daoimp.PersonDaoImp">
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
        <!–
        上面的这个等价于下面的配置,看个人爱好吧
        <property name="sessionFactory" ref="sessionFactory"> </property>
        –>
    </bean>
    <bean id="personService" class="com.hnu.scw.service.imp.PersonServiceImp1">
        <property name="personDao">
            <ref bean="personDao"/>
        </property>
    </bean>-->
    <!--配置bean扫描-->
    <context:component-scan base-package="com.hnu.scw" ></context:component-scan>
    <!--配置sessionFactory(方法一)-->
    <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
    </bean>-->
    <!-- 配置数据库配置,配置c3p0连接池 -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property>
        <property name="driverClass" value="${jdbc.driverClass}" ></property>
        <property name="user" value="${jdbc.user}" ></property>
        <property name="password" value="${jdbc.password}" ></property>
    </bean>
    <!--配置sessionFactory(方法二),一般都是采取这种方式,比较简单-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!--引入数据库配置信息dataSource-->
        <property name="dataSource" >
            <ref bean="dataSource"/>
        </property>
        <property name="hibernateProperties">
            <props>
                <!--三个可选的hibernate配置内容-->
                <prop key="hibernate.show_sql" >true</prop>
                <prop key="hibernate.format_sql" >true</prop>
                <prop key="hibernate.hbm2ddl.auto" >update</prop>
            </props>
        </property>
        <!-- 配置实体扫描,引入orm元数据,指定orm元数据所在的包路径,spring会自动读取包中的所有配置 -->
        <property name="mappingDirectoryLocations" value="classpath:com/hnu/scw/model" ></property>
    </bean>

    <!--配置hibernate事务-->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

    <!-- 开启注解事务,一般使用xml进行配置会比较好些,也就是下面的方法-->
    <!--<tx:annotation-driven transaction-manager="transactionManager" />-->

    <!--配置切面通知-->
    <tx:advice id="tx" transaction-manager="transactionManager">
        <tx:attributes>
            <!--根据service中的方法名来自定义配置信息,一般的都默认配置为如下信息
            isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"
            -->
            <tx:method name="save*"/>
            <tx:method name="insert*"/>
            <tx:method name="update*"/>
            <tx:method name="delete*"/>
        </tx:attributes>
    </tx:advice>
    <!--织入切面管理service中事务-->
    <aop:config >
        <aop:pointcut id="perform" expression="execution(* com.hnu.scw.service.*.*(..))"/>
        <aop:advisor advice-ref="tx" pointcut-ref="perform"/>
    </aop:config>
</beans>

(14)编写spring和hibernate的整合测试代码,代码如下:

     /**
     * 测试spring和hibernate的整合-------------这就是用的xml来配置的形式
     */
    @Test
    public void fun3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        PersonService personService = (PersonService) applicationContext.getBean("personService");
        Person person = new Person();
        person.setSex("男");
        person.setName("我是一个好学生123123123");
        personService.savePerson(person);
    }

    /**
     * 注解bean的注入测试---------这就是用的注解的形式
     */
    @Resource(name = "personService")
    private PersonService personService;
    @Test
    public void fun4(){
        Person person = new Person();
        person.setSex("男");
        person.setName("我是一个好学生3333333333333");
        personService.savePerson(person);
    }

第四步:SpringMVC的整合

(1)编写springmvc的配置文件------这里就是要对springmvc的工作流程要熟悉一下会比较好,这样配置的时候,就很快了。

springmvc工作流程:用户请求----.>DispatcherServlet(前端处理器)--->handlerMapping(处理器映射)---->controller---->service---->dao---->数据库----->dao---->service--->controller----->ModelAndView(模型视图对象)---->ViewResolver(视图解析器)----->view(JSP)----->用户
(2)springmvc.xml文件配置如下:----这个比较简单,所以就不一步步来说了。。

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
		http://www.springframework.org/schema/mvc 
		http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-4.0.xsd">
		<!-- 配置扫描器 controller-->
		<context:component-scan base-package="com.hnu.scw.controller"/>
		<!-- 配置处理器映射器  适配器 -->
		<mvc:annotation-driven/>
		<!-- 对静态资源放行  -->
		<mvc:resources location="/css/" mapping="/css/**"/>
		<mvc:resources location="/js/" mapping="/js/**"/>
		<mvc:resources location="/fonts/" mapping="/fonts/**"/>
		<!-- 配置视图解释器 jsp -->
		<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
			<property name="prefix" value="/WEB-INF/jsp/"/>
			<property name="suffix" value=".jsp"/>
		</bean>
		
</beans>

第五步:Spring和SpringMVC的整合----其实就是编写web项目中的web.xml文件

代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!-- 让spring随web启动而创建的监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 配置spring配置文件位置参数 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!-- POST提交过滤器 UTF-8 -->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>

    <!-- 扩大session作用范围
  	注意: 任何filter一定要在struts的filter之前调用
   -->
    <filter>
        <filter-name>openSessionInView</filter-name>
        <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>openSessionInView</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--配置springmvc-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--配置springmvc的配置文件的位置-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--设置拦截请求的内容,
        1:*.do *.action 拦截以.do结尾的请求 (不拦截 jsp png jpg .js .css)
        2:/ 拦截所有请求 (不拦截.jsp) 建议使用此种 方式 (拦截 .js.css .png) (放行静态资源)
		3:/* 拦截所有请求(包括.jsp) 此种方式 不建议使用
        -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

第六步:大功告成,进行完整的测试即可。。

好了,上面主要就是说了三大框架的配置文件的搭建,下面的话,就把自己的每一个层的代码,贴一下,这样方法能够把整个流程看明白(用的注解形式开发@Autowired,@service,@Reponsity @Componet)

Controller层:

package com.hnu.scw.controller;
import com.hnu.scw.model.Person;
import com.hnu.scw.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author scw
 * @create 2017-12-19 16:44
 * @desc
 **/
@Controller
public class PersonController {
    @Autowired
    private PersonService personService;

    @RequestMapping(value = "/person")
    public String testDemo(){
        Person person = new Person();
        person.setName("终于成功了");
        person.setSex("男");
        personService.savePerson(person);
        System.out.println("我是测试,我进来了!!!");
        return "hello";
    }
}
Service层:(基于接口和实现类,这也是项目开发的面向接口编程的规范)
package com.hnu.scw.service;
import com.hnu.scw.model.Person;
public interface PersonService {
    public void savePerson(Person person);
}
package com.hnu.scw.service.imp;
import com.hnu.scw.dao.PersonDao;
import com.hnu.scw.model.Person;
import com.hnu.scw.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Administrator
 * @create 2017-12-19 16:01
 * @desc
 **/
@Service
public class PersonServiceImp1 implements PersonService {
    @Autowired
    private PersonDao personDao;

    @Override
    public void savePerson(Person person) {
        personDao.savePerson(person);
    }


}

Dao层:同样也是接口和实现类--------这是个简单的开发,不是实际真实的,实际开发中,是有一个最基本的Dao,然后每个都是去继承这个Dao来开发,这个在我另外的一篇文章中有提到,可以去看看。。看看Mybatis和Hibernate中DAO层的封装区别-------------(非常值得看一下,有基础DAO,那么编写就很好了)

package com.hnu.scw.dao;
import com.hnu.scw.model.Person;
public interface PersonDao {
    public void savePerson(Person person);
}
实现类:
package com.hnu.scw.daoimp;
import com.hnu.scw.dao.PersonDao;
import com.hnu.scw.model.Person;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

/**
 * @author scw
 * @create 2017-12-19 15:17
 * @desc
 **/
@Repository
public class PersonDaoImp  implements PersonDao{
    @Autowired
    private SessionFactory sessionFactory;

    /**
     * 获取到session,最好是把这个方法放到最基本的dao,然后所有的dao全部继承基础的dao类
     * @return
     */
    private Session getSession(){
       return sessionFactory.getCurrentSession();
    }
    /**
     * 保存person用户
     * @param person
     */
    @Override
    public void savePerson(Person person) {
        getSession().save(person);
        /*
        千万要不能用继承HibernateSupport的方法来进行下面这样,
        因为这样是获取不到sessionFactory的,所以要么就是用setFactory方法,要么就是用上面写的getsession()方法来注入
        this.getHibernateTemplate().save(person);
        */
    }
}

注意:千万要注意,有很多人,在学习的时候都是Dao继承的HibernateSupport,然后通过hibernateTemplate来进行的方法操作,这样在整合的时候,就不能这样的,而是要通过sessionFactory注入来进行操作,这是一个坑,你如果不行,你可以试试还是用原来的继承的方法进行。这个的原因是:因为当spring来管理sessionFactory对象,那么必须通过set()方法或者通过@Autowired来注入sessionFactory,否则是获取不到这个对象的,大家可以试试。。你就明白了原因,如果继承HibernateSupprot,这里在启动项目的时候,就会报一个错误:sessionFactory and datasourc  must  be required.....................所以,特意提醒。


好了,再添加一点小知识,就是对DAO层的封装,来写一个简单的BaseDAO的类,这样以后不管什么DAO,都继承这个父类,就省了很多的重复代码。(下面就是随便写的几个方法,可以根据项目需要,把公共的方法放在BaseDao类中就好了)

BaseDao接口:(注意:用了泛型,是为了有普遍性)

package com.hnu.scw.dao;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
/**
 * 最基础的basedao接口的设计
 * @param <T>
 */
@Repository
public interface BaseDao<T>{

    /**
     * 保存数据信息
     * @param t 参数是泛型,这样就具有通用性
     */
    public Long save(T t);

    /**
     * 更新数据操作
     * @param t
     */
    public void update(T t);

    /**
     * 获取到对应id主键的对象内容
     * @param id
     * @return
     */
    public T load(Serializable id);

    /**
     * 获取对应查询内容的数据条数
     * @param hql
     * @param paras
     * @return
     */
    public Integer findTotalCount(String hql , Object[] paras);
}
BaseDaoImpl类:------------------同样使用了泛型
package com.hnu.scw.dao.impl;
import com.hnu.scw.dao.BaseDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;

/**
 * @author Administrator
 * @create 2017-12-21 9:25
 * @desc 基本dao层的实现
 **/
public class BaseDaoImpl<T> implements BaseDao<T>{
    @Autowired
    private SessionFactory sessionFactory;
    /**
    获取加载到调用者的类型
     */
    protected Class<T> clazz;

    public BaseDaoImpl(){
        //获得当前类型的带有泛型类型的父类
        ParameterizedType genericSuperclass =(ParameterizedType)getClass().getGenericSuperclass();
        //获得运行期的泛型类型
        clazz   = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
    }

    /**
     * 获取当前线程的session对象,用于操作数据库
     * @return
     */
    public Session getSession(){
        try {
            return sessionFactory.getCurrentSession();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Long save(T t) {
        return (Long) getSession().save(t);
    }

    @Override
    public void update(T t) {
        getSession().update(t);
    }

    @Override
    public T load(Serializable id) {
        return getSession().load( clazz, id);
    }

    @Override
    public Integer findTotalCount(String hql, Object[] paras) {
        Query query = getSession().createQuery(hql);
        //设置参数参数(如果是空,那么就不需要进行设置参数,就是查询所有)
        setFindParamter( query ,paras);
        //进行查询
        List<Object> list = query.list();
        if (list.size() == 0) {
            return 0;
        } else {
            return Integer.valueOf(list.get(0).toString());
        }
    }

    /**
     * 设置查询语句的参数
     * @param query
     * @param paras
     */
    private void setFindParamter(Query query, Object[] paras) {
        if (ArrayUtils.isNotEmpty(paras)) {
            int j = 0;
            for (int i = 0; i < paras.length; i++) {
                //如果是集合,就使用下面if中的方法,如果是数组类型的参数,就用else中的方法
                if (paras[i] instanceof Collection<?>) {
                    query.setParameterList("list", (Collection<?>) paras[i]);
                } else {
                    query.setParameter(j, paras[i]);
                    j++;
                }
            }
        }
    }
}
然后,再回过头看一下之前写的PersonDao接口和PersonDaoImpl类是不是就可以简化成下面的呢?

PersonDao接口:

package com.hnu.scw.dao;

import com.hnu.scw.model.Person;
import org.springframework.stereotype.Repository;

@Repository
public interface PersonDao extends BaseDao<Person>{
   
}
PersonDaoImpl类:
package com.hnu.scw.dao.impl;
import com.hnu.scw.dao.PersonDao;
import com.hnu.scw.model.Person;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

/**
 * @author scw
 * @create 2017-12-19 15:17
 * @desc
 **/
@Repository
public class PersonDaoImp  extends BaseDaoImpl<Person> implements PersonDao{

    
}
    这样的话,如果每个不同的DAO需要有各自的方法,那么只需要在各自的接口中进行添加即可,而如果要用公共的方法的话,那么由于继承关系,就可以直接使用BaseDAO中的方法了,是不是就是Java中最经典的面向接口编程了呢?!!!!所以好好看看看看Mybatis和Hibernate中DAO层的封装区别-我写的这篇文章,你就会更加明白了!!!


    好了,,最基本的配置到这里就算完美的结束了,自己想着写这个也是因为,在看这个框架的源代码的时候,觉得,里面运用到了很多设计模式和比较好的编程思想,所以就特别进行了搭建环境,这样的话,对整个的框架就有一个大体的了解,知道每一层在干什么,什么业务是在哪一个框架和哪一层进行管理的,这样出问题了就会比较好的定位。。如果,文章中有问题,欢迎指正,还有其他的文章,欢迎大家去阅读哦,可以让你真正明白,从底层来看框架,真正的理解为什么要用这些,以及里面的知识点。
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值