1、添加两个框架的支持 2、第一种整合方式: a)在spring配置文件里添加action的bean,注入service层对象 b)在srtuts.xml里配置的action的class为对应的bean的ID c)Spring的bean的作用域设置为scope=”prototype” 3、第二种整合方式 a)在spring的配置文件里不创建action的bean b)Struts.xml里的class还是原来的action类的路径 c)在action中创建的service层对象的属性名称与spring配置文件里的service层bean的id一一对应,spring会自动注入。
1、添加两个框架支持 - Hibernate必须导入3.3版本的,不能使用4.0以上的版本 - 如果先添加hibernate,在添加spring,那么会保留hibernate的配置文件,在spring配置文件中会读取hibernate配置文件
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml"> </property> </bean> 如果后添加hibernate,那么hibernate配置信息可以直接写到spring配置文件中,可以不要hibernate配置文档 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"> </property> <property name="username" value="admin"></property> <property name="password" value="admin"></property> <!--由于driverclass不会自动生成,需要手动添加--> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.Oracle9Dialect </prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> 上述两种情况只是myeclipse添加时自动选择的结果,也可手动变换。不管哪种情况,spring都需要创建一个sessionFactory的bean,这个bean用来创建session操作数据库2、实现类写法
实现类不再使用之前hibernatesessionfactory工具类来操作Spring对hibernate的操作也有封装将实现类继承HibernateDaoSupport并且实现需要注入sessionFactory对象,虽然在此类中并没有看到sessionFactory属性,其实注入的是父类HibernateDaoSupport里的sessionFactory属性 <bean id="td" class="dao.impl.TblDaoImpl"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> 该类有个getHibernateTemplate() 方法等同于hibernate的session该方法返回结果为HibernateTemplate使用改类的find、save、get、delete、update等方法实现数据操作 public class TblDaoImpl extends HibernateDaoSupport implements TblDao{ public List<TblUser> getAll() { return super.getHibernateTemplate().find("from TblUser"); } public TblUser getUser(int id){ return super.getHibernateTemplate().get(TblUser.class, id); } public void delTbl(int id){ super.getHibernateTemplate().delete(getUser(id)); } public void editTbl(TblUser tu){ super.getHibernateTemplate().update(tu); } public int addTbl(TblUser tu){ return Integer.parseInt(super.getHibernateTemplate().save(tu).toString()); } }3、添加事务支持
事务一般添加在service层由于触发事务回滚需要抛出异常,所以service不捕获异常,全部由action层来捕获Spring有专门的类来管理事务 <bean id="txm" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> Spring使用aop的方式把事务添加到指定的切面 <tx:advice id="txadvice" transaction-manager="txm"> <tx:attributes> <tx:method name="add*"/> <tx:method name="edit*"/> <tx:method name="del*"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* service.*.*(..))" id="pc"/> <aop:advisor advice-ref="txadvice" pointcut-ref="pc"/> </aop:config>4、整合过程中还需要删除一个包 - 如果报classNotFoundException:org/ogject/asm/type - 删除hibernate的cglib.2.2.jar包,因为与spring的包冲突,删除完后要清空服务器
5、使用注解实现配置
a)@Repository :用于标注DAO类b)@Service :用于标注业务类c)@Controller :用于标注控制器类d)使用@Autowired注解实现Bean的自动装配,默认按类型匹配,可以使用@Resource指定Bean的名称 @Service public class StuService { @Autowired StuDao sd; public void setSd(StuDao sd) { this.sd = sd; } } 由于dao层没有sessionFactory,那么需要重写父类的setSessionFacotry方法来注入 @Repository public class StuDaoImpl extends HibernateTemplate implements StuDao{ @Override @Autowired public void setSessionFactory(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); } spring配置文件里添加扫描注解配置 <context:component-scan base-package="com.*"></context:component-scan> base-package指定扫描哪些包 6、使用注解实现事务添加注解事务驱动 <bean id="tx" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <tx:annotation-driven transaction-manager="tx"/> 在servicec层需要添加事务的方法上添加@Transactional注解 @Transactional public void addStu(Student stu) { sd.addStu(stu); int a = 1/0; delStu(stu.getStuid()); }1、hibernate连接信息需要整合到spring配置文件中,不要用单独的hibernate配置文件 2、使用myeclipse整合spring与hibernate4,spring配置文件默认生成事物管理类bean与事务注解扫描,推荐使用注解声明事物
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" />3、Spring与hibernate3整合时可以使用的hibernateTemplater类,在整合hibernate4或者以上版本之后不推荐使用hibernateTemplater,建议使用hibernate原生的api,这样更加灵活。
4、整合时获取session不再使用openSession()的方法来打开session,而是使用getCurrentSession()方法来获取session
5、那么配置要保证能够从线程中获取session,需要配置openSessionInView过滤器,spring自带了此过滤器,直接配置即可
<filter> <filter-name>openSession</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>openSession</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>6、在实现类中如果要操作数据库,还是使用hibernate的的api操作
@Repository public class CopyOfStuDaoImpl implements StuDao{ @Autowired SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } Session getSession(){ return sessionFactory.getCurrentSession(); }7、在实际编程中可自行创建工具类方便操作 该工具类还可添加常用的数据库操作方法。例如增删查改等。类似于自定义一个hiberntaTemplater类。使用这种方式需要在实现类继承此类,并注入sessionFactory对象。
package util; import java.io.Serializable; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; /** * hibernateDao工具类 * @author Administrator * */ public class HibernateSessionFactory { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /** * 封装session对象 * @return */ public Session getSession(){ return sessionFactory.getCurrentSession(); } /** * 新增对象 * @param obj */ public Serializable save(Object obj){ return getSession().save(obj); } /** * 删除对象 * @param obj */ public void delete(Object obj){ getSession().delete(obj); } /** * 修改对象 * @param obj */ public void update(Object obj){ getSession().update(obj); } /** * 根据主键查询指定对象 * @param cls * @param id * @return */ public <T> T get(Class<T> cls,Serializable id){ return (T) getSession().get(cls, id); } /** * 查询所有数据 * @param hql * @return */ public List find(String hql){ return getSession().createQuery(hql).list(); } /** * 根据参数查询 * @param hql * @param val * @return */ public List find(String hql,Object... val){ Query query = getSession().createQuery(hql); for(int i=0;i<val.length;i++){ query.setParameter(i, val[i]); } return query.list(); } /** * 分页查询 * @param hql * @param fistResult * @param maxResult * @param val * @return */ public List find(String hql,int fistResult,int maxResult,Object... val){ Query query = getSession().createQuery(hql); for(int i=0;i<val.length;i++){ query.setParameter(i, val[i]); } query.setFirstResult(fistResult); query.setMaxResults(maxResult); return query.list(); } /** * 根据命名参数查询 * @param hql * @param obj * @return */ public List findByNamed(String hql,Object obj){ Query query = getSession().createQuery(hql); query.setProperties(obj); return query.list(); } /** * 分页查询 * @param hql * @param obj * @param fistResult * @param maxResult * @return */ public List findByNamed(String hql,Object obj,int fistResult,int maxResult ){ Query query = getSession().createQuery(hql); query.setProperties(obj); query.setFirstResult(fistResult); query.setMaxResults(maxResult); return query.list(); } }