您的位置:首页 > 编程语言 > Java开发

spring声明式事务处理(hibernate)

2015-09-24 16:39 513 查看
spring声明式事务处理与hibernate的整合。

在上一个博文我们讨论到了spring声明式事务处理(jdbc操作数据库)。

思路:

1、无论是jdbc还是hibernate,都要使用到datasSource,所以首先要导入dataSource。

2、测试dataSource是否导入成功

3、bean的创建,以及映射文件,hibernate的配置文件,

4、建立dao,service层

5、测试dao,service层,看看能否得到dao/service

6、aop的配置

代码实现如下:

把dataSource放到spring容器中,并测试是否放置成功

以下是spring配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
<!--
datasource的导入,这里是固定写法
-->
<!-- 读取dataSource -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<!--
声明配置文件jdbc.properties的位置
-->
<value>classpath:jdbc.properties</value>
</property>
</bean>

<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 读取dataSource -->

</beans>


/**
* spring_hibernate的测试类
* 在这里为了不重复new  applicationContext的对象,所以把它放出来
*/
public class spring_hibernate_Test {
public static ApplicationContext applicationContext;
static{
applicationContext=new ClassPathXmlApplicationContext("cn/ansel/spring_hibernate/config/applicationContext.xml");

}
@Test
public void testDataSource(){
//测试dataSource是否成功放到spring容器中,如果没有成功,就会报错
System.out.println(applicationContext.getBean("dataSource"));
}
}


运行结果:

org.apache.commons.dbcp.BasicDataSource@983d95


domain,dao,service层,并放到spring容器中(domain中的类不用放到spring容器中)。

首先创建好Person类:

public class Person implements Serializable {
private Long pid;
private String pname;
private String pdescription;
//省略getter&setter
}


因为这里是与hibernate结合,所以要写好映射文件和hibernate的配置文件

以下是Person的映射文件: Person.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--
name代表pojo的全名,这里有个小技巧,可以直接把类名打上去,然后看看提示,
如果没有提示,关了再开就可以看到提示
table对应的表名
-->
<class name="cn.ansel.spring_hibernate.bean.Person" >

<!--
id:代表主键属性
name:主键的名字
column:表中列的名字
length:数据库中字段的长度
type:name的类型
-->
<id name="pid" column="pid" length="111" type="java.lang.Long">

<!--
generator:主键的生成类型
-->
<generator class="increment"></generator>
</id>

<!--
property:代表其他属性
name、column、type、length与上雷同
-->
<property name="pname" column="pname" length="200" type="java.lang.String"></property>
<property name="pdescription" column="pdescription" length="100" type="java.lang.String"></property>
</class>
</hibernate-mapping>


以下是hibernate的配置文件,并且在hibernate的配置文件中把Person的映射文件加到里面

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
数据库的用户名
-->
<session-factory>
<property name="connection.username">root</property>
<!--
密码
-->
<property name="connection.password">root</property>
<!--
url
-->
<property name="connection.url">
jdbc:mysql://localhost:3306/hibernate1
</property>
<!--
作用:根据持久化类和映射文件生成表
validate
create-drop
create
update
-->
<property name="hbm2ddl.auto">update</property>
<!--
显示hibernate内部生成的sql语句
-->
<property name="show_sql">true</property>
<mapping resource="cn/ansel/spring_hibernate/bean/Person.hbm.xml" />
</session-factory>
</hibernate-configuration>


*注hibernate.cfg.xml中添加Person.hbm.xml文件可以直接通过可视化界面添加,这样可以降低出错的几率

编写dao,servicr层:

/**
* 这里dao层就一个方法:保存用户
*/
public interface PersonDao {
public void savePerson(Person person);
}

/**
* 这里是dao的实现层,实现dao的保存用户的方法
* 在这里还要做的事就是把这个实现类继承hibernateDaoSupport类,因为要调用里面的方法来保存用户
*/
public class PersonDaoImpl  extends HibernateDaoSupport implements PersonDao {

@Override
public void savePerson(Person person) {
//得到hibernate模版,调用里面的方法保存用户
this.getHibernateTemplate().save(person);
}
}

/**
* 这里是service层,还是只有一个方法,保存用户,
*
*/
public interface PersonService {
public void savePerson(Person person);
}

/**
* 这里是personService的实现类,在这里主要实现逻辑业务的处理 并在这里要引用personDao,引用其实现类类处理保存用户的方法
* 注意:在这里引入了personDao,不要忘记了创建 其getter&setter方法!
*/
public class PersonServiceImpl implements PersonService {
//personDao的引用
private PersonDao personDao;

@Override
public void savePerson(Person person) {
this.personDao.savePerson(person);
}

// getter setter
public PersonDao getPersonDao() {
return personDao;
}

public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}

}


把dao,service层放到spring容器中

<!--把 sessionFactory放大spring容器,由于这里有2种方法,并且是固定写法,所以我在spring framework开发参考手册直接拷贝过来-->

<!-- 方法一 -->
<!--    这里bean的id一定要跟下面的dao层的property名字对应。下面我们定义了sessionFactory,所以在这里我们也要定义id为sessionFactory -->
<!--    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">-->
<!--    虽然说是用hibernate操作,但是底层还是需要dataSource,所以在这里吧dataSource导入-->
<!--    <property name="dataSource" ref="myDataSource"/>-->
<!--    <property name="mappingResources">-->
<!--      <list>-->
<!--         这里的value的取值为Person映射文件的全名-->
<!--         <value>classpath:cn/ansel/spring_hibernate/config/hibernate.cfg.xml</value>-->
<!--      </list>-->
<!--    </property>-->
<!--     hibernateProperties:表示方言-->
<!--    <property name="hibernateProperties">-->
<!--      <value>-->
<!--        hibernate.dialect=org.hibernate.dialect.MySQLDialect-->
<!--      </value>-->
<!--    </property>-->
<!--  </bean>-->

<!-- 方法二 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 第二种方法比第一种方法简便,只需要把hibernate的配置文件导入到这里即可。 -->
<property name="configLocation">
<value>classpath:cn/ansel/hibernate/config/hibernate.cfg.xml</value>
</property>
</bean>

<!--
把dao,service放到sprig容器
由于这里继承了hibernateDaoSupport这个类,这里需要导入的属性是sessionFactory,而不是dataSource
由于这里需要引入sessionFacroty,所以要先把sessionFactory放到spring容器中
-->
<bean id="personDao" class="cn.ansel.spring_hibernate.dao.impl.PersonDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<!--配置service -->
<bean id="personService" class="cn.ansel.spring_hibernate.service.impl.PersonServiceImpl">
<property name="personDao">
<ref bean="personDao"/>
</property>
</bean>


测试dao,service是否成功放到spring容器

/**
* 测试dao/service是否成功放到spring容器,如果没有成功,在获取的时候会报错
*/
@Test
public void testDao(){
applicationContext.getBean("personDao");
}

@Test
public void testService(){
applicationContext.getBean("personService");
}


运行测试类,都安全通过。

aop的配置

<!-- aop配置顶层-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<!-- 在这里创建tx(就是我们前面说的通知,这通知有2个作用) -->
<tx:advice id="tx" transaction-manager="transactionManager">
<tx:attributes>
<!-- 剩下的跟jdbc的aop配置差不多 -->
<tx:method name="save*" read-only="false"/>
</tx:attributes>
</tx:advice>

<!--
aop的配置
在这里因为在aop:advisor中引用到了tx,所以在这之前要创建出tx
-->
<aop:config>
<aop:pointcut expression="execution(* cn.ansel.spring_hibernate.service.impl.*.*(..))" id="perform"/>
<aop:advisor advice-ref="tx" pointcut-ref="perform"/>
</aop:config>


测试类:

/**
* 测试类 ,保存一个用户
*/
@Test
public void testSave(){
PersonService personService= (PersonService) applicationContext.getBean("personService");
Person person=new Person();
person.setPdescription("aaa");
person.setPname("ansel");
personService.savePerson(person);
}


运行之前数据库的内容:



运行结果



myEcplise输出:



运行之后数据库的内容:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 事务