Spring4入门之shh的整合
SSH整合方式一:无障碍整合
SSH框架的回顾
SSH整合
-
创建web项目,引入相应的jar包
-
Struts2的相关jar包
struts-2.3.24\apps\struts2-blank\WEB-INF\lib*.jar
Struts2中有一些包需要了解的:
包名 作用 struts2-convention-plugin-2.3.24.jar Struts2的注解开发包 struts2-json-plugin-2.3.24.jar ----Struts2的整合AJAX的开发包 Struts2的整合AJAX的开发 struts2-spring-plugin-2.3.24.jar Struts2的整合Spring的开发 -
Hibernate的相关jar包
Hibernate的开发的必须的包:
hibernate-release-5.0.7.Final\lib\required*.jar
MySQL驱动:
日志记录:
使用C3P0连接池
注意:Struts2和Hibernate都引入了一个相同的jar包(javassist包)。删除一个(低版本的) -
Spring的相关jar包
-
IOC开发的包:
AOP开发的包:
JDBC模板开发的包:
事务管理:
整合web项目开发:
整合单元测试:
整合ORM项目开发:
-
-
引入配置文件
-
web.xml
<!-- Struts2的过滤器 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
struts.xml
-
Hibernate的配置文件
hibernate.cfg.xml(删除那个与线程绑定的session)
映射文件
-
Spring 的配置文件
web.xml
<!-- Spring的核心监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 加载Spring的配置文件的路径,默认加载加载的是:/WEB-INF/applicationContext.xml --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- Struts2的过滤器 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
日志记录
log4j.properties
-
-
创建包结构和相关类
- 引入相关的页面
Spring整合Struts2方式一:Action由Struts2自身创建的
-
编写action
CustomerAction.java
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> { private Customer customer; @Override public Customer getModel() { return customer; } /* * 保存客户的方法 */ public String save() { // 如果web层没有使用Struts2,获取业务层必须进行如下的编写。 WebApplicationContext applicationContext = WebApplicationContextUtils .getWebApplicationContext(ServletActionContext.getServletContext()); CustomerService customerService = (CustomerService) applicationContext.getBean("customerService"); System.out.println("Action的save方法执行了。。。"); customerService.save(customer); return NONE; } }
-
配置struts.xml中配置Action
<!-- 配置Struts2的常量 --> <constant name="struts.action.extension" value="action" /> <constant name="struts.devMode " value="true" /> <package name="ssh1" extends="struts-default" namespace="/" > <action name="customer_*" class="com.syj.shh.web.action.CustomerAction" method="{1}"> </action> </package>
-
在Struts和Spring整合的时候我们需要引入 struts-spring-plugin.jar插件包
-
在插件包中有如下配置
<constant name="struts.objectFactory" value="spring" /> <constant name="struts.class.reloading.watchList" value="" /> <constant name="struts.class.reloading.acceptClasses" value="" /> <constant name="struts.class.reloading.reloadConfig" value="false" /> <constant name="xwork.disallowProxyMemberAccess" value="true" />
开启一个常量:在Struts2中只有开启这个常量就会引发下面常量生效default.properties中:
# struts.objectFactory = spring ### specifies the autoWiring logic when using the SpringObjectFactory. ### valid values are: name, type, auto, and constructor (name is the default) struts.objectFactory.spring.autoWire = name
-
让Action按照名称自动注入Service:在Action中提供需要调用的Service属性和set方法
private CustomerService customerService; public void setCustomerService(CustomerService customerService) { this.customerService = customerService; }
-
CustomerAction的完整代码
package com.syj.shh.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.syj.shh.domain.Customer; import com.syj.shh.service.CustomerService; /** * 客户管理的Action * * @author SYJ * */ public class CustomerAction extends ActionSupport implements ModelDriven<Customer> { private Customer customer; @Override public Customer getModel() { return customer; } private CustomerService customerService; public void setCustomerService(CustomerService customerService) { this.customerService = customerService; } /* * 保存客户的方法 */ public String save() { // 如果web层没有使用Struts2,获取业务层必须进行如下的编写。 /* * WebApplicationContext applicationContext = WebApplicationContextUtils * .getWebApplicationContext(ServletActionContext.getServletContext()); * CustomerService customerService = (CustomerService) * applicationContext.getBean("customerService"); */ System.out.println("Action的save方法执行了。。。"); customerService.save(customer); return NONE; } }
Spring整合Struts2方式二:Action交给Spring管理(推荐)
-
引入插件包struts-spring-plugin.jar
-
将Action交给Spring管理
<!-- 将action页交给Spring管理 --> <bean id="cutsomerAction" class="com.syj.shh.web.action.CustomerAction" scope="prototype"> <property name="customerService" ref="customerService"/> </bean>
-
在struts.xml中配置Action
<!-- 配置Struts2的常量 --> <constant name="struts.action.extension" value="action" /> <constant name="struts.devMode " value="true" /> <package name="ssh1" extends="struts-default" namespace="/" > <action name="customer_*" class="cutsomerAction" method="{1}"> </action> </package>
-
注意:
需要配置Action为多例的:
需要手动注入Service
Spring整合Hibernate框架一(有配置文件)
-
创建数据库和表:
Create database ssh1; Use ssh1; CREATE TABLE `cst_customer` ( `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)', `cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)', `cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源', `cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业', `cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别', `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话', `cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话', PRIMARY KEY (`cust_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-
编写实体类和映射
-
Spring整合hibernate
-
在Spring中配置,加载Hibernate.cfg.xml
<!-- Spring整合Hibernate --> <!-- 加载Hibernate的配置文件 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> </bean>
-
在Spring和Hibernate整合后,Spring提供了一个Hibernate的模板简化Hibernate的开发
-
最初的时候我们还需要在applicationContext.xml中配置
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate"> <property name="dataSource" ref="dataSource" /> </bean>
-
我们可以将DAO改为继承HibernateDaoSupport
public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao { @Override public void save(Customer customer) { System.out.println("Dao层的save方法执行了。。。"); System.out.println(customer); this.getHibernateTemplate().save(customer); } }
-
查看HibernateDaoSupport源码可以知道在父类中有两个方法:
我们可以在配置文件的customerDao中直接注入HibernateTemplate的模板类,但是我们还是需要再HibernateTemplate模板类中注入sessionFactory
我们可以直接在customerDao中注入sessionFactory即可
-
-
配置的时候在DAO中直接注入sessionFactory
<!-- 配置Dao --> <bean id="customerDao" class="com.syj.shh.dao.impl.CustomerDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
-
在Dao的实现类中使用HibernateTemplate
@Override public void save(Customer customer) { System.out.println("Dao层的save方法执行了。。。"); System.out.println(customer); this.getHibernateTemplate().save(customer); }
-
配置事务管理器
<!-- 配置事务管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
-
开启注解式事务
<tx:annotation-driven transaction-manager="transactionManager"/>
-
在类上使用注解
@Transactional public class CustomerServiceImpl implements CustomerService { private CustomerDao customerDao; public void setCustomerDao(CustomerDao customerDao) { this.customerDao = customerDao; } @Override public void save(Customer customer) { System.out.println("Service的save方法执行了。。。。"); customerDao.save(customer); } }
SSH整合方式二:将Hibernate的配置交给Spring管理(没有Hibernate的配置文件)
-
目的就是将Hibernate核心配置文件中的内容全部转移到Spring的配置文件中
-
Hibernate.cfg.xml中的相关内容
数据库连接的配置;
Hibernate的方言
Hibernate的是否展示sql语句
Hibernate的格式化sql
等等
C3P0连接池
映射文件
-
第一步:引入C3P0连接池
<!-- 配置C3P0连接池 ============ --> <!-- 加载外部文件 --> <context:property-placeholder location="classpath:jdbc.properties" /> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" > <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
-
第二步:引入Hibernate的配置文件
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" > <!-- 注入连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 配置Hibernate的相关属性 --> <property name="hibernateProperties"> <props> <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> </bean>
查看LocalSessionFactoryBean源代码:
public void setHibernateProperties(Properties hibernateProperties) { this.hibernateProperties = hibernateProperties; } //========================== public void setMappingResources(String... mappingResources) { this.mappingResources = mappingResources; }
-
引入映射文件
<!-- 设置属性的映射文件 --> <property name="mappingResources"> <list> <value>com/syj/shh/domain/Customer.hbm.xml</value> </list> </property>
-
取出hibernate.cfg.xml文件的全部applicationContext.xml代码
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 将action页交给Spring管理 --> <bean id="cutsomerAction" class="com.syj.shh.web.action.CustomerAction" scope="prototype"> <property name="customerService" ref="customerService" /> </bean> <!-- CustomerService --> <bean id="customerService" class="com.syj.shh.service.impl.CustomerServiceImpl"> <property name="customerDao" ref="customerDao" /> </bean> <!-- 配置Dao --> <bean id="customerDao" class="com.syj.shh.dao.impl.CustomerDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 配置C3P0连接池 ============ --> <!-- 加载外部文件 --> <context:property-placeholder location="classpath:jdbc.properties" /> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" > <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- Spring整合Hibernate======================== --> <!-- 引入Hibernate的配置文件 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" > <!-- 注入连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 配置Hibernate的相关属性 --> <property name="hibernateProperties"> <props> <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> <!-- 设置属性的映射文件 --> <property name="mappingResources"> <list> <value>com/syj/shh/domain/Customer.hbm.xml</value> </list> </property> </bean> <!-- 配置事务管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
Hibernate模板的使用
-
保存操作
save(Object obj);
-
修改操作
update(Object obj);
-
删除操作
delete(Object obj);
-
查询操作
-
查询一个
get(Class c,Serializable id);
load(Class c,Serializable id);
-
查询多个
List find(String hql,Object… args);
List findByCriteria(DetachedCriteria dc);
List findByCriteria(DetachedCriteria dc,int firstResult,int maxResults);
List findByNamedQuery(String name,Object… args);
-
延迟加载问题的解决
-
延迟加载问题
由于事务的开启和关闭都是在Service层,假如我们需要查询一个学生的信息的时候,有学生的姓名、年龄、性别和所属于班级。
由于关联对象的查询默认是使用延迟加载的。所以我们当在web层展示信息的时候我们不能获取到学生的所属班级情况
-
延迟加载生成的原因
-
延迟加载的解决办法:
我们只需要在web.xml中加入一个过滤器(解决延迟加载的过滤器要在struts.xml核心过滤器之前)
<!-- 解决延迟加载问题的过滤器 --> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping>