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提供了简化方法,在数据访问层非常常见的模板回调模式。第二,声明式事务

  • 相关阅读:
    Spring Cloud 模块简介2
    Eureka简介
    Spring Cloud 模块简介
    成神之路-基础篇 转
    Java面试题无答案
    java程序猿常用Linux命令
    Java工程师成神之路 转
    大型网站技术架构 大纲
    Mockito 相关资料
    webApp路由控制-vue-router2.0
  • 原文地址:https://www.cnblogs.com/hhx626/p/6010306.html
Copyright © 2011-2022 走看看