网上有很多整合三大框架的Demo,我想对于初学者一定看的是云里雾里,博主也是小白一枚,为避免大家踩坑,特此奉上基于注解的Struts2+Spring2.5+hibernate3.5的整合案例。
新建工程:楼主用的是MyEclipse,Eclipse亦可,看个人喜好。
点击Finish
更改项目编码方式:右键项目—>选择Properties—>UTF-8
在lib目录下导入相关jar包,并build path
这里顺便提一句,数据库连接池用的是c3p0
那么为什么要用数据库连接池呢?
在Web开发中,如果要使用jdbc连接数据库,那么每次访问请求都必须建立连接——打开数据库——存取数据库——关闭连接等一系列步骤。
但是我们知道数据库的连接打开不仅费时,而且消耗比较多的系统资源。如果进行数据库操作的次数比较少,那么还不至于有多大的影响,但是假如频繁的进行数据库操作,那么系统的性能将会受到很大影响。
其次,是造成数据库“连接泄漏”。如果在某次使用或者某段程序中没有正确地关闭Connection、Statement和ResultSet资源,那么每次执行都会留下一些没有关闭的连接,这些连接失去了引用而不能得到重新使用,因此就造成了数据库连接的泄漏。
数据库连接的资源是宝贵而且是有限的,如果在某段使用频率很高的代码中出现这种泄漏,那么数据库连接资源将被耗尽,影响系统的正常运转。
为了解决上述问题,因此就引入了数据库连接池技术。用一句话概括数据库连接池技术那就是负责分配、管理和释放数据库连接。
一些常见的数据库连接池:C3P0,DBCP,Proxool,Druid
Proxool 最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况.
Druid 阿里巴巴的数据库连接池
导入配置文件,在项目下新建config,test资源包
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">
<context:component-scan base-package="com.liuzehui"></context:component-scan>
<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>
<property name="initialPoolSize" value="3"></property>
<property name="minPoolSize" value="3"></property>
<property name="maxPoolSize" value="5"></property>
<property name="acquireIncrement" value="3"></property>
<property name="maxStatements" value="8"></property>
<property name="maxStatementsPerConnection" value="5"></property>
<property name="maxIdleTime" value="1800"></property>
</bean>
<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" />
<constant name="struts.action.extension" value="action" />
<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">
<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>
<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 {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
@Test
public void testSessionFactory() {
SessionFactory sessionFactory = (SessionFactory) context
.getBean("sessionFactory");
System.out.println(sessionFactory);
}
}
测试成功,控制台打印结果:
org.hibernate.impl.SessionFactoryImpl@41a8dfb3
现在开始开始测试Spring和Struts2,先启动下服务器看能不能正常启动,我这里用的是Tomcat 7
信息: Server startup in 8977 ms
在刚才的test资源包下建立测试Action类
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 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 ;
}
实体映射文件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">
<hibernate-mapping>
<class name="com.liuzehui.entity.Role" table="ROLE">
<id name="id" type="java.lang.String">
<column name="ID" />
<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;
@Repository
public class RoleDaoImpl implements RoleDao {
@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
@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 name="test" class="testAction">
<result name="success">/test.jsp</result>
</action>
<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>
重启服务器 正常
提交表单
数据表
项目结构
测试事务是否回滚
打开RoleServiceImpl类
重启服务器,重新提交表单
错误提示说不能除以0
因为插入语句在1/0之前。现在我们查看数据库,看是否存入
刷新数据库,并没有插入新的语句
说明已回滚
@Scope(“prototype”)
因为Spring默认的是单例,Strust交给Spring管理加上这个注解,就能保证它是多例
@Transactional 基于注解的方式开启事务
如果在RoleServiceImpl层不加注解会报:
no hibernate session bound to thread 异常
原因是:是没有开启事务,因为当前session是从事务中获取的.
部分文字来源于网络,侵删