最近在学习SSH,struts2.3+spring4+hibernate4,都是一些最基本的增删改查,总结了一些问题及解决的办法,如果有错误还请指教。
sessionFactory的配置:
1 <!-- 配置hibernate session工厂 --> <!--hibernate4--> <!-- <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> --> <!--hibernate3--> 2 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 3 <property name="dataSource" ref="dataSource" /> 4 <property name="hibernateProperties"> 5 <props> 6 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> 7 <prop key="hibernate.dialect">${hibernate.dialect}</prop> 8 <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> 9 <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> 10 </props> 11 </property> 13 <!-- 自动扫描注解方式配置的hibernate类文件 --> 14 <property name="packagesToScan"> 15 <list> 16 <value>com.huxin.model</value> 17 </list> 18 </property> 23 </bean>
因为Spring3.1以上版本不再为hibernate提供HibernateTemplate这个类,因此我用的hibernate原生的session:
公共接口:
/** * @author HuXin * @param <T> 公共接口 因此加了范型 */ public interface BaseDao<T> { public void save(T t); public void delete(T t); public void deleteById(String hql,Integer id); public void update(T t); public void saveOrUpdate(T o); //单一查 public T get(Class<T> c, Serializable id); //查询总条数 public Long count(String hql); //全查 public List<T> find(String hql); //分页 public List<T> find(String hql,int pageNo,int pageSize); //用作批量删除 public int executeHql(String hql);
公共接口的实现类:
package com.huxin.DaoImpl; import java.io.Serializable; import java.util.List; import java.util.Map; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.huxin.dao.BaseDao; import com.huxin.model.SshEmployee; @Repository("baseDao") public class BaseDaoImpl<T> implements BaseDao<T> { @Autowired private SessionFactory sessionfactory; //把获得session提出来 ,避免代码重复 private Session getCurrentSession() { return this.sessionfactory.getCurrentSession(); } //------------------------------------------------------- @Override public void save(T t) { this.getCurrentSession().save(t); } @Override public void delete(T t) { this.getCurrentSession().delete(t); } @Override public void deleteById(String hql,Integer id) { Query query = this.getCurrentSession().createQuery(hql); if (id != null) { query.setInteger(0, id); query.executeUpdate(); } } @Override public void update(T t) { this.getCurrentSession().update(t); } @Override public void saveOrUpdate(T t) { this.getCurrentSession().saveOrUpdate(t); } @Override public T get(Class<T> c, Serializable id) { return (T) this.getCurrentSession().get(c, id); } @Override public Long count(String hql) { Query query = this.getCurrentSession().createQuery(hql); return (Long) query.uniqueResult(); } @Override public List<T> find(String hql) { return this.getCurrentSession().createQuery(hql).list(); } @Override public List<T> find(String hql,int pageNo,int pageSize) { Query query = this.getCurrentSession().createQuery(hql); return query.setFirstResult((pageNo-1)*pageSize).setMaxResults(pageSize).list(); } @Override public int executeHql(String hql) { return this.getCurrentSession().createQuery(hql).executeUpdate(); } }
使用hibernate原生的session,当需要访问懒加载的数据时在web.xml中还需要配置一个过滤器:openSessionInViewFilter
web.xml 中的配置。
<!-- openSessionInView配置 一定要在struts2的配置之前 --> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <!-- Struts2配置 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping>
我发现配置openSessionInViewFilter ,启动后他默认是给没有配置事务边界的方法都默认为只读的,当增删改的时候回没效果,即控制台不报错,而数据库并没有被修改,我的解决是:
<!-- 配置事务管理器 --> <bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 定义传播特性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true" /> <tx:method name="list*" propagation="REQUIRED" read-only="true" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="*" propagation="REQUIRED" read-only="false" /> </tx:attributes> </tx:advice> <!-- 关联 哪些类 那些包 那些方法需要配置事务 --> <aop:config> <aop:pointcut expression="execution(* com.huxin.service.impl.*.*(..))" id="mycut" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="mycut" /> </aop:config>