初嘗 Spring Boot 2.1.1 搭配 Hibernate

從 Spring Boot 官方文檔來看,搭配的是 Hibernate 5.3Spring Framework 5.1java

pom.xml依賴mysql

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.1.RELEASE</version>
	<!-- <version>1.5.6.RELEASE</version> -->
</parent>
<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<java.version>1.8</java.version>
</properties>
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<optional>true</optional>
		<scope>true</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
	<dependency>
		<groupId>log4j</groupId>
		<artifactId>log4j</artifactId>
		<version>1.2.17</version>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid-spring-boot-starter</artifactId>
		<version>1.1.10</version>
	</dependency>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>1.2.54</version>
	</dependency>
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-entitymanager</artifactId>
	</dependency>
</dependencies>

application.ymlweb

spring:
  profiles:
    active: application-dev.yml
  datasource:
    druid:
      min-idle: 5  
      max-pool-prepared-statement-per-connection-size: 20  
      test-while-idle: true  
      time-between-eviction-runs-millis: 60000  
      max-active: 20  
      validation-query: SELECT 1 FROM DUAL  
      filters: stat,wall,logback    
      max-wait: 60000  
      test-on-borrow: false  
      pool-prepared-statements: true  
      initial-size: 5  
      min-evictable-idle-time-millis: 300000  
      test-on-return: false  
      password: Cif_5d6b7c
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/levi?serverTimezone=UTC
    username: root
  jpa:
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext

關於建立 Entity 要注意,除了類上要 @Entity@Table 註解以外,必定要在主鍵上標識 @Id 註解,此時項目啓動,能夠自動生成表,並且若是字段上未標識 @Column 註解加 name 屬性,生成數據表時,會自動把字段名由駝峯轉成下劃線命名方式。spring

新的問題是此時沒辦法在 Dao 層注入 SessionFactory。檢查過 WebApplicationContext,發現 Spring Bean 中確實沒有,因而計劃解決方案。sql

方案1:從 EntityManagerFactory 中獲取,結論是沒能成功json

[@Repository](https://my.oschina.net/u/3055569)
@Transactional
public class BaseDaoImpl<T extends BaseEneity> implements BaseDao<T> {

	@PersistenceUnit
	private EntityManagerFactory emf;
	
	@Autowired
	WebApplicationContext webApplicationConnect;
	
	protected EntityManager entityManager() {
		return emf.createEntityManager();
	}
	
	protected Session session() {
		SessionFactory sessionFactory = emf.unwrap(SessionFactory.class);
		//Session session = sessionFactory.openSession();
		//Session session = sessionFactory.getCurrentSession();
		return session;
	}
}

不管是 openSession(),仍是 getCurrentSession(),都不能成功實現簡單的 save 功能。springboot

方案2:配置 WebConfig,這個方法成功了,但並非很滿意session

WebConfig.javaapp

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

@Configuration
public class WebConfig {

	@Autowired
	private JpaProperties jpaProperties;
	@Autowired
	private DataSource dataSource;

	@Bean
	public HttpMessageConverters fastJsonHttpMessageConverters() {
		FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();

		FastJsonConfig fastJsonConfig = new FastJsonConfig();
		fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);

		fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);

		HttpMessageConverter<?> converter = fastJsonHttpMessageConverter;

		return new HttpMessageConverters(converter);

	}

	@Bean
	@Primary
	public EntityManagerFactory entityManagerFactory() {
		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
		factory.setJpaVendorAdapter(vendorAdapter);
		factory.setPackagesToScan("com.judas.springboot.entity");
		factory.setDataSource(dataSource);// 數據源
		factory.setJpaPropertyMap(jpaProperties.getProperties());
		factory.afterPropertiesSet();// 在完成了其它全部相關的配置加載以及屬性設置後,才初始化
		return factory.getObject();
	}
	
	@Bean
	public SessionFactory sessionFactory(EntityManagerFactory emf) {
		SessionFactory sessionFactory = emf.unwrap(SessionFactory.class);
		System.out.println(sessionFactory);
		return sessionFactory;
	}
	
	@Bean
	public PlatformTransactionManager transcationManager(EntityManagerFactory emf) {
		return new HibernateTransactionManager(sessionFactory(emf));
	}
}

如今就能夠在 Dao 層注入 SessionFactory 了。spring-boot

@Autowired
private SessionFactory sessionFactory;

不如意的是,這種狀況若是自動生成數據表,就沒有了字段名稱駝峯轉下劃線的功能。固然這能夠在 hibernate.cfg.xml 配置。但我想表達的是,沒能正常使用 Spring Boot 中的配置,但暫時妥協。

技術博客有好多配置方法比上面簡單,如

@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
    return new HibernateJpaSessionFactoryBean();
}

可看到 HibernateJpaSessionFactoryBean 就感受很不愉快。 還有調用 jpaproperties.getHibernateproperties() 方法的,但這個版本中是沒有此方法的。

有更好解決方案的夥伴能夠討論。

相關文章
相關標籤/搜索