1.三大框架整合理论
今天迎来了 ,比较激动人心的时刻, struts2 hibernate spring 整合 的一天 哈哈哈!!
web项目分三层,web(jsp+sevlet) serivce(javabean) dao(Hibernate)
spring可以帮struts2 管理action 对象,
spring 可以帮hibernate 管理sessionFactory session 的创建工厂, session 的生命周期不用管了, session 的获得托管了spring aop事务也交给了spring 维护, 我们只需要哪hibernate 操作数据库就可以了, hibernate 只需要操作业务的增删改查
2.导包
hibernate/lib/required 下的所有包
hibernate/lib/jpa包 java 定义的orm 一面向对象的形式操作数据库, 里面都是接口
数据库驱动包
struts 中的包
black 项目中的所有演示包
注意: 这里的jar包GA与hibernate 中的重复删掉一个版本低的
struts2 整合spring插件包 struts-spring-plugin.jar 包
注意: 这个包一旦导入了, 启动struts2 就会自动找spring 容器, 如果没有就会报错,不整合spring 就不用
spring 导包
基本 4+2
core beans context expression logging log4j
整合web web包
spring-web
整合aop 4个包
spring-aop spring-aspect aop 联盟 aopweaving
整合事务&jdbc 4
spring-jdbc spring-tx c3p0 spring-orm
整合junit 测试 test 包
spring-test
共 40 个包
2. 单独配置Spring 容器
2.1 创建 applicationContext.xml ,并且导入约束(4.个) beans context aop tx 容器, 注解,代理,事务
配置服务器启动时候自动加载spring配置文件, 然后创建spring 容器
测试: 加载进服务器中, 看下是否能够运行
3.单独配置struts2 到web 中
1. 首先配置struts2 核心过滤器
2. 配置struts2 主配置文件
3. 测试
success ! 成功
3. struts2 与spring 整合
整合的原理是, 不让struts2 创建session 了, 直接让spring 代理, struts2 向spring要session就行了
1. 导包 (已经导入)
2. 配置常量(打开default.xml) 查看配置
3. 配置常量
3.4.配置方案1
由struts2继续创建action , 创建之后给spring代理, spring 解决依赖关系, 这种方式解耦,不过这种凡是不推荐使用, 因为, 我们要的是, 对象 全由spring 进行管理, 包括action 的生命周期, 因为spring 中的aop功能都是针对他管理的对象, 才能用, 如果由struts2 创建的化, spring 中的功能用不到action中, 配置如下:
struts2 依然创建action对象,然后给spring 代理
然后再action 中提供注入的set 方法, 直接将service 对象注入到,action中
注意:action 中的属性名称一定 要和applicationContext.xml中的配置对应
3.5.配置方案2
由spring 完全管理action中的生命周期, (注意, 一定要再文件中配置action 的多实例化)
1. 我们在struts2 的配置文件中action 的上面class 直接写applicationContext beanname 的名称,
2. 手动配置, 注入action
这样就可以实现 , action 的全部都有spring代理, 实现了理想的效果
4. 单独整合hibernate
由于和spring 的整合, 事务的隔离级别托管给了spring 容器, 所以不用hibernate 管理, 这段代码不用写了
session 与线程绑定也不能配置了, spring 会管理session 的
1. 导入实体&orm 元数据
2. 配置文件配置
核心配置
辅助配置
字符集问题
引入orm 元数据
3. 测试
成功就代表hibernate 的单独配置成功
5. spring 与hibernate 整合 (把sessionFactory 对象交给spring 管理)
5.1 第一种整合方式 : 仍然使用外部的hibernate 文件
在spring 中配置 一个class 为org.springframework.orm.hibernate5.LocalSessionFactoryBean的类
通过子节点引入外部文件 如下所示
5.2 第二种整合方式 ,把hibernate.cfg.xml 放在applicationcontext.xml 直接不用hibernate.fig.xml
<!-- 方案二 -->
<!-- 配置hibernate 基本信息 -->
<property name="hibernateProperties">
<!-- 这里属于复杂类型注入 -->
<props>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql:///crm</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">123456</prop>
<!-- 设置sql 方言 -->
<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>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.url">
<![CDATA[jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf8]]>
</prop>
</props>
</property>
<!-- 引入orm 元数据 --> <!-- 指定映射目录路径中 -->
<property name="mappingDirectoryLocations" value="classpath:com/zzq/domain">
注意 : 这里的映射路径 不是"." 是/ 严格 区分大小写
5.3 spring 整合c3p0 连接池
引入c3p0 连接池 配置文件
jdbc.jdbcUrl=jdbc:mysql:///crm?useUnicode=true&characterEncoding=utf8
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=123456
在applicationContext.xml中引入db.properties 用context-property-placeholder 标签,location 属性
然后把连接池注入到,sessionFactory 中
这样就配置成功了
6.spring 整合hibernate 环境中,操作数据库
1.书写dao层 和impl 类
我们访问数据库有两种方法, HQL , Criteria , hql 需要匿名内部类,这个比较多一点,但是可以实现查询的 ,还有用criteria 这种的结果只能返回集合, 查询多个比较好用效果如下 :
package com.zzq.dao.impl;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import com.zzq.dao.UserDao;
import com.zzq.domain.User;
// HibernateDaoSupport 需要session对象 因此要注入sessionFactory 对象
public class UserDaoimpl extends HibernateDaoSupport implements UserDao {
public User getByUserCode(final String userCode) {
/*return this.getHibernateTemplate().execute(new HibernateCallback<User>() {
public User doInHibernate(Session session) throws HibernateException {
String hql = "form User where user_code = ? " ;
Query query = session.createQuery(hql);
query.setParameter(0,userCode);
User user = (User) query.uniqueResult();
return user;
}
}); */ /*离线查询对象*/
DetachedCriteria dc =DetachedCriteria.forClass(User.class);
dc.add(Restrictions.eq("user_code",userCode));
List<User> list = (List<User>)this.getHibernateTemplate().findByCriteria(dc) ;
if(list !=null && list.size()>0){
return list.get(0);
}else {
return null ;
}
}
}
2. 配置文件中书写 (要把sessionFactory 工厂类, 传递给userDao) 这样hibernate模板才能用
7. spring的aop 事务
准备工作: 配置核心管理器, 注入sessionFactory对象(没有事务的维持, 所有的操作都是只读操作)
7.1 xml 配置aop
1.配置通知(advice) 书写拦截的方法
2. 然后进行织入
2.1 切点, 用execution 表达式 () 创建 注意: 这里一定是前面用空格的 注意 !!!!!(bug)
2.3 然后织入
把两个名称id 进行映射 、(注意这里一定要 ,一定要在被注入的类中设置set 方法进行 接受,然后这个变量一定名字和配置文件中的名字对应)
7.1 注解 配置aop
1. xml中开启注解配置
2. 直接在类中使用注解(可以在整个 类上加注解, 然后为true 这里就整个类为只读,如果有单独的方法需要我们就把这个加上去,然后改成false 就可以了)
@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
8. 扩大session 域
为了避免使用懒加载的时候出现no-session 的情况,我们需要扩大session 范围,
配置filter