SSH整合是通过Spring牵线搭桥的,由spring容器接管Struts2的Action创建,由Spring接管实例化的创建,由spring接管sessionFactory,维护session,由spring接管aop事务。
hibernate包
Struts2包
spring包
标签库包(2个)
导入约束
配置web.xml让spring随项目启动而启动
123 org.springframework.web.context.ContextLoaderListener 4 567 contextConfigLocation 8 classpath:applicationContext.xml 9
2<listener>
3 <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
4listener>
5
6<context-param>
7 <param-name>contextConfigLocationparam-name>
8 <param-value>classpath:applicationContext.xmlparam-value>
9context-param>
导入约束dtd约束
配置struts2核心过滤器到web.xml
123 struts2 4 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 5 67 struts2 8 /* 9
2<filter>
3 <filter-name>struts2filter-name>
4 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
5filter>
6<filter-mapping>
7 <filter-name>struts2filter-name>
8 <url-pattern>/*url-pattern>
9filter-mapping>
导包(已经导入)
配置常量
14
4<constant name="struts.objectFactory" value="spring">constant>
整合方案一:struts2仍然创建Action,spring负责组装依赖属性。(不推荐)
145 /success.jsp 6
4<action name="UserAction_*" class="cn.it.web.action.UserAction" method="{1}" >
5 <result name="success" >/success.jspresult>
6action>
整合方案二:Action,依赖属性,都是由spring创建组装。
167 /index.htm 8 /login.jsp 9
6<action name="UserAction_*" class="userAction" method="{1}" >
7 <result name="toHome" type="redirect" >/index.htmresult>
8 <result name="error" >/login.jspresult>
9action>
方案二中的applicationContext.xml配置
1234 5
2
3<bean name="userAction" class="cn.it.web.action.UserAction" scope="prototype" >
4 <property name="userService" ref="userService" >property>
5bean>
创建实体类和映射文件
配置hibernate.hbm.xml文件
将sessionFactory对象交给spring管理。
将sessionFactory配置到spring容器。
加载配置:两种方案,方案一:不推荐
123 4
2<bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
3 <property name="configLocation" value="classpath:hibernate.cfg.xml" >property>
4bean>
加载配置:方案二(重点)
1 2 3 4 5 6 7 8 13 org.hibernate.dialect.MySQLDialect 1415 16 true 17 true 18 update 19 20 21 22 23
2<bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
3
4 <property name="dataSource" ref="dataSource" >property>
5
6 <property name="hibernateProperties">
7 <props>
8
13 <prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialectprop>
14
15
16 <prop key="hibernate.show_sql" >trueprop>
17 <prop key="hibernate.format_sql" >trueprop>
18 <prop key="hibernate.hbm2ddl.auto" >updateprop>
19 props>
20 property>
21
22 <property name="mappingDirectoryLocations" value="classpath:cn/it/domain" >property>
23bean>
添加读取文件db.properties
添加配置文件c3p0配置文件,并导入db.properties文件
配置完c3p0后就不需要在applicationContext.xml中配置driver,url,root,password了。
12 345 6 7 8 9
2<context:property-placeholder location="classpath:db.properties" />
3
4<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
5 <property name="jdbcUrl" value="${jdbc.jdbcUrl}" >property>
6 <property name="driverClass" value="${jdbc.driverClass}" >property>
7 <property name="user" value="${jdbc.user}" >property>
8 <property name="password" value="${jdbc.password}" >property>
9bean>
spring整合过jdbc操作数据库,让jdbc操作数据库的类继承JdbcDaoSupport,实现了在spring监管下操作数据库。
spring对于dao层的任何框架都进行了处理,对jdbc有封装,对Hibernate也有封装,对mybaties也有封装。
spring整合hibernate就是让dao层,继承HibernateDaoSupport,获取spring封装下的方法,实现操作数据库。HibernateDaoSupport根据连接池创建了jdbc模板,实现类可以直接继承使用。HIbernateDaoSupport封装了session操作。
1//HibernateDaoSupport 为dao注入sessionFactory2public class UserDaoImpl extends HibernateDaoSupport implements UserDao {//HibernateDaoSupport 为dao注入sessionFactory
2public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
那么在ssh框架中操作数据库有两种方法,一种是hql语句,一种是Criteria方法
1public User getByUserCode(final String usercode) { 2 //HQL 3 return getHibernateTemplate().execute(new HibernateCallback() { 4 @Override 5 public User doInHibernate(Session session) throws HibernateException { 6 String hql = "from User where user_code = ? "; 7 Query query = session.createQuery(hql); 8 query.setParameter(0, usercode); 9 User user = (User) query.uniqueResult();10 return user;11 }12 });public User getByUserCode(final String usercode) {
2 //HQL
3 return getHibernateTemplate().execute(new HibernateCallback() {
4 @Override
5 public User doInHibernate(Session session) throws HibernateException {
6 String hql = "from User where user_code = ? ";
7 Query query = session.createQuery(hql);
8 query.setParameter(0, usercode);
9 User user = (User) query.uniqueResult();
10 return user;
11 }
12 });
使用criteria方法操作数据库
1DetachedCriteria dc = DetachedCriteria.forClass(User.class);2dc.add(Restrictions.eq("user_code", usercode));3List list = (List) getHibernateTemplate().findByCriteria(dc); 4if(list != null && list.size()>0){5 return list.get(0);6}else{7 return null;8}
2dc.add(Restrictions.eq("user_code", usercode));
3List list = (List) getHibernateTemplate().findByCriteria(dc);
4if(list != null && list.size()>0){
5 return list.get(0);
6}else{
7 return null;
8}
spring整合下的dao依赖属性是sessionFactory
12 3 4 5
2 "userDao" class="cn.itcast.dao.impl.UserDaoImpl" >
3
4 "sessionFactory" ref="sessionFactory" >
5
在处理jdbc的aop事务时已经讲过,这个和那个是一样的,spring通过aop思想对所有的方法进行事务处理操作。相当于把事务处理操作单独拉出来,谁用事务就给它安装。
在applicationContext.xml中配置核心事务管理器
123 4
2<bean name="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" >
3 <property name="sessionFactory" ref="sessionFactory" >property>
4bean>
在ac.xml中配置通知
1 2 3 4 5 6 7 8 9 10 11 12 <tx:advice id="txAdvice" transaction-manager="transactionManager" >
2 <tx:attributes>
3 <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
4 <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
5 <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
6 <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
7 <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
8 <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
9 <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
10 <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
11 tx:attributes>
12tx:advice>
配置将通知织入事务
145 6 7
4<aop:config>
5 <aop:pointcut expression="execution(* cn.it.service.impl.*ServiceImpl.*(..))" id="txPc"/>
6 <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" />
7aop:config>
开启注解事务,在ac.xml中配置
12
2<tx:annotation-driven transaction-manager="transactionManager" />
在service类中使用注解
1@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)2public class UserServiceImpl implements UserService{@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
2public class UserServiceImpl implements UserService{
1@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)2public void saveUser(User u) {3 ud.save(u);4}@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
2public void saveUser(User u) {
3 ud.save(u);
4}
由于hibernate加载机制默认懒加载机制即:延迟加载,只有调用时才加载,不调用不加载。
延迟加载机制:当查询时,会返回一个代理对象,不会先查,而是等用的时候再查,但是,等到页面再获取查的内容时,session已经在service层关闭,就会导致no session问题。解决方案是,把session作用范围扩大到一次请求。
目的:确保在view层session仍然是打开状态。
解决方案:是配置filter在web.xml,
134 openSessionInView 5 org.springframework.orm.hibernate5.support.OpenSessionInViewFilter 6
3<filter>
4 <filter-name>openSessionInViewfilter-name>
5 <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilterfilter-class>
6filter>
12 openSessionInView 3 /* 4 <filter-mapping>
2 <filter-name>openSessionInViewfilter-name>
3 <url-pattern>/*url-pattern>
4filter-mapping>