zoukankan      html  css  js  c++  java
  • 【spring 6】Spring和Hibernate的整合:编程式事务

    一、编程式事务简介

    在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择。用过 Hibernate 的人都知道,我们需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。通过 Spring 提供的事务管理 API,我们可以在代码中灵活控制事务的执行。在底层,Spring 仍然将事务操作委托给底层的持久化框架来执行。

    二、实例分析

    2.1,首先,导入Spring、Hibernate的相关jar包,以及所使用数据库的驱动jar,搭建其基本环境

    2.2,其次,编写相关代码


    ApplicationContext配置文件:

    <pre name="code" class="html"><?xml version="1.0" encoding="UTF-8"?>
    
    <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.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    
    	<!-- 注入D层实现 -->
    	<bean id="logManagerImpl" class="com.angel.usermanager.manager.LogManagerImpl"></bean>
    	<bean id="userManagerImpl" class="com.angel.usermanager.manager.UserManagerImpl">
    		<property name="logManager" ref="logManagerImpl"></property>
    		<property name="log" ref="logModel"></property>
    	</bean>
    
    	<!-- 注入实体 -->
    	<bean id="userModel" class="com.angel.usermanager.domain.User"></bean>
    	<bean id="logModel" class="com.angel.usermanager.domain.Log"></bean>
    	
    </beans>
    

    
    

    在Hibernate的配置文件中添加:

    <span style="font-family:KaiTi_GB2312;font-size:18px;"><property name="hibernate.current_session_context_class">thread</property></span>
    注意:

    * 如果是本地事务(jdbc事务)
    <property name="hibernate.current_session_context_class">thread</property>
    * 如果是全局事务(jta事务)
    <property name="hibernate.current_session_context_class">jta</property>

    HibernateUtils类:

    <span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.usermanager.util;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    public class HibernateUtils {
    
    	private static SessionFactory factory;
    	
    	private HibernateUtils() {
    	}
    	
    	static {
    		try {
    			Configuration cfg = new Configuration().configure();
    			factory = cfg.buildSessionFactory();
    		}catch(Exception e) {
    			e.printStackTrace();
    			throw new java.lang.RuntimeException(e);
    		}	
    	}
    	
    	public static SessionFactory getSessionFactory() {
    		return factory;
    	}
    	
    	public static Session getSession() {
    		return factory.openSession();
    	}
    	
    	public static void closeSession(Session session) {
    		if (session != null) {
    			if (session.isOpen()) {
    				session.close();
    			}
    		}
    	}
    }
    </span>


    UserManagerImpl类:

    </pre><pre name="code" class="java">package com.angel.usermanager.manager;
    
    import java.util.Date;
    
    import org.hibernate.Session;
    
    import com.angel.usermanager.domain.Log;
    import com.angel.usermanager.domain.User;
    import com.angel.usermanager.util.HibernateUtils;
    
    public class UserManagerImpl implements UserManager {
    	
    	private LogManager logManager; 
    	public void setLogManager(LogManager logManager) {
    		this.logManager = logManager;
    	}
    	
    	private Log log;
    	public void setLog(Log log){
    		this.log=log;
    	}
    	
    	public void addUser(User user) {
    		Session session = null;
    		try {
    			<span style="color:#ff6666;">session = HibernateUtils.getSessionFactory().getCurrentSession();</span>
    			session.beginTransaction();
    
    			session.save(user);
    
    			log.setType("操作日志");
    			log.setTime(new Date());
    			log.setDetail("Agel7");
    
    			logManager.addLog(log);
    
    			session.getTransaction().commit();
    		} catch (Exception e) {
    			e.printStackTrace();
    			session.getTransaction().rollback();
    		}
    	}
    
    }
    

    测试类:

    <pre name="code" class="java">package com.angel.usermanager.test;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.angel.usermanager.domain.User;
    import com.angel.usermanager.manager.UserManager;
    
    public class Client {
    	public static void main(String[] args) {
    		// 读取配置文件
    		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
    		UserManager userManager = (UserManager) factory.getBean("userManagerImpl");
    		User user = (User) factory.getBean("userModel");
    		user.setName("张三7");
    
    		userManager.addUser(user);
    
    	}
    }
    

    
    


    三、总结

    openSession和getCurrentSession的区别:openSession必须手动关闭,currentSession在事务结束后自动关闭;openSession没有和当前线程绑定,currentSession和当前线程绑定
    采用编程式事务,方便了我们对于事务的理解。但是,事务管理的代码散落在业务逻辑代码中,破坏了原有代码的条理性,并且每一个业务方法都包含了类似的启动事务、提交/回滚事务的样板代码。这就导致了相同代码的反复出现,有没有什么解决方案呢?第一,spring提供了简化方法,在数据访问层非常常见的模板回调模式。第二,声明式事务

  • 相关阅读:
    有点忙啊
    什么是协程
    HDU 1110 Equipment Box (判断一个大矩形里面能不能放小矩形)
    HDU 1155 Bungee Jumping(物理题,动能公式,弹性势能公式,重力势能公式)
    HDU 1210 Eddy's 洗牌问题(找规律,数学)
    HDU1214 圆桌会议(找规律,数学)
    HDU1215 七夕节(模拟 数学)
    HDU 1216 Assistance Required(暴力打表)
    HDU 1220 Cube(数学,找规律)
    HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)
  • 原文地址:https://www.cnblogs.com/hhx626/p/6010306.html
Copyright © 2011-2022 走看看