spring声明式事务处理(hibernate)

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输出:
这里写图片描述

运行之后数据库的内容:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值