网上有很多整合三大框架的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 .log 4j.ConsoleAppender
log4j.appender .stdout .Target =System.out
log4j.appender .stdout .layout =org.apache .log 4j.PatternLayout
log4j.appender .stdout .layout .ConversionPattern =%d{ABSOLUTE} %5 p %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 @41 a8dfb3
现在开始开始测试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是从事务中获取的.
部分文字来源于网络,侵删