第一篇:《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"; } }