Spring4Hibernate事務控制(註解版)

第一篇:《Spring4純註解啓動》的博客http://www.javashuo.com/article/p-wjwzjchq-ma.htmljava

第二篇:《SpringSecurity安全性框架實戰》的博客http://www.javashuo.com/article/p-htsxdbfd-ma.htmlmysql

你們好,繼前面兩篇文章以後,今天跟你們分享一下註解版的Spring4Hibernate實戰,以及對事務的控制。本demo基於第一篇文章的基礎上實現的。以後我會開放項目的git地址。git

目錄:(紅色)web

DbConfig:spring

package com.spittr.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;


/**
 * 數據庫鏈接配置
 * 實現事務
 * @author zoe
 * 2017年2月9日
 */
@Configuration
public class DbConfig {
	
	/**
	 * 數據庫鏈接
	 * jdbc驅動
	 * @return
	 */
	@Bean
	public DataSource developDataSource(){
		DriverManagerDataSource ds = new DriverManagerDataSource();
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl("jdbc:mysql://localhost:3306/app?characterEncoding=utf8");
		ds.setUsername("root");
		ds.setPassword("zoe13120");
		return ds;
	}
	
	/**
	 * 裝配sessionFactory
	 * @param dataSource
	 * @return
	 */
	@Bean
	public LocalSessionFactoryBean sessionFactory(DataSource dataSource){
		LocalSessionFactoryBean sfb = new LocalSessionFactoryBean();
		sfb.setDataSource(dataSource);
		sfb.setPackagesToScan("com.spittr.web.model");
		Properties properties = new Properties();
		properties.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLDialect");
		properties.setProperty("hibernate.show_sql","true");
		properties.setProperty("hibernate.format_sql","false");
		sfb.setHibernateProperties(properties);
		return sfb;
	}
	
	/**
	 * 裝配hibernat事務管理器
	 * @param sessionFactory
	 * @return
	 */
	@Bean
	public HibernateTransactionManager hibernateTransactionManager(SessionFactory sessionFactory){
		HibernateTransactionManager htm = new HibernateTransactionManager(sessionFactory);
		return htm;
	}

}

WebConfig:sql

package com.spittr.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * web啓動配置文件
 * @author zoe
 *
 */
@Configuration
@EnableWebMvc
@ComponentScan("com.spittr.web")
@EnableTransactionManagement
public class WebConfig extends WebMvcConfigurerAdapter {
		
	@Bean
	public ViewResolver viewResolver(){
		InternalResourceViewResolver resolver = new InternalResourceViewResolver();//jsp視圖解析器
		resolver.setPrefix("/WEB-INF/view/");
		resolver.setSuffix(".jsp");
		resolver.setExposeContextBeansAsAttributes(true);
		return resolver;
	}
	
	/**
	 * 配置靜態資源的處理
	 * 將請求交由Servlet處理,不通過DispatchServlet
	 */
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
		configurer.enable();
	}
}

在這個類上必定要加@EnableTransactionManagement註解,不然事務沒法開啓。數據庫

將這兩個類配置好,tomcat應該就能夠啓動了。剩下的就是建立Repository,而後再Repository上配置事務。tomcat

HibernateRepository:安全

package com.spittr.web.repository;

import org.hibernate.Session;

/**
 * hibernate倉庫
 * @author zoe
 * 2017年2月9日
 * @param <T>
 */
public interface HibernateRepository<T> {
	
	public Session currentSession();
	
	/**
	 * 查詢對象經過ID
	 * @param clazz
	 * @param id
	 * @return
	 */
	public T queryEntityById(Class<T> clazz,String id);
	
	/**
	 * 保存&更新對象
	 * @param t
	 */
	public void saveOrUpdateEntity(T t);

}

HibernateRepositoryImpl:session

package com.spittr.web.repository;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional
@SuppressWarnings("unchecked")
public class HibernateRepositoryImpl<T> implements HibernateRepository<T> {
	
	@Autowired
	private SessionFactory sessionFactory;

	@Override
	public Session currentSession() {
		return sessionFactory.getCurrentSession();
	}

	@Override
	@Transactional(readOnly=true)
	public T queryEntityById(Class<T> clazz,String id) {
		return (T) currentSession().get(clazz, id);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void saveOrUpdateEntity(T t) {
		currentSession().saveOrUpdate(t);
	}

}

注意,在這個實現類中,是控制事務的關鍵。在@Transactional這個註解裏,有多個屬性能夠配置,如propagation控制的是「傳播行爲」,readOnly控制的是「只讀」等;

數據庫鏈接成功,Repository事務已加入,剩下的就是具體的業務代碼。這一塊我寫的比較簡單,測試用。

有一點要注意,我整合出了一個新的註解類@ServiceWithTransaction,主要內容是Spring的@Service加上@Transactional。

package com.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 帶事務控制的service註解
 * @author zoe
 * 2017年2月9日
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
@Transactional
public @interface ServiceWithTransaction {
	String value() default "";
}

控制層我就不提供了,你們隨便找一個controller就能夠了。

RepositoryService:

package com.spittr.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.annotation.ServiceWithTransaction;
import com.spittr.web.model.SysMenu;
import com.spittr.web.repository.HibernateRepository;

/**
 * 
 * @author zoe
 * 2017年2月9日
 */
@ServiceWithTransaction
//或者以下
//@Service
//@Transactional
public class RepositoryService {
	
	@Autowired
	private HibernateRepository<SysMenu> hibernateRepository;
	
	public String repository() {
		SysMenu entity = hibernateRepository.queryEntityById(SysMenu.class,"1");
		SysMenu t = new SysMenu();
		t.setId("134");
		hibernateRepository.saveOrUpdateEntity(t);
		SysMenu t2 = new SysMenu();
		t2.setId("138");
		hibernateRepository.saveOrUpdateEntity(t2);
		return "repository";
	}
}
相關文章
相關標籤/搜索