从 Spring Boot 官方文档来看,搭配的是 Hibernate 5.3 和 Spring Framework 5.1。
pom.xml依赖
<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.yml
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 属性,生成数据表时,会自动把字段名由驼峰转成下划线命名方式。
新的问题是此时没办法在 Dao 层注入 SessionFactory。检查过 WebApplicationContext,发现 Spring Bean 中确实没有,于是计划解决方案。
方案1:从 EntityManagerFactory 中获取,结论是没能成功
[@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 功能。
方案2:配置 WebConfig,这个方法成功了,但并不是很满意
WebConfig.java
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 了。
@Autowired
private SessionFactory sessionFactory;
不如意的是,这种情况如果自动生成数据表,就没有了字段名称驼峰转下划线的功能。当然这可以在 hibernate.cfg.xml 配置。但我想表达的是,没能正常使用 Spring Boot 中的配置,但暂时妥协。
技术博客有好多配置方法比上面简单,如
@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
return new HibernateJpaSessionFactoryBean();
}
可看到 HibernateJpaSessionFactoryBean 就感觉很不愉快。 还有调用 jpaproperties.getHibernateproperties() 方法的,但这个版本中是没有此方法的。
有更好解决方案的伙伴可以讨论。