首页 > 代码库 > ssh笔记整合

ssh笔记整合

1.整合Spring和Hibernate框架
JBOA数据库设计
1.部门表
2.雇员表
3.职位表
4.报销单表
5.报销单明细表
6.审核记录表
2.SSH架构
1.Struts 2+Spring+Hibernate
2.以Spring作为核心框架,数据持久化使用
Hibernate完成,表现层使用Struts 2
3.Spring提供对象管理、面向切面编程等实用功能
4.通过Spring提供的服务简化编码、降低开发难度、提高开发效率
1.整合思路
1.逆依赖方向而行。由spring提供对象管理和服务
2.依次实现Spring与Hibernate、Spring与struts2集成
在Spring中配置数据源和会话工厂
1.方法一:定义独立的Hibernate配置文件,由Spring导入并创建会话工厂Bean
2.方法二:在Spring配置文件中进行集中配置。
1.先配置数据源,再以此为基础配置会话工厂Bean
2.持久化类的映射文件可以逐个配置,也可以按目录导入
使用HibernateDaoSupport基类
1.DAO类继承HibernateDaoSupport
2.使用getHibernateTemplate()方法获取HibernateTemplate实现完成持久化操作

事务的属性:
1.propagation:事务传播机制
required(默认值)增删改
nested(嵌套事务)
mandatory
requires_new
supports、查询
never、不需要参数
not_supported 不需要开启事务,优先级
2.isolation:事务隔离等级
default(默认值)、
read_uncommitted并发性能好 查询用 查询快 脏读

read_committed 隔离级别最低 (oracle 默认级别) 不可重复读
repeatable_read、(mysql默认级别)解决不可重复读
serializable 最严格 绝对安全 读写最低 银行
3.timeout:事务超时时间。允许事务运行的时间,以秒为单位。默认值为-1,表示不超时
4.read_only:事务是否为只读。默认值为false.
5.rollback-for:设定能够触发回滚的异常
1.Spring默认只在抛出runtime exception时才标识事务回滚
2.可以通过全限定类名指定需要回滚事务的异常,多个类名用逗号隔开
6.no-rollback-for:设定不触发回滚的异常
1.Spring默认checked Exception不会触发事务回滚
2.可以通过全限定类名指定不需要回滚事务的异常,多个类名用英文逗号隔开

在spring中配置数据源和会话工厂

1.方法一:定义独立的Hibernate 配置文件 Spring导入并创建会话工厂Bean

2.方法二:在Spring配置文件中进行集以此为中配置
1.先配置数据源,再以此为基础配置会话工厂Bean
2.持久化类的映射文件可以逐个配置,也可以按目录导入。

 

<!-- spring加载hibernate的配置文件 接管会话工厂-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="http://www.mamicode.com/classpath:hibernate.cfg.xml"></property>
</bean>

<!-- spring 创建了一个模板 EmployeeDaoImpl extends HibernateDaoSupport 必须注入sessionFactory -->
<bean id="employeeDao" class="cn.bdqn.jboa.dao.impl.EmployeeDaoImpl"
p:sessionFactory-ref="sessionFactory">
<!-- <property name="sessionFactory" ref="sessionFactory"></property>
引用sessionFactory p:sessionFactory-ref="sessionFactory"
-->
</bean>
<bean id="claimVoucherDao" class="cn.bdqn.jboa.dao.impl.ClaimVoucherDaoImpl"
p:sessionFactory-ref="sessionFactory"></bean>

<!-- 业务层 -->
<bean id="employeeService" class="cn.bdqn.jboa.service.impl.EmployeeServiceImpl"
p:employeeDao-ref="employeeDao"></bean>
<bean id="claimVoucherService" class="cn.bdqn.jboa.service.impl.ClaimVoucherServiceImpl"
p:claimVoucherDao-ref="claimVoucherDao"></bean>

<!-- 声明 事务管理器-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
</bean>


<!--给事务做属性配置 引用事务管理器 transaction-manager="transactionManager"-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="add*"/>
<tx:method name="save*"/>
<tx:method name="update*"/>
<tx:method name="modify*"/>
<tx:method name="delete"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>


<!-- 切面置入 -->
<aop:config>
<aop:pointcut expression="execution(public * service..*(..))" id="serviceMethod"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>

在web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>

<!-- 添加环境变量读取spring配置文件 -->
<!-- 默认在/web-inf/applicationContext.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 监听器读取配置文件 -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- 会话开闭 加上一次 请求完成 不加业务为分界线 把它放在struts2核心过滤器上面-->
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<!-- 当你applicationContext.xml 不按会话工厂sessionFactory配置 -->
<!-- <init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>SessionFactory</param-value>替换的名字
</init-param> -->
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>

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

<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>

<!--基于dbcp配置 省略hibernate的配置文件-->
<!--数据源的配置 dbcp c3p0 proxool -->

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<!--数据源的配置 dbcp c3p0 proxool -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="http://www.mamicode.com/oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="http://www.mamicode.com/jdbc:oracle:thin:@localhost:1521:jbit"></property>
<property name="username" value="http://www.mamicode.com/bdqn1"></property>
<property name="password" value="http://www.mamicode.com/bdqn1"></property>
<property name="maxActive" value="http://www.mamicode.com/100"></property><!-- 最大活动连接数 -->
<property name="maxIdle" value="http://www.mamicode.com/10"></property><!-- 最大闲时连接数 -->
<property name="maxWait" value="http://www.mamicode.com/10000"></property><!-- 最大等待时间 以毫秒为单位 -->

</bean>

<!-- spring加载hibernate的配置文件 接管会话工厂-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- <property name="configLocation" value="http://www.mamicode.com/classpath:hibernate.cfg.xml"></property> -->
<!-- 引用数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 配置hibernate的辅助参数 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
<!-- 配置hibernate的映射文件 -->
<!-- <property name="mappingResources">
<list>
<value>cn/bdqn/jboa/entity/CheckResult.hbm.xml</value>
</list>
</property> -->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:cn/bdqn/jboa/entity/</value>
</list>
</property>

</bean>
<!-- spring 创建了一个模板 EmployeeDaoImpl extends HibernateDaoSupport 必须注入sessionFactory -->
<bean id="employeeDao" class="cn.bdqn.jboa.dao.impl.EmployeeDaoImpl"
p:sessionFactory-ref="sessionFactory">
<!-- <property name="sessionFactory" ref="sessionFactory"></property>
引用sessionFactory p:sessionFactory-ref="sessionFactory"
-->
</bean>
<bean id="claimVoucherDao" class="cn.bdqn.jboa.dao.impl.ClaimVoucherDaoImpl"
p:sessionFactory-ref="sessionFactory"></bean>
<!-- 业务层 -->
<bean id="employeeService" class="cn.bdqn.jboa.service.impl.EmployeeServiceImpl"
p:employeeDao-ref="employeeDao"></bean>
<bean id="claimVoucherService" class="cn.bdqn.jboa.service.impl.ClaimVoucherServiceImpl"
p:claimVoucherDao-ref="claimVoucherDao"></bean>
<!-- 声明 事务管理器 开闭事务的增强类-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
</bean>
<!--给事务做属性配置 引用事务管理器 transaction-manager="transactionManager"
相当于环绕around通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="add*"/>
<tx:method name="save*"/>
<tx:method name="update*"/>
<tx:method name="modify*"/>
<tx:method name="delete"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 切面置入 -->
<aop:config>
<aop:pointcut expression="execution(public * service..*(..))" id="serviceMethod"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>


</beans>


模板与回调机制

1.模板虽好,但有得有失
有时我们需要更加灵活
2.Spring提供了回调机制
模板固化了不变的、流程化的内容,简化使用

回调允许我们在固化的流程中加入变化的内容
3.HibernateCallback接口
public T execute(HibernateCallback<T> action) throws DataAccessException

 

添加业务层和事务机制

如何在添加报销单明细的业务流程中控制好事务?
分析
1.可以采用Hibernate控制事务
2.事务应该在业务逻辑层控制
3.硬编码方式,代码繁琐,且破坏分层,代码不易维护
提示
1,可以采用AOP的方式实现
2,Spring提供了声明式事务支持

配置步骤:
1.导入tx和aop命名空间
2.配置事务管理器,并为其注入SessionFactory
3.基于该事务管理器配置事务增强,指定事务规则
4.定义切入点
5.织入事务切面


异常
checked runtime
默认 不回滚 回滚

强制回滚rollback-for no-rollback-for

Struts 2和Spring集成的第二种方式
1.自动注入的方式有时显得灵活性不足,无法满足需求
2.把Action像业务类和DAO一样声明在Spring的配置文件中,这样就可以更加灵活配置Action


配置c3p0数据源
<bean id="dataSource" destroy-method="close"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="http://www.mamicode.com/oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="http://www.mamicode.com/jdbc:oracle:thin:@localhost:1521:jbit"></property>
<property name="user" value="http://www.mamicode.com/bdqn1"></property>
<property name="password" value="http://www.mamicode.com/bdqn1"></property>
<!--最大连接数-->
<property name="maxPoolSize" value="http://www.mamicode.com/40"></property>
<!--最小连接数-->
<property name="minPoolSize" value="http://www.mamicode.com/1"></property>
<!--初始化连接数-->
<property name="initialPoolSize" value="http://www.mamicode.com/1"></property>
<!--连接最大空闲时间-->
<property name="maxIdleTime" value="http://www.mamicode.com/60"></property>
<!--等待连接时间-->
<property name="checkoutTimeout" value="http://www.mamicode.com/2000"></property>


</bean>


jdbc.properties文件

driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:jbit
username=bdqn1
password=bdqn1


spring applicationContext.xml


<context:property-placeholder location=classpath:jdbc.properties

<bean id="dataSource" destroy-method="close"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="http://www.mamicode.com/${driver}"></property>
<property name="jdbcUrl" value="http://www.mamicode.com/${url}"></property>
<property name="user" value="http://www.mamicode.com/${username}"></property>
<property name="password" value="http://www.mamicode.com/${password}"></property>
</bean>

通过JNDI从服务器容器中获取DataSource资源
1.在服务器环境中配置数据源
2.在Spring配置文件引用JNDI资源
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="http://www.mamicode.com/java:comp/env/xxx"></property>
</bean>

tomcat/conf/context.xml

为什么需要拆分配置文件
1.项目规模变大,配置文件可读性、可维护性差。
2.团队开发时,多人修改同一个配置文件,易发生冲突。
拆分策略
1.公用配置+每个系统模块一个单独配置文件(dao service action)
2.公用配置+DAO Bean配置+业务逻辑Bean配置+ActionBean配置
3.两种策略各有特色,适用于不同场合
分模块开发:引用spring配置文件
第一种方法
<import resource="classpath:applicationContext-dao.xml"/>
<import resource="classpath:applicationContext-service.xml"/>
<import resource="classpath:applicationContext-web.xml"/>
第二种方法
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>

使用注解实现事务处理
在Spring配置文件中配置事务管理类,并添加对注解配置的事务的支持
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
</bean>
注解
<tx:annotation-driven transaction-manager="transactionManager"/>

使用@Transactional为方法添加事务支持
public class EmployeeServiceImpl implements EmployeeService{

}
@Transactional(propagation=Propagation.SUPPORTS)

public Employee login(Employee employee)throws Exception{

}

ssh笔记整合