spring与struts2整合就是将Action对象交给spring容器负责创建,spring与Hibername整合就是将sessionFactory交给sring来负责维护,同时也负责session的维护以及aop事务。
1导包
1.1 hibernate
- required文件夹下的包
- jpa文件夹下的包
- 日志的包
- 数据库连接的包
1.2 struts2
首先导基础的包,但是javassist-3.18.1-GA.jar与hibernate中的重复。还需要导入一个包,struts整合spring的包。struts2-spring-plugin-2.3.24.jar,这个包一旦导入,strutst2在启动时就会寻找sprig容器。
1.3 spring
- 基本4+2
- 整合web
- 整合aop
- 整合jdbc事务
这里由于要整合hibernate,所以还要导入spring-orm的包 - 整合junit4测试
2 书写配置文件
2.1 单独配置spring
2.2 单独配置struts2
2.3 struts2与spring整合
首先需要导入一个strut2和spring整合的包。
整合方式有两种:
<constant name="struts.objectFactory" value="spring"></constant>
<package name="crm" namespace="/" extends="struts-default" >
<!-- 整合方案1:class属性上仍然配置action的完整类名
struts2仍然创建action,由spring负责组装Action中的依赖属性,属性所对应的变量名应该是一样的,场景是:在UserAction里,有一个名为userServcie的变量,在spring的配置文件里有UserService对应的bean,name属性为userService,否则没法自动完成装配,
-->
<!--
整合方案2:class属性上填写spring中action对象的BeanName
完全由spring管理action生命周期,包括Action的创建
注意:需要手动组装依赖属性
<bean name="userAction" class="cn.itcast.web.action.UserAction" scope="prototype" >
<property name="userService" ref="userService" ></property>
</bean>
-->
<action name="UserAction_*" class="com.dlj.web.action.UserAction" method="{1}">
<result name="success" >/hello.jsp</result>
</action>
</package>
第一种方式不推荐,不推荐理由:最好由spring完整管理action的生命周期,spring中的功能才能应用到Action上。
spring中Action所对应的Bean应该是多例的
2.4 单独配置hibernate
首先就是隔离级别的属性,不用配置,还有指定session与当前线程绑定也不要配置。
2.5 spring整合hibernate
整合原理:将sessionFactory对象交给spring容器管理
<!-- 将SessionFactory配置到spring容器中 -->
<!-- 加载配置方案1:仍然使用外部的hibernate.cfg.xml配置信息 -->
<bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
<property name="configLocation" value="classpath:hibernate.cfg.xml" ></property>
</bean>
配置方案二:
<!-- 加载配置方案2:在spring配置中放置hibernate配置信息 -->
<bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
<!-- 将连接池注入到sessionFactory, hibernate会通过连接池获得连接 -->
<property name="dataSource" ref="dataSource" ></property>
<!-- 配置hibernate基本信息 -->
<property name="hibernateProperties">
<props>
<!-- 必选配置 -->
<!-- <prop key="hibernate.connection.driver_class" >com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url" >jdbc:mysql:///crm_32</prop>
<prop key="hibernate.connection.username" >root</prop>
<prop key="hibernate.connection.password" >1234</prop> -->
<prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
<!-- 可选配置 -->
<prop key="hibernate.show_sql" >true</prop>
<prop key="hibernate.format_sql" >true</prop>
<prop key="hibernate.hbm2ddl.auto" >update</prop>
</props>
</property>
<!-- 引入orm元数据,指定orm元数据所在的包路径,spring会自动读取包中的所有配置 -->
<property name="mappingDirectoryLocations" value="classpath:cn/itcast/domain" ></property>
</bean>
2.6 spring整合c3p0连接池
<!-- 连接池 -->
<!-- 指定spring读取db.properties配置 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 1.将连接池放入spring容器 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property>
<property name="driverClass" value="${jdbc.driverClass}" ></property>
<property name="user" value="${jdbc.user}" ></property>
<property name="password" value="${jdbc.password}" ></property>
</bean>
使用这段代码,首先需要在src目录下新建一个db.properties文件,然后在spring整合hibernate的配置中,就可以把数据库的配置部分给注释掉了。但是数据库方言这个配置不可以注释,但是好像我注释了也没有报错。
2.7 spring整合Hibernate操作数据库
spring也有一个模板,就是HibernateTemplate,这个和JDBC模板类似,也需要实现HibernateDataSupport,这样就可以直接获得HibernateTemplate对象,同时还要将SeessionFactory注入进去。
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
@Override
public com.dlj.entity.User getByUserCode(String username) {
// HQL
/*
* return getHibernateTemplate().execute(new HibernateCallback<User>() {
*
* @Override public User doInHibernate(Session session) throws
* HibernateException { // TODO Auto-generated method stub String hql =
* "from User where username=?"; Query query = session.createQuery(hql);
* query.setParameter(0, username); User user = (User)
* query.uniqueResult(); return user; }
*
* });
*/
// Criteria
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
dc.add(Restrictions.eq("username", username));
List<User> list = (List<User>) getHibernateTemplate().findByCriteria(dc);
if (list != null && list.size() > 0) {
return list.get(0);
} else {
return null;
}
}
}
2.7 spring的aop事务
首先是配置核心事务管理器
<!-- 配置核心事务管理器 -->
<!-- 事务核心管理器,封装了所有事务操作. 依赖于sessionFactory -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="sessionFactory" ref="sessionFactory" ></property>
</bean>
2.7.1 xml配置aop事务
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager" >
<tx:attributes>
<tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置织入 -->
<aop:config >
<!-- 配置切点表达式 -->
<aop:pointcut expression="execution(* com.dlj.service.impl.*ServiceImpl.*(..))" id="txPc"/>
<!-- 配置切面 : 通知+切点
advice-ref:通知的名称
pointcut-ref:切点的名称
由于spring已经将通知给我们写好了,所以这里直接配置切面
-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" />
</aop:config>
userDao下:
public void saveUser(User u) {
// TODO Auto-generated method stub
getHibernateTemplate().save(u);
}
2.7.2 注解配置aop事务
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
2.7.3 扩大session作用范围
为了避免使用懒加载时出现no-session问题.需要扩大session的作用范围
在web.xml文件中进行配置:
<!-- 扩大session作用范围
注意: 任何filter一定要在struts的filter之前调用
-->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>