转s2sh三大框架整合过程(仅供参考)

 

三大框架顾名思义就是非常有名的Struts2 ,Hibernate,Spring,

框架整合的方法很多,现在我写一个非常简单的整合过程,相信大家一看就会!

这里使用的struts-2.2.1.1、hibernate-3.2.0、spring2.5.6

第一步,搭建Struts2环境

  1、导入struts2的jar包(直接把struts-blank项目下的依赖库coypy到自己项目中)

  2、 配置web.xml,增加struts2提供的过滤器(参考struts-blank项目)

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5"  3  xmlns="http://java.sun.com/xml/ns/javaee"  4  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  6  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  7  8 <filter>  9 <filter-name>struts2</filter-name> 10 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 11 </filter> 12 13 <filter-mapping> 14 <filter-name>struts2</filter-name> 15 <url-pattern>/*</url-pattern> 16 </filter-mapping> 17 18 </web-app>
复制代码

  3、建立包:com.qcf.struts.test,并增加普通java类,代码如下:

复制代码
 1 package com.qcft.struts.test;
 2 
 3 public class FirstAction {  4  5 private String msg;  6  7 public String execute() throws Exception{  8 System.out.println("FirstAction.test1()");  9 setMsg("为了让生活美好!"); 10 return "success"; 11  } 12 13 public String getMsg() { 14 return msg; 15  } 16 17 public void setMsg(String msg) { 18 this.msg = msg; 19  } 20 }
复制代码

  4、在src下增加struts.xml,并增加FirstAction类的配置内容:

复制代码
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC  3  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  4  "http://struts.apache.org/dtds/struts-2.0.dtd">  5  6 <struts>  7 <package name="default" namespace="/" extends="struts-default">  8 <action name="first" class="com。qcf.struts.test.FirstAction">  9 <result name="success">ok.jsp</result> 10 </action> 11 </package> 12 <!-- Add packages here --> 13 </struts>
复制代码

  5、增加ok.jsp页面,用来显示FirstAction中的属性msg:

复制代码
 1 <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
 2 <%@ taglib prefix="s" uri="/struts-tags" %>
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5 <head>  6 <title>测试struts2</title>  7 </head>  8 <body>  9 <s:property value="msg" /> 10 </body> 11 </html>
复制代码

  测试成功!

第二步:搭建Hibernate环境

  1、导入hibernate所需要的基本的jar包

  

  2、添加hibernate.cfg.xml配置文件

    打开etc目录,将hibernate.cfg.xml拷贝到项目src下

    修改配置文件hibernate.cfg.xml内容,结合etc/hibernate.properties(文件中搜索”mysql”),完成后配置内容如下:

复制代码
 1 <!DOCTYPE hibernate-configuration PUBLIC
 2     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 3  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  4 <hibernate-configuration>  5 <session-factory>  6 <property name="show_sql">true</property>  7 <property name="hibernate.dialect">  8  org.hibernate.dialect.MySQLDialect  9 </property> 10 <property name="connection.driver_class"> 11  com.mysql.jdbc.Driver 12 </property> 13 <property name="hibernate.connection.url"> 14  jdbc:mysql://localhost:3306/testhib 15 </property> 16 <property name="connection.username"> 17  root 18 </property> 19 <property name="connection.password"> 20  123456 21 </property> 22 </session-factory> 23 </hibernate-configuration>
复制代码

  3、新建pojo类(Plain Old Java Objects 简单的java对象,实际上就是我们讲的普通javabean对象):User

View Code

  4、增加映射文件User.hbm.xml(写法可以参考:eg/User.hbm.xml)

    映射文件hbm.xml说明了pojo类和表的对应关系,以及pojo类中属性和表中字段的对应关系。

    注:本映射文件增加到跟pojo同一个包中

复制代码
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC  3  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  4  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  5 <hibernate-mapping  6 package="com.qcf.hib.bean">  7 <class name="User" table="_user" lazy="true">  8 <id name="id">  9 <generator class="native"/> 10 </id> 11 <property name="name" type="java.lang.String" 12  not-null="true" 13  length="15" 14  column="_name"/> 15 <property name="birthday" type="java.util.Date" column="birthday"/> 16 </class> 17 </hibernate-mapping>
复制代码

  5、在hibernate.cfg.xml中增加User.hbm.xml文件的配置,让hibernate知道本映射关系。在<session-factory>元素下增加:

  <mapping resource="com/qcf/hib/bean/User.hbm.xml"/>

  6、修改hibernate.cfg.xml文件,在<session-factory>下增加hbm2ddl.auto的配置:

  <property name="hibernate.hbm2ddl.auto">update</property>

          create-drop: 运行时,先创建,运行完,在删除。

          create:每次运行前都会删除已有的。在创建。 测试时,可以使用create.

          update:映射文件和表。不会重新创建表及不会重新执行ddl语句,只会更新表中的记录。

          validate:看映射文件和表是不是对应,如果不对应,他也不会更新,会报错。经常用它,保险一些。

  7、增加Test.java测试类:

复制代码
 1 package com.bjsxt.hib.test;
 2 
 3 import java.util.Date;  4  5 import org.hibernate.Session;  6 import org.hibernate.SessionFactory;  7 import org.hibernate.cfg.Configuration;  8  9 import com.bjsxt.hib.bean.User; 10 11 public class Test { 12 public static void main(String[] args) { 13 Configuration conf = new Configuration().configure(); 14 SessionFactory factory = conf.buildSessionFactory(); 15 Session session = factory.openSession(); 16 User user = new User("高淇",new Date()); 17  session.save(user); 18  session.close(); 19  } 20 }
复制代码

  8、 上一次执行,我们发现表创建成功但是数据记录并没有插入表中。jdbc是自动提交,autocommit。hibernate缺省是false. 因此,我们必须很明确的开启事务才行。我们将Test.java文件内容修改如下:

复制代码
 1 package com.qcf.hib.test;
 2 
 3 import java.util.Date;  4  5 import org.hibernate.Session;  6 import org.hibernate.SessionFactory;  7 import org.hibernate.Transaction;  8 import org.hibernate.cfg.Configuration;  9 10 import com.bjsxt.hib.bean.User; 11 12 public class Test { 13 public static void main(String[] args) { 14 Configuration conf = new Configuration().configure(); 15 SessionFactory factory = conf.buildSessionFactory(); 16 Session session = factory.openSession(); 17 Transaction transaction = session.beginTransaction(); 18 19 User user = new User("高淇",new Date()); 20  session.save(user); 21 22 transaction.commit();//保存之后,关闭session之前,显示提交事务.(必须调用,不然不会提交。即使session关闭,也不回自动提交) 23  session.close(); 24  } 25 }
复制代码

  测试成功,数据库中也有相应的数据添加成功!

第三步:搭建Spring环境

  1、导入Spring所需要的jar包

    spring.jar这一个即可!

  2、写一个测试类

复制代码
1 package com.qcf.test;
2 
3 public class UserDao { 4 public void add(String uname,String pwd){ 5 System.out.println("增加一个用户!"); 6  } 7 }
复制代码

  3、增加配置文件beans.xml,内容如下:

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans  3 xmlns="http://www.springframework.org/schema/beans"  4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5 xmlns:p="http://www.springframework.org/schema/p"  6 xsi:schemaLocation="http://www.springframework.org/schema/beans  7 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">  8  9 <bean id="userDao" class="com.sxt.test.UserDao"></bean> 10 11 </beans>
复制代码

  

通过上面的配置文件,spring框架知道了UserDao类的存在!可以通过反射机制自动将UserDao类的对象new出! 所以注意托管给spring的类必须符合基本的javabean规范:
1.    如果有属性,则必须有相应的get/set方法。 
2.    必须要无参的构造器 

  4、建立Test.java类

 

复制代码
 1 package com.qcf.test;
 2 
 3 import org.springframework.context.ApplicationContext;  4 import org.springframework.context.support.ClassPathXmlApplicationContext;  5  6 public class Test {  7 public static void main(String[] args){  8 // UserDao userDao = new UserDao();  9 // userDao.add("a", "123"); 10 11 ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"beans.xml"}); 12 UserDao userdao = (UserDao) context.getBean("userDao"); 13 userdao.add("d", "222"); 14  } 15 }
复制代码

  5、上面的代码中,我们可以使用context.getBean("userDao")代替了 new UserDao(这样的代码,也就是spring内部有个工厂类,替我们完成了new对象的操作!而这个工厂类是通过读取beans.xml文件知道了字 符串”userDao”和com.sxt.test.UserDao类之间的关系!

  直接运行Test.java类即可。

第四步:已经将三个框架各自搭建完毕。现在先整合Struts和spring

  整合struts2和spring非常简单只需两步:

  1、在web.xml下面添加一个spring的过滤器(添加到最上面,在struts2的配置文件上面)

复制代码
1     <listener>
2       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 3 </listener> 4 <context-param> 5 <param-name>contextConfigLocation</param-name> 6 <param-value>classpath:application.xml</param-value> 7 </context-param> 
复制代码

  2、添加一个struts-spring.plus的插件,这个可以再struts官方提供的jar中即可找到

  注:action中的class不用填写全名,直接写spring中注册的id即可,如:testAction

1     <package name="default" namespace="/" extends="struts-default"> 2 <action name="testAction" class="testAction"> 3 <result name="success">index.jsp</result> 4 </action> 5 </package>

 第五步:整合spring和hibernate

  1、首先将web.xml添加头文件

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"  3  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  4  xmlns:aop="http://www.springframework.org/schema/aop"  5  xmlns:tx="http://www.springframework.org/schema/tx"  6  xmlns:context="http://www.springframework.org/schema/context"  7  xsi:schemaLocation="  8 http://www.springframework.org/schema/beans  9 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 10 http://www.springframework.org/schema/tx 11 http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 12 http://www.springframework.org/schema/aop 13 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 14  http://www.springframework.org/schema/context 15  http://www.springframework.org/schema/context/spring-context-2.5.xsd 16 ">
复制代码

  2、配置sessionFactory(配置了C3P0数据库连接池)

复制代码
    <!-- 导入jdbc.properties -->
    <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置sessionfactory --> <bean name="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 配置application.xml路径 --> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> <!-- 配置c3p0连接池 --> <property name="dataSource"> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 数据库连接信息 --> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <!-- 其它配置 --> <!-- 数据库初始化时获取三个链接,取值应该在min --> <property name="initialPoolSize" value="3"></property> <!-- 连接池中保留的最小连接数 --> <property name="minPoolSize" value="3"></property> <!-- 连接池中保留的最大连接数 --> <property name="maxPoolSize" value="10"></property> <!-- 当连接池中连接耗尽时c3p0一次获取的连接数 --> <property name="acquireIncrement" value="3"></property> <!-- 配置数据源内加载的preparestatement数量 --> <property name="maxStatements" value="3"></property> <!-- 单个连接所拥有的最大statments缓存数 --> <property name="maxStatementsPerConnection" value="3"></property> <!-- 设置最大空闲时间不使用自动丢弃,如果为0永远不丢弃 --> <property name="maxIdleTime" value="1800"></property> </bean> </property> </bean>
复制代码

  3、配置事务管理(XML)

复制代码
 1 <!-- 配置声明事务管理 -->
 2     <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  3 <property name="sessionFactory" ref="sessionFactory"></property>  4 </bean>  5 <!-- AOP核心配置 -->  6 <aop:config>  7 <!-- 定义aop切面 -->  8 <aop:pointcut expression="execution(public * com.qcf.test.*.*(..))" id="testa"/>  9 <aop:advisor advice-ref="txadvice" pointcut-ref="testa"/> 10 </aop:config> 11 <!-- 定义切割方法 --> 12 <tx:advice id="txadvice" transaction-manager="txManager"> 13 <tx:attributes> 14 <tx:method name="save*" propagation="REQUIRED"/> 15 </tx:attributes> 16 </tx:advice> 17 <!-- -->
复制代码

  配置事务(annotation)

复制代码
 1      <!-- 自动扫面
 2       -->
 3      <context:component-scan base-package="com.qcf"></context:component-scan>  4  5  6 <!-- 配置事务 -->  7 <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  8 <property name="sessionFactory" ref="sessionFactory"></property>  9 </bean> 10 11 <!-- annotation配置事务 --> 12 <tx:annotation-driven transaction-manager="txManager"/>
复制代码

  测试方法:

View Code

  4、配置HibernateTemplate

   HibernateTemplate类可让我们将Hibernate的使用模板化,使我们对hibernate的调用更加简单!使用他,我们只需要在配置文件中增加:

 

1     <!-- 配置hibernatetempter -->
2     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> 3 <property name="sessionFactory" ref="sessionFactory"></property> 4 </bean> 5 

 

  hibernateTemplate常用方法:  

    ◦ void delete(Object entity):删除指定持久化实例

    ◦ deleteAll(Collection entities):删除集合内全部持久化类实例

    ◦ find(String queryString):根据HQL查询字符串来返回实例集合

    ◦ get(Class entityClass, Serializable id):根据主键加载特定持久化类的实例

    ◦ save(Object entity):保存新的实例

    ◦ saveOrUpdate(Object entity):根据实例状态,选择保存或者更新

    ◦ update(Object entity):更新实例的状态,要求entity是持久状态

    ◦ setMaxResults(int maxResults):设置分页的大小(setFirstResult方法)

 

  HibernateTemplate的典型用法:

    1.   需要直接获得session对象的处理方式(比如:分页处理)
复制代码
1         hibernateTemplate.execute(new HibernateCallback() {
2             
3             public Object doInHibernate(Session session) throws HibernateException, 4  SQLException { 5 // TODO Auto-generated method stub 6 session.save(new User(0, "lisi", 19)); 7 return null; 8  } 9 });
复制代码

 

 

 

 

      2. 不需要直接获得session对象的情况

复制代码
 1     public List<User> getAllUser(){
 2             List<User> list=hibernateTemplate.find("from User");
 3 for (int i = 0; i < list.size(); i++) {  4  System.out.println(list.get(i).getId());  5  6  }  7  8 List list2 = hibernateTemplate.find("from User where name=? and id=?", new Object[]{"zhangsan",1});  9 for (int i = 0; i < list2.size(); i++) { 10  System.out.println(list2.get(i).toString()); 11  } 12 13 return null; 14 }
复制代码

  5、HibernateDaoSupport

    封装了HibernateTemplate!常见用法如下:

 

复制代码
public class UserDaoImpl3 extends HibernateDaoSupport  {
    public void add(User u) { this.getHibernateTemplate().save(u); } } public class UserDaoImpl3 extends HibernateDaoSupport { public void add(User u) { Session s = this.getSession(); s.save(u); releaseSession(s); //手动释放session资源  } }
复制代码

 

  6、JDBCTemplate的使用

   dbcTemplate类是spring为了让我们更加容易使用jdbc而提供的封装。JdbcTemplate对jdbc操作做了简单的封装。内部也使用了类似HibernateTemplate中使用的模板方法模式。JdbcTemplate在工作中用的不多。本节为自学内容,目的是让大家开阔眼界。

  要使用JdbcTemplate,我们必须要在spring中增加配置:

 

1 <!--配置一个JdbcTemplate实例-->  
2 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 3 <property name="dataSource" ref="dataSource"/> 4 </bean>

 

  测试类如下:

View Code

  7、OpenSessionInView管理session

 

  OpenSessionInViewFilterSpring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开 HibernateSession,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。 

 

由于Hibernate引入了Lazy Load特性,使得脱离HibernateSession周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个 LazyLoadException。所以为了解决这个问题,Spring引入了这个Filter,使得HibernateSession的生命周期变长。

 

OpenSessionInViewFilter:org.springframework.orm.hibernate3.support.OpenSessionInViewFilter]是 Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开HibernateSession,一直保持这个 Session,直到这个请求结束,具体是通过一个Filter来实现的。 

 

  由于Hibernate引入了Lazy Load特性,使得脱离HibernateSession周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个 LazyLoadException。所以为了解决这个问题,Spring引入了这个Filter,使得HibernateSession的生命周期 变长。 

 

有两种方式可以配置实现OpenSessionInView,分别是 OpenSessionInViewInterceptorOpenSessionInViewFilter,功能完全相同,只不过一个在 web.xml配置,另一个在application.xml配置而已。

 

  我们可以在web.xml中配置opensessioninview,代码如下:

 

复制代码
 1 <!-- 配置Spring自动管理Session. 要配置到struts过滤器之前!-->  
 2  <filter>  3 <filter-name>hibernateSessionFilter</filter-name>  4 <filter-class>  5  org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  6 </filter-class>  7 </filter>  8 <filter-mapping>  9 <filter-name>hibernateSessionFilter</filter-name> 10 <url-pattern>/*</url-pattern> 11 </filter-mapping>
复制代码

 

  8、ThreadLocal模式管理session

我们知道Session是由SessionFactory负责创建的,而SessionFactory的实现是线程安全的,多个并发的线程可以同时访问一 个SessionFactory并从中获取Session实例,那么Session是否是线程安全的呢?很遗憾,答案是否定的。

早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了 一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单, 就是为每一个使用某变量的线程都提供一个该变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像 每一个线程都完全拥有一个该变量。 

ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。

比如下面的示例实现(为了简单,没有考虑集合的泛型)

 

复制代码
 1 public  class  ThreadLocal  {
 2     private  Map  values  =  Collections.synchronizedMap(new  HashMap());  3     public  Object  get()  {  4    Thread  currentThread  =  Thread.currentThread();   5     Object  result  =  values.get(currentThread);   6      if(result  ==  null&&!values.containsKey(currentThread))  {  7        result  =  initialValue();  8        values.put(currentThread,  result);   9          } 10          return  result;  11         } 12     public  void  set(Object  newValue)  { 13      values.put(Thread.currentThread(),  newValue); 14        } 15      public  Object  initialValue()  { 16      return  null17      } 18    }
复制代码

 

那麽具体如何利用ThreadLocal来管理Session呢?Hibernate官方文档手册的示例之中,提供了一个通过ThreadLocal维护Session的好榜样:

 

复制代码
 1 public  class  HibernateUtil  {
 2   public  static  final  SessionFactory  sessionFactory;  3     static  {  4       try  {  5         sessionFactory  =  new  Configuration().configure().buildSessionFactory();  6         } catch (Throwable  ex) {  7           throw  new  ExceptionInInitializerError(ex);  8            }  9          } 10    public static final ThreadLocal<Session>session=new ThreadLocal<Session>(); 11    public  static  Session  currentSession()  throws  HibernateException  { 12        Session  s  =  session.get(); 13        if(s  ==  null)  { 14          s  =  sessionFactory.openSession(); 15          session.set(s); 16           } 17          return  s; 18          } 19    public  static  void  closeSession()  throws  HibernateException  { 20          Session  s  =  session.get(); 21         if(s  !=  null)  { 22            s.close(); 23           } 24           session.set(null); 25         } 26      }
复制代码

 

只要借助上面的工具类获取Session实例,我们就可以实现线程范围内的Session共享,从而避免了线程中频繁的创建和销毁Session实例。当 然,不要忘记在用完后关闭Session。写到这里,想再多说一些,也许大多数时候我们的DAO并不会涉及到多线程的情形,比如我们不会将DAO的代码写 在Servlet之中,那样不是良好的设计,我自己通常会在service层的代码里访问DAO的方法。但是我还是建议采用以上的工具类来管理 Session,毕竟我们不能仅仅考虑今天为自己做什么,还应该考虑明天为自己做什么!

 

转载于:https://www.cnblogs.com/janeaiai/p/5749925.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值