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

 1 package com.qcf.hib.bean;
 2
 3 import java.util.Date;
 4
 5 public class User {
 6     private int id;
 7     private String name;
 8     private Date birthday;
 9
10     public int getId() {
11         return id;
12     }
13     public void setId(int id) {
14         this.id = id;
15     }
16     public String getName() {
17         return name;
18     }
19     public void setName(String name) {
20         this.name = name;
21     }
22     public Date getBirthday() {
23         return birthday;
24     }
25     public void setBirthday(Date birthday) {
26         this.birthday = birthday;
27     }
28     public User(int id, String name, Date birthday) {
29         super();
30         this.id = id;
31         this.name = name;
32         this.birthday = birthday;
33     }
34     public User(String name, Date birthday) {
35         super();
36         this.name = name;
37         this.birthday = birthday;
38     }
39
40     public User() {
41     }
42 }

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

  测试方法:

 1 package com.qcf.dao.impl;
 2
 3 import javax.annotation.Resource;
 4
 5 import org.hibernate.Session;
 6 import org.hibernate.SessionFactory;
 7 import org.springframework.stereotype.Controller;
 8 import org.springframework.stereotype.Service;
 9 import org.springframework.transaction.annotation.Transactional;
10
11 import com.qcf.dao.UserDao;
12 import com.qcf.po.User;
13
14 @Service
15 public class UserDaoImpl implements UserDao  {
16
17     @Resource
18     private SessionFactory sessionFactory;
19     /**
20      * 增加用户
21      */
22     @Transactional
23     public void addUser() {
24         // TODO Auto-generated method stub
25         Session session=sessionFactory.getCurrentSession();
26         session.save(new User(0, "zhangsan", 19));
27         session.save(new User(0, "zhan", 19));
28
29     }
30     public SessionFactory getSessionFactory() {
31         return sessionFactory;
32     }
33     public void setSessionFactory(SessionFactory sessionFactory) {
34         this.sessionFactory = sessionFactory;
35     }
36
37
38
39 }

  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>

  测试类如下:

 1 package com.qcf.dao.impl;
 2
 3 import java.sql.ResultSet;
 4 import java.sql.SQLException;
 5 import java.util.List;
 6 import java.util.Map;
 7
 8 import javax.annotation.Resource;
 9
10 import org.springframework.context.ApplicationContext;
11 import org.springframework.context.support.ClassPathXmlApplicationContext;
12 import org.springframework.jdbc.core.JdbcTemplate;
13 import org.springframework.jdbc.core.RowMapper;
14 import org.springframework.stereotype.Component;
15
16 import com.sxt.po.User;
17
18 /**
19  * 用来测试jdbcTemplate的用法
20  * @author Administrator
21  *
22  */
23 @Component("userDao")
24 public class UserDaoImpl {
25     @Resource
26     private JdbcTemplate jdbcTemplate;
27
28     public void testInsertUser(User user){
29         jdbcTemplate.update("insert into user (uname,pwd) values (?,?)",new Object[]{user.getUname(),user.getPwd()});
30     }
31
32     public void testUpdateUser(String pwd,int id){
33         jdbcTemplate.update("update user set pwd=? where id=?",new Object[]{pwd,id});
34     }
35     public void deleteUser(int id){
36         jdbcTemplate.update("delete from user where id=?",new Object[]{id});
37     }
38
39     public void testGetUserById(int id){
40         User user = (User) jdbcTemplate.queryForObject("select id,uname,pwd from user where id=?", new Object[]{id}, new RowMapper(){
41             @Override
42             public Object mapRow(ResultSet rs, int no) throws SQLException {
43                 User u = new User();
44                 u.setId(rs.getInt("id"));
45                 u.setUname(rs.getString("uname"));
46                 u.setPwd(rs.getString("pwd"));
47                 return u;
48             }});
49
50         System.out.println(user.getUname());
51     }
52
53     public void testGetUsers(){
54         List<Map> list = jdbcTemplate.queryForList("select * from user where id>?",new Object[]{1});
55         for (Map map : list) {
56             System.out.println(map.get("uname"));
57         }
58     }
59     public static void main(String[] args) {
60         ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
61         UserDaoImpl ud = (UserDaoImpl) context.getBean("userDao");
62         User u = new User();
63         u.setUname("sss");
64         u.setPwd("123");
65 //        ud.testInsertUser(u);
66 //        ud.testDeleteUser(2);
67         ud.testGetUsers();
68     }
69
70 }

  7、OpenSessionInView管理session

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

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

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

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

有两种方式可以配置实现OpenSessionInView,分别是 OpenSessionInViewInterceptor和OpenSessionInViewFilter,功能完全相同,只不过一个在 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  null; 
17      }
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,毕竟我们不能仅仅考虑今天为自己做什么,还应该考虑明天为自己做什么!

时间: 2024-11-03 18:29:17

s2sh三大框架整合过程(仅供参考)的相关文章

转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 v

安装oracle 11g详细过程仅供参考

SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)(转)

使用 SSM ( Spring . SpringMVC 和 Mybatis )已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录 SSM 整合的过程, 这次刚刚好基于自己的一个小项目重新搭建了一次,而且比项目搭建的要更好一些.以前解决问题的过程和方法并没有及时记录,以后在自己的小项目中遇到我再整理分享一下. 这次 , 先说说 三大框架整合过程 .个人认为使用框架并不是很难,关键要理解其思想,这对于我们提高编程水平很有帮

SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)

使用SSM(Spring.SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录SSM整合的过程,这次刚刚好基于自己的一个小项目重新搭建了一次,而且比项目搭建的要更好一些.以前解决问题的过程和方法并没有及时记录,以后在自己的小项目中遇到我再整理分享一下.这次,先说说三大框架整合过程.个人认为使用框架并不是很难,关键要理解其思想,这对于我们提高编程水平很有帮助.不过,如果用都不会,谈思想就

SSM三大框架整合详细教程Spring+SpringMVC+MyBatis+maven

[源码获取地址] 使用SSM(Spring.SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录SSM整合的过程,这次刚刚好基于自己的一个小项目重新搭建了一次,而且比项目搭建的要更好一些.以前解决问题的过程和方法并没有及时记录,以后在自己的小项目中遇到我再整理分享一下.这次,先说说三大框架整合过程.个人认为使用框架并不是很难,关键要理解其思想,这对于我们提高编程水平很有帮助.不过,如果

SSM三大框架整合详细教程

使用SSM(Spring.SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录SSM整合的过程,这次刚刚好基于自己的一个小项目重新搭建了一次,而且比项目搭建的要更好一些.以前解决问题的过程和方法并没有及时记录,以后在自己的小项目中遇到我再整理分享一下.这次,先说说三大框架整合过程.个人认为使用框架并不是很难,关键要理解其思想,这对于我们提高编程水平很有帮助.不过,如果用都不会,谈思想就

SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)【转】

使用SSM(Spring.SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录SSM整合的过程,这次刚刚好基于自己的一个小项目重新搭建了一次,而且比项目搭建的要更好一些.以前解决问题的过程和方法并没有及时记录,以后在自己的小项目中遇到我再整理分享一下.这次,先说说三大框架整合过程.个人认为使用框架并不是很难,关键要理解其思想,这对于我们提高编程水平很有帮助.不过,如果用都不会,谈思想就

struts2,spring,hibernate三大框架整合

本文利用mvc三层架构来讲述S2SH三大框架整合的步骤: 1.建立好包结构,建立好的包结构如下: 2.导入相应的jar包 (1)struts2用到的jar包 (2)spring用到的jar包 (3)hibernate用到的jar包 (4)mysql驱动包,junit和struts2插件 (5)公共包,例如日志 commons-logging-1.1.3.jar log4j-1.2.17.jar slf4j-log4j12-1.5.0.jar 最后经过整理的jar包清单如下: antlr-2.7.

(转)hibernate-5.0.7+struts-2.3.24+spring-4.2.4三大框架整合

http://blog.csdn.net/yerenyuan_pku/article/details/70040220 SSH框架整合思想 三大框架应用在JavaEE三层结构,每一层都用到了不同的框架.SSH框架整合的思想可用下图来表示:  SSH框架的整合方式一:零障碍整合(带有Hibernate配置文件) 我们先整合Struts2和Spring这两个框架,再整合Spring和Hibernate这两个框架. 整合Struts2和Spring框架 整合Struts2和Spring这两个框架要解决