手把手教你如何玩转SSH(Spring+SpringMVC+Hibernate)

来源:互联网 发布:cs1.6显示网络 编辑:程序博客网 时间:2024/06/05 03:13

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

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

第一步:导包

    咳咳,别看这个工作简单,然而蕴含的内容就是很多的,因为包如果导错了,那么后期构建的时候,你就会出现很多莫名其妙的问题,所以包一定要注意。首先,要保证包的版本最好处于相近的版本,而别一个是用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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsdhttp://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/beanshttp://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 **/@Controllerpublic 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 **/@Servicepublic 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 **/@Repositorypublic 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> */@Repositorypublic 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;@Repositorypublic 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 **/@Repositorypublic class PersonDaoImp  extends BaseDaoImpl<Person> implements PersonDao{    }
这样的话,如果每个不同的DAO需要有各自的方法,那么只需要在各自的接口中进行添加即可,而如果要用公共的方法的话,那么由于继承关系,就可以直接使用BaseDAO中的方法了,是不是就是Java中最经典的面向接口编程了呢?!!!!所以好好看看看看Mybatis和Hibernate中DAO层的封装区别-我写的这篇文章,你就会更加明白了!!!

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

原创粉丝点击