SSH框架网上商城项目第1战之整合Struts2、Hibernate4.3和Spring4.2


       本文开始做一个网上商城的项目,首先从搭建环境开始,一步步整合S2SH。这篇博文主要总结一下如何整合Struts2、Hibernate4.3和Spring4.2。

        整合三大框架得先从搭建各部分环境开始,也就是说首先得把Spring,Hibernate和Struts2的环境搭建好,确保它们没有问题了,再做整合。这篇博文遵从的顺序是:先搭建Spring环境-->然后搭建Hibernate环境--> 整合Spring和Hibernate --> 搭建Struts2环境 --> 整合Spring和Struts2。

1. 整个项目jar包的管理

        Spring的jar包很多,开发的时候建议将它们分个类,然后依次添加到User Library,方便管理,也一目了然。这里我总结一下整个SSH所需要的基本jar包,看下图:


        从图中可以看出,首先将Spring的jar分为四类:spring-4.2.4-core、spring-4.2.4-aop、spring-4.2.4-persistence以及spring-4.2.4-web。将spring的核心包都放到core中,与aop相关的都放到aop中,与持久化(与Hibernate整合)相关的放到persistence中,与web(与struts2整合)相关的放到web中。每个部分都有哪些jar包呢?请看下面的截图:

  


        注:以上每个分类的包中,并非包含原来包中所有的jar,有些jar文件并没有用到,等具体项目需要的时候再往里加就行了,上图是保证项目的环境可以搭建所需要的的最基本的jar包。

2.搭建Spring环境

       上面的jar包截图是最后整合好的所有jar包,刚开始搭建环境的时候不需要一次性全部加进来,可以一点一点的加,这样也更利于理解每个部分的jar包都有什么作用,当然,一次都加进来也是可以的。

2.1 添加配置文件beans.xml和相应的jar包

        新建一个工程,然后添加在User Library中添加自己的库,这里主要添加两个,即spring-4.2.4-core和spring4.2.4-aop,添加jar包不再赘述。添加完了后,在src目录下添加beans.xml文件,这个文件的模板网上很多,Spring自带的例子里也有,考一份过来就行,见下图:


2.2 测试Spring的IoC环境

        我们写一个普通的java类java.util.Date类来测试一下Spring IoC是否正常,如果在测试程序中能正常注入,则说明Spring的IoC环境搭建成功,下面我们写一个测试用例:

/** 
 * @Description TODO(采用Spring的注解调试,仅仅支持Spring3.1及以上) 
 * @author Ni Shengwu 
 * 
 */ 
/* 
 * Spring3.1后多了个spring-test-4.2.4.RELEASE.jar包,这个jar包专门用来支持JUnit基于注解的测试的,该jar包在spring-4.2.4-core中 
 * 该jar包里有个SpringJUnit4ClassRunner.class,用@RunWith注解加进来即可 
 * 
 * 注解@ContextConfiguration表示将ApplicationContext对象注入进来,就不用像以往那样在测试程序里先new了,直接使用 
 */ 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations="classpath:beans.xml") 
public class SSHTest { 
 
 @Resource 
 private Date date; 
 
 @Test //测试Spring IOC的开发环境 
 public void springIoc() { 
 System.out.println(date); 
 } 
} 

        最后能正常输出:Thu Apr 28 22:45:13 CST 2016。说明Date对象已经被Spring给注入进来了,从而验证了Spring IoC功能正常,为此,Spring的环境搭建完成。

3. 搭建Hibernate环境

        Hibernate的环境搭建相比于Spring要复杂一些,因为用到了MyEclipse中的逆向工程。我们按以下步骤来搭建Hibernate开发环境:

3.1 添加相应的jar包

        这里主要是向User Library中添加两项jar包:hibernate4.3.11和MySQL驱动包mysql-connector-java-5.1.26,不再赘述。

3.2 新建数据库和表

drop database if exists shop; 
create database shop default character set utf8; 
use shop; 
drop table if exists category; 
create table category 
( 
 /* 类别编号,自动增长 */ 
 id int not null auto_increment, 
 /* 类别名称 */ 
 type varchar(20), 
 /* 类别是否为热点类别,热点类别才有可能显示在首页*/ 
 hot bool default false, 
 /* 设置类别编号为主键*/ 
 primary key (id) 
); 

3.3 DB浏览器连接到Mysql数据库

        DB浏览器指的是MyEclipse中的一个视图窗口,可以很直观的看到MySQL中都有哪些数据库和表,打开DB浏览器的方法:Window->Open Perspective->DB Browser打开DB浏览器工作窗口。如果没有DB Browser,按照下面:Window->Show View->other->输入DB Browser,找到打开即可。

        打开后,我们开始连接到MySQL数据库了,在DB Browser窗口的空白处右键->new,就会弹出下面的对话框:

        填好后,点击Test Driver测试一下,测试通过表示DataBase connection Driver已经配置好,然后finish即可,这样我们就能在DB浏览器窗口中看到数据库MySQL5.6了,右键打开就能看到数据库中已有的库和表了,如下:


3.4 创建xml映射文件和sessionFactory

        sessionFactory是用来创建session的,我们通过如下方式创建:工程名右键->myeclipse->Add Hibernate Capabilities,如果没有Add Hibernate Capabilities,就点击project facets->Install Hibernate Facets,会弹出如下窗口:

        下一步,在MyEclipse中添加Hibernate Support,即hibernate.cfg.xml映射文件和sessionFactory。这里主要是给sessionFactory建个包,默认包不行。

        下一步,添加驱动,由于我们之前已经配置好了一个驱动了,所以在这里直接选择刚刚配置好的即可。

        下一步,由于之前我们已经添加过自己的jar保留,这里不用选择,直接finish。

        这样我们就完成了Hibernate配置文件和sessionFactory的创建。下面我们简单看一下MyEclipse创建的sessionFactory里面都有啥:

public class HibernateSessionFactory { 
 
 private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); //sessionFactory中用的是线程池技术 
 private static org.hibernate.SessionFactory sessionFactory; //sessionFactory:创建session的工厂 
 
 private static Configuration configuration = new Configuration(); 
 private static ServiceRegistry serviceRegistry; 
 
 static { //类加载时初始化sessionFactory 
 try { 
 configuration.configure(); 
 serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); 
 sessionFactory = configuration.buildSessionFactory(serviceRegistry); //Hibernate4中创建sessionFactory的方法 
 } catch (Exception e) { 
 System.err.println("%%%% Error Creating SessionFactory %%%%"); 
 e.printStackTrace(); 
 } 
 } 
 private HibernateSessionFactory() { //私有构造方法阻止new出对象,保证sessionFactory的单例 
 } 
 
 public static Session getSession() throws HibernateException { 
 Session session = (Session) threadLocal.get(); //从线程池中拿session 
 
 if (session == null || !session.isOpen()) { //如果线程池是空的,或者session打开失败 
 if (sessionFactory == null) { 
 rebuildSessionFactory(); //如果sessionFactory是空的,那就再创建一次,和static部分一样的 
 } 
 session = (sessionFactory != null) ? sessionFactory.openSession() : null; //sessionFactory不为空就创建一个session 
 threadLocal.set(session); //然后把这个session放到线程池中,下次再拿 
 } 
 
 return session; 
 } 
 
 public static void rebuildSessionFactory() { 
 try { 
 configuration.configure(); 
 serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); 
 sessionFactory = configuration.buildSessionFactory(serviceRegistry); 
 } catch (Exception e) { 
 System.err.println("%%%% Error Creating SessionFactory %%%%"); 
 e.printStackTrace(); 
 } 
 } 
 
 public static void closeSession() throws HibernateException { 
 Session session = (Session) threadLocal.get(); 
 threadLocal.set(null); 
 
 if (session != null) { 
 session.close(); 
 } 
 } 
 
 public static org.hibernate.SessionFactory getSessionFactory() {//提供一个公共接口让外界获得这个单例sessionFactory 
 return sessionFactory; 
 } 
 
 public static Configuration getConfiguration() { 
 return configuration; 
 } 
 
} 

 从创建的HibernateSessionFactory中可以看出,主要用到了单例模式和线程池技术。也不难理解。

3.5 通过逆向工程生成model、orm映射文件

        下面开始使用逆向工程创建实例对象了,也就是数据库的表对应的model。在DB Browsera窗口右击我们刚刚创建的表shop,选择Hibernate Reverse Engineering开始创建:

        创建的时候有两种方式,基于配置文件的和基于注解的,具体的看开发人员心情了,可以选择:

        然后下一步,选择一下native主键自增方式,然后便完成了逆向工程创建model和orm映射了。

        完成后,会有Category的model生成,同时在hibernate.cfg.xml文件中也会生成相应的映射,前面基于配置文件的和基于注解的在hibernate.cfg.xml中生成的映射时不同的。

3.6 测试Hibernate持久化数据库

        因为这里还没有与Spring整合,只是单纯的搭建Hibernate开发环境,所以我们没有必要使用注解,我们通过直接new一个service的方式执行数据入库。

先写CategoryService接口和实现类:

public interface CategoryService { 
 public void save(Category category); //用来测试Hibernate环境 
} 
 
public class CategoryServiceImpl implements CategoryService { 
 
 @Override //没有和Spring整合的情况 
 public void save(Category category) { 
 //通过刚刚生成的sessionFactory获取session 
 Session session = HibernateSessionFactory.getSession(); 
 try { 
 //手动事务 
 session.getTransaction().begin(); 
 //执行业务逻辑 
 session.save(category); 
 //手动提交 
 session.getTransaction().commit(); 
 } catch(Exception e) { 
 session.getTransaction().rollback(); 
 throw new RuntimeException(e); 
 } finally { 
 HibernateSessionFactory.closeSession(); 
 } 
 } 
} 

        下面在刚刚的测试用例中添加对Hibernate的测试:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations="classpath:beans.xml") 
public class SSHTest { 
 
 @Resource 
 private Date date; 
 
 @Test //测试Spring IOC的开发环境 
 public void springIoc() { 
 System.out.println(date); 
 } 
 
 @Test //测试Hibernate的开发环境,因为没有整合,可以直接new 
 public void hihernate() { 
 CategoryService categoryService = new CategoryServiceImpl(); 
 Category category = new Category("男士休闲", true); 
 categoryService.save(category); 
 } 
} 

        我们查看数据库,发现多了刚刚插入的这项,说明Hibernate环境没有问题。至此,Hibernate的开发环境我们就搭建好了。

4. 整合Spring和Hibernate

        搭建好了Spring和Hibernate的开发环境后,我们开始整合这两者。整合Spring和Hibernate后就可以使用AOP让Spring来管理Hibernate的事务了。整合Spring和Hibernate主要从两大方面入手,一是导入必要的jar包,二是配置beans.xml文件。下面我们一步步整合Spring和Hibernate。

4.1 导入相应的jar包

        整合Spring和Hibernate时需要导入的jar包有两大块,spring4.2.4-persistence和c3p0-0.9.5.1,每一块jar包中的具体jar文件请参见上面的截图,这里不再赘述。下面开始配置beans.xml文件了。

4.2 配置数据源dataSource

        首先配置一下dataSource,然后hibernate.cfg.xml中相应的部分可以干掉了。因为在Spring中配置好了,Spring会去初始化这个dataSource,也就是说这就交给Spring来完成了,hibernate.cfg.xml中的相应部分可以删掉了。如下:

<!-- com.mchange.v2.c3p0.ComboPooledDataSource类在c3p0-0.9.5.1.jar包的com.mchange.v2.c3p0包中 --> 
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
 <property name="driverClass" value="com.mysql.jdbc.Driver" /> 
 <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/shop" /> 
 <property name="user" value="root" /> 
 <property name="password" value="root" /> 
</bean> 

        hibernate.cfg.xml中需要干掉的部分:


4.3 配置sessionFactory

        配置sessionFactory是用来产生一个session的,另外HibernateTemplate也可以,但是这里采用sessionFactory而不用HibernateTemplate,是因为HibernateTemplate是Spring提供的,依赖于Spring,如果哪天不用Spring了,就会报错。而sessionFactory是Hibernate提供的,没有问题。HibernateTemplate的依赖性太强了。下面看一下具体配置:

<!-- org.springframework.orm.hibernate4.LocalSessionFactoryBean类在spring-orm-4.2.4.RELEASE.jar包的org.springframework.orm.hibernate4包中 --> 
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
 <property name="dataSource" ref="dataSource" /> 
 <property name="configLocation" value="classpath:hibernate.cfg.xml" /> <!-- 加载hibernate配置文件 --> 
</bean> 

        sessionFactory中的dataSource我们用刚刚配好的dataSource,用ref属性引用进来即可,configLocation我们不在这配了,直接加载hibernate.cfg.xml文件,使用hibernate配置文件中的配置,更加简洁方便。

4.4 配置事务管理器

        配置事务管理器,是用来管理sessionFactory的,这样所有的由sessionFactory产生的session将会有声明式的管理。配置如下:

<!-- org.springframework.orm.hibernate4.HibernateTransactionManager类spring-orm-4.2.4.RELEASE.jar包的org.springframework.orm.hibernate4包中 --> 
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
 <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

        同样,sessionFactory我们用刚刚配置好的sessionFactory,用ref属性引用进来即可。到这里就会发现,从上面一直配下来,都是一连串的操作,一个个引用下来。

4.5 配置advice(通知)

配置advice的目的是指定哪些方法需要什么类型的事务模式。看配置:

<tx:advice id="advice" transaction-manager="transactionManager"> 
 <tx:attributes> 
 <tx:method name="save*" propagation="REQUIRED"/> 
 <tx:method name="update*" propagation="REQUIRED"/> 
 <tx:method name="delete*" propagation="REQUIRED"/> 
 <tx:method name="*" propagation="SUPPORTS"/> 
 </tx:attributes> 
</tx:advice> 

        REQUIRED表示如果存在事务,则支持当前的事务,如果没有则创建一个新的事务,这个事务模式应用在所有以save、update和delete开头的方法上,也就是说对数据库的增删改的时候需要添加事务支持。SUPPORTS表示如果存在事务,则支持当前的事务,如果没有就算了。

4.6 配置AOP切面

<aop:config> 
 <!-- 配置哪些包的类要切入事务 --> 
 <aop:pointcut id="pointcut" expression="execution(* cn.it.shop.service.impl.*.*(..))" /> 
 <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/><!-- 连接了<span style="font-family:Microsoft YaHei;">上</span>面的advice和上面的pointcut --> 
 <!-- aop:pointcut要写在aop:advisor上面,否则会报错 --> 
 </aop:config> 

        AOP即面向切面编程,aop:pointcut定义一个切面,expression属性中配置的意思是所有cn.it.shop.service.impl包下的所有方法,不管返回值和参数是什么,都要切入事务。该包是属于dao层的,直接操作数据库的。aop:advice将通知和切面结合起来,我们直接使用上面配置好的advice和pointcut,将其引入进来即可。这样配置好了后,意思就是说,凡是cn.it.shop.service.impl包下的方法都需要切入事务管理,具体地,以save、update、delete开头的方法使用REQUIED方式,其他方法使用SUPPORTS方式。这样就很好理解这个配置的意思了。
4.7 测试整合结果
        之前搭建Hibernate环境的时候,我们测试是直接new了一个Service来操作数据库,因为当时还没有和Spring整合。现在通过配置beans.xml后,让Spring去管理Hibernate的事务了,所以现在的测试要把Service交给Spring管理,通过Spring注入进来,并且依赖sessionFactory,如果能插入数据到数据库,则说明声明事务OK。
        首先,我们要在Spring的配置文件beans.xml中配一下这个Service:

免费下载

整个项目的源码下载地址:http://www.phpstudy.net/article/86099.htm

原文地址:http://blog.csdn.net/eson_15/article/details/51277324

(注:到最后提供整个项目的源码下载!欢迎大家收藏或关注)

以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持phpstudy。


« 
» 

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3