目录
导入相应的jar包
这里用到了Spring的jar包以及数据源的jar
pom.xml的依赖关系如下:
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!--Spring4.3.5-web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!--Spring4.3.5-core-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!--Spring4.3.5-AOP-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
配置数据源dataSource
将Spring与Hibernate进行整合,需要将之前的数据源转移到Spring中,通过Spring初始化数据源,而不再使用Hibernate
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/shop"/>
<property name="user" value="root"/>
<property name="password" value="mysql"/>
</bean>
同时将hibernate.cfg.xml中关于这个地方的配置去除
<hibernate-configuration>
<session-factory>
<!--
<property name="connection.url">jdbc:mysql://localhost:3306/shop</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">mysql</property>-->
<!-- <property name="connection.username"/> -->
<!-- <property name="connection.password"/> -->
<mapping class="com.study.model.CategoryEntity"/>
<mapping resource="com/study/model/CategoryEntity.hbm.xml"/>
</session-factory>
</hibernate-configuration>
配置SessionFactory
存取数据库中的数据都是通过Session进行的,配置SessionFactory,这个的作用是用来产生Session的,使用Hibernate提供的LocalSessionFactoryBean类,dataSource是上一步创建的,通过ref引入进来
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!--<prop key="hibernate.current_session_context_class">thread</prop>-->
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
配置事务管理器
啥是事务管理?
事务管理是对一系列数据库操作进行管理,一个事务包括一个或者多个SQL语句。一个事务是对数据库读写的一个序列。
通过Spring来管理事务,通过Spring对数据库打开,提交,回滚。事务管理器用来管理SessionFactory的,这样所有的由sessionFactory产生的session将会有声明式的管理。
<!--配置事务管理器-->
<bean id="transactionManagers" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
配置advice通知
Spring通知类型分为:前置通知(MethodBeforeAdvice)、后置通知(AfterReturningAdvice)、环绕通知(MethodInterceptor)、异常通知(ThrowsAdvice)。
配置advice是指定那些方法需要什么类型的事务模式
<!--配置advice通知-->
<tx:advice id="advice" transaction-manager="transactionManagers">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
配置AOP切面
<aop:config>
<aop:pointcut id="pointcuts" expression="execution(* com.study.service.impl.*.*(..))"/>
<aop:advisor advice-ref="advice" pointcut-ref="pointcuts"/>
</aop:config>
AOP即面向切面编程,aop:pointcut定义一个切面,expression属性中配置的意思是所有com.study.service.impl包下的所有方法,不管返回值和参数是什么,都要切入事务。该包是属于dao层的,直接操作数据库的。aop:advice将通知和切面结合起来,我们直接使用上面配置好的advice和pointcut,将其引入进来即可。这样配置好了后,意思就是说,凡是com.study.service.impl.*.*(..))包下的方法都需要切入事务管理,具体地,以save、update、delete开头的方法使用REQUIED方式,其他方法使用SUPPORTS方式。
测试
public void hibernate(){
wac = new ClassPathXmlApplicationContext("applicationContext.xml");
categoryService = (CategoryService)wac.getBean("categoryService");
CategoryEntity categoryEntity = new CategoryEntity();
categoryEntity.setId(454353332);
categoryEntity.setType("type");
categoryEntity.setHot((byte) 1);
categoryService.save(categoryEntity);
}
测试代码,通过applicationContext.xml获取到bean,然后将数据插入到数据库
遇到的问题总结
错误1:Batch update returned unexpected row count from update [0]; actual row count: 0;
错因:数据表主键设置了自增长,而在我们插入数据的时候又设置了ID的值导致
错误2:Spring AOP报错之通配符的匹配很全面, 但无法找到元素 'aop:config' 的声明
错因:schemaLocation中xsd路径没有包括
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
错误3:org.hibernate.HibernateException: save is not valid without active transaction
错因:
从3.0.1版本开 始,Hibernate增加了SessionFactory.getCurrentSession()方法。一开始,它假定了采用JTA事务,JTA事务 定义了当前session的范围和上下文(scope and context)。Hibernate开发团队坚信,因为有好几个独立的JTA TransactionManager实现稳定可用,不论是否被部署到一个J2EE容器中,大多数(假若不是所有的)应用程序都应该采用JTA事务管理。 基于这一点,采用JTA的上下文相关session可以满足你一切需要。
更好的是,从3.1开始,SessionFactory.getCurrentSession()的后台实现是可拔插的。因此,我们引入了新的扩展接口(org.hibernate.context.CurrentSessionContext)和新的配置参数(hibernate.current_session_context_class),以便对什么是“当前session”的范围和上下文(scope and context)的定义进行拔插。
因此屏蔽掉<prop key="hibernate.current_session_context_class">thread</prop>,后问题解决