整合Struts2+Spring2.5+Hibernate3.5

网上有很多整合三大框架的Demo,我想对于初学者一定看的是云里雾里,博主也是小白一枚,为避免大家踩坑,特此奉上基于注解的Struts2+Spring2.5+hibernate3.5的整合案例。

新建工程:楼主用的是MyEclipse,Eclipse亦可,看个人喜好。

点击Finish

更改项目编码方式:右键项目—>选择Properties—>UTF-8

整合Struts2+Spring2.5+Hibernate3.5_第1张图片

在lib目录下导入相关jar包,并build path

整合Struts2+Spring2.5+Hibernate3.5_第2张图片

这里顺便提一句,数据库连接池用的是c3p0

那么为什么要用数据库连接池呢?

在Web开发中,如果要使用jdbc连接数据库,那么每次访问请求都必须建立连接——打开数据库——存取数据库——关闭连接等一系列步骤。

但是我们知道数据库的连接打开不仅费时,而且消耗比较多的系统资源。如果进行数据库操作的次数比较少,那么还不至于有多大的影响,但是假如频繁的进行数据库操作,那么系统的性能将会受到很大影响。

其次,是造成数据库“连接泄漏”。如果在某次使用或者某段程序中没有正确地关闭Connection、Statement和ResultSet资源,那么每次执行都会留下一些没有关闭的连接,这些连接失去了引用而不能得到重新使用,因此就造成了数据库连接的泄漏。

数据库连接的资源是宝贵而且是有限的,如果在某段使用频率很高的代码中出现这种泄漏,那么数据库连接资源将被耗尽,影响系统的正常运转。

为了解决上述问题,因此就引入了数据库连接池技术。用一句话概括数据库连接池技术那就是负责分配、管理和释放数据库连接。

一些常见的数据库连接池:C3P0,DBCP,Proxool,Druid

Proxool 最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况.

Druid 阿里巴巴的数据库连接池

导入配置文件,在项目下新建config,test资源包

整合Struts2+Spring2.5+Hibernate3.5_第3张图片

右键项目,Build path—>configure build path—>Source

整合Struts2+Spring2.5+Hibernate3.5_第4张图片

Spring配置文件: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" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <!-- 自动扫描与装配bean -->
    <context:component-scan base-package="com.liuzehui"></context:component-scan>

    <!-- 导入外部的properties配置文件 -->
    <context:property-placeholder location="classpath:jdbc.properties" />


    <!-- 配置数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- =========== 数据库连接信息 =========== -->
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="driverClass" value="${driverClass}"></property>
        <property name="user" value="${username}"></property>
        <property name="password" value="${password}"></property>
        <!-- =========== 连接池的管理配置 =========== -->
        <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
        <property name="initialPoolSize" value="3"></property>
        <!--连接池中保留的最小连接数。Default: 3 -->
        <property name="minPoolSize" value="3"></property>
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="5"></property>
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement" value="3"></property>
        <!-- 控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
        <property name="maxStatements" value="8"></property>
        <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
        <property name="maxStatementsPerConnection" value="5"></property>
        <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="1800"></property>
    </bean>


    <!-- 配置SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
    </bean>


    <!-- 配置声明式的事务管理(采用基于注解的方式) -->
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    <tx:annotation-driven transaction-manager="txManager" />

</beans>

Hibernate配置文件:hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>

    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQL5InnoDBDialect
    </property>

    <!-- 其他配置信息 -->
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">update</property>

    <!-- 声明映射文件 -->

</session-factory>
</hibernate-configuration>

jdbc.properties配置文件:jdbc.properties

jdbcUrl = jdbc:mysql:///ssh_test
driverClass = com.mysql.jdbc.Driver
username = root
password =*******

password,填写你的数据库密码

日志文件:log4j.properties

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n


log4j.rootLogger=warn, stdout

log4j.logger.com.liuzehui=debug

Struts2配置文件:struts.xml

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

<struts>
    <!-- 配置为开发模式 -->
    <constant name="struts.devMode" value="true" />
    <!-- 把action扩展名改为.action,可以根据自己的习惯修改 -->
    <constant name="struts.action.extension" value="action" />
    <!-- 把主题设为simple -->
    <constant name="struts.ui.theme" value="simple" />

    <package name="default" namespace="/" extends="struts-default">

    </package>

</struts>

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">


    <!-- 配置Spring的用于初始化ApplicationContext对象的监听器 -->
    <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>
    </context-param>


    <!-- 配置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>


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

ok,导好配置文件之后,现在开始一步一步测试

在test资源包包下建立测试类

先来测试Spring整合Hibernate:因为sessionFactory整合在Spring的配置文件中,所以就先来测它

package com.liuzehui.test;

import org.hibernate.SessionFactory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
    // 加载spring容器
    ApplicationContext context = new ClassPathXmlApplicationContext(
            "applicationContext.xml");

    // 测试SessionFactory
    @Test
    public void testSessionFactory() {
        // 从Spring容器中拿到bean
        SessionFactory sessionFactory = (SessionFactory) context
                .getBean("sessionFactory");
        // 打印sessionFactory,看是否有这个对象
        System.out.println(sessionFactory);
    }

}

测试成功,控制台打印结果:

org.hibernate.impl.SessionFactoryImpl@41a8dfb3

现在开始开始测试Spring和Struts2,先启动下服务器看能不能正常启动,我这里用的是Tomcat 7

信息: Server startup in 8977 ms

在刚才的test资源包下建立测试Action类

整合Struts2+Spring2.5+Hibernate3.5_第5张图片

package com.liuzehui.test;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;

@Controller
@Scope("prototype")
public class TestAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        System.out.println("run....");
        return SUCCESS;
    }

}

在Struts.xml配置文件中加入对于的action

<package name="default" namespace="/" extends="struts-default">

        <!-- 配置测试用的action -->
        <action name="test" class="testAction">
            <result name="success">/test.jsp</result>
        </action>

    </package>

在WebRoot下建立test.jsp

访问 http://localhost:8080/S2S3H4/test.action

页面访问结果:

控制台输出:

run....

OK,前面测试成功之后,现在整合SSH

建立数据库,由上jdbc.properties配置文件可知,我的数据库名为ssh_test,建库时,指定编码为utf-8

在src资源包下新建一个实体类

package com.liuzehui.entity;

/*** * * 角色 */
public class Role {

    private String id ;
    private String name ;
    //setter getter方法
}

实体映射文件role.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-1-29 16:35:23 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.liuzehui.entity.Role" table="ROLE">
        <id name="id" type="java.lang.String">
            <column name="ID" />
            <!-- 主键生成策略UUID -->
            <generator class="uuid" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
    </class>
</hibernate-mapping>

在hibernate.cfg.xml文件中配置映射关系

<!-- 声明映射文件 -->
<mapping resource="com/liuzehui/entity/Role.hbm.xml" />

编写Dao

package com.liuzehui.dao;

import com.liuzehui.entity.Role;

public interface RoleDao {
    // 添加角色
    public void save(Role role);

}

编写Dao实现类

package com.liuzehui.dao.impl;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.liuzehui.dao.RoleDao;
import com.liuzehui.entity.Role;

//添加到spring容器中
@Repository
public class RoleDaoImpl implements RoleDao {

    // 注入sessionFactory
    @Autowired
    private SessionFactory sessionFactory;

    /** * 保存 */
    public void save(Role role) {
        sessionFactory.getCurrentSession().save(role);
    }

}

编写service层

package com.liuzehui.service;

import com.liuzehui.entity.Role;

public interface RoleService {
    // 添加角色
    public void save(Role role);
}

编写Service层实现类

package com.liuzehui.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.liuzehui.dao.RoleDao;
import com.liuzehui.entity.Role;
import com.liuzehui.service.RoleService;

@Service
// 添加到spring容器中
@Transactional
// 开启事务
public class RoleServiceImpl implements RoleService {

    @Autowired
    // 自动注入
    private RoleDao roleDao;

    @Override
    public void save(Role role) {
        roleDao.save(role);
    }

}

编写控制层

package com.liuzehui.action;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.liuzehui.entity.Role;
import com.liuzehui.service.RoleService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@Controller
@Scope("prototype") 
public class RoleAction extends ActionSupport implements ModelDriven<Role> {

    //必须实例化
    private Role role = new Role();

    //获取传来的表单数据
    @Override
    public Role getModel() {
        return role;
    }

    @Autowired
    private RoleService roleService;

    /** * 保存 * @return */
    public String save(){
        roleService.save(role);
        return "save_ok";
    }

}

配置Struts.xml文件

<package name="default" namespace="/" extends="struts-default">

        <!-- 配置测试用的action -->
        <action name="test" class="testAction">
            <result name="success">/test.jsp</result>
        </action>

        <!-- role -->

        <action name="role_*" method="{1}" class="roleAction">
            <result name="save_ok">/WEB-INF/jsp/roleAction/save.jsp</result>
        </action>

    </package>

在/WEB-INF/jsp/roleAction/路径下新建save.jsp页面

<h3>添加成功!</h3>

在index.jsp上提交表单

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<% String path = request.getContextPath(); %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>

        <form action="<%=path%>/role_save.action">
            用户名:<input type="text" name="name">
            <input type="submit" value="提交">
        </form>

  </body>
</html>


重启服务器 正常

提交表单

整合Struts2+Spring2.5+Hibernate3.5_第6张图片

数据表

这里写图片描述

项目结构

整合Struts2+Spring2.5+Hibernate3.5_第7张图片

测试事务是否回滚

打开RoleServiceImpl类

整合Struts2+Spring2.5+Hibernate3.5_第8张图片

重启服务器,重新提交表单

整合Struts2+Spring2.5+Hibernate3.5_第9张图片

错误提示说不能除以0

因为插入语句在1/0之前。现在我们查看数据库,看是否存入

刷新数据库,并没有插入新的语句

这里写图片描述

说明已回滚

@Scope(“prototype”)

因为Spring默认的是单例,Strust交给Spring管理加上这个注解,就能保证它是多例

@Transactional 基于注解的方式开启事务

如果在RoleServiceImpl层不加注解会报:

no hibernate session bound to thread 异常

原因是:是没有开启事务,因为当前session是从事务中获取的.

部分文字来源于网络,侵删

你可能感兴趣的:(eclipse,spring,Hibernate,struts,Path)