在写以下代码时需要注意几个问题:
-
所有的实体类如果不是通过其他对象获取,请使用 @Bean注解注入的方式获取,否则你会发现总有几个获取到的对象为null
-
SessionFactory 是通过LocalSessionFactoryBean对象的getObject()方法获取的对象,不需要使用@Bean进行注入,否则会导致LocalSessionFactoryBean和SessionFactory出现冲突,因为在LocalSessionFactoryBean中已经实例化了一个Session工厂。
-
mysql默认时区为美国,所以要在mysql 连接的后面加上?serverTimezone=UTC
-
hibernate事务工厂管理类
package com.spring.config;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.SessionFactory;
import org.hibernate.dialect.MySQLDialect;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager;
import java.util.Properties;
@Configuration
public class TransactionManager {
/**
* 配置数据源
* @return
*/
@Bean("dataSource")
public BasicDataSource getDataSource() {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");//设置MYSQL 驱动
//这里出现一个The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone
//这是因为mysql默认为美国的时区,而我们中国所在地区时区与美国不一样所导致,在url后面添加 ?serverTimezone=UTC解决
basicDataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC");//设置mysql连接URL
basicDataSource.setUsername("root");//设置mysql用户名
basicDataSource.setPassword("123456");//设置mysql密码
return basicDataSource;
}
@Bean("LocalSessionFactoryBean")
public LocalSessionFactoryBean getLocalSessionFactoryBean() {
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
Properties properties = new Properties();
properties.setProperty("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect");
localSessionFactoryBean.setHibernateProperties(properties);
return localSessionFactoryBean;
}
/**
* 下面注释掉的这种做法是错误的,因为我们可以直接通过localSessionFactoryBean.getObject()获取SessionFactory对象
* 并且如果如下进行注入,LocalSessionFactoryBean对象中已存在SessionFactory会导致在spring容器中存在两个
* SessionFactory导致冲突并且会报以下错误:
* Method requestMappingHandlerMapping in org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration required a single bean, but 2 were found:
* - LocalSessionFactoryBean: defined by method 'getLocalSessionFactoryBean' in class path resource [com/spring/config/TransactionManager.class]
* - SessionFactory: defined by method 'getSessionFactory' in class path resource [com/spring/config/TransactionManager.class]
* @param localSessionFactoryBean
* @return
*/
/*@Bean("SessionFactory")
public SessionFactory getSessionFactory(@Qualifier("LocalSessionFactoryBean")LocalSessionFactoryBean localSessionFactoryBean) {
return localSessionFactoryBean.getObject();
}*/
/**
* 配置hibernate事务管理
* @return
*/
@Bean("HibernateTransactionManager")
public HibernateTransactionManager getHibernateTransactionManager(@Qualifier("dataSource") BasicDataSource basicDataSource,@Qualifier("LocalSessionFactoryBean") LocalSessionFactoryBean sessionFactory) {
HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager();
/*localSessionFactoryBean.setMappingResources("");*///配置hibernate的xml实体映射文件
hibernateTransactionManager.setDataSource(basicDataSource);
//下面注意:你都让spring容器去管理类了,当然不能自己new了
//要用spring的getBean方法去创建实例 这样spring才能帮你注入
hibernateTransactionManager.setSessionFactory(sessionFactory.getObject());//这里要注意,sessionFactory必须是Spring注入的不然获取到的值为null
return hibernateTransactionManager;
}
/* @Bean
public JtaTransactionManager getJtaTransactionManager() {
return null;
}*/
}
-
pom.xml文件
下面的代码要注意一个地方就是我的mysql驱动为mysql 8的连接驱动,如果是其他版本请注意修改
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.spring</groupId>
<artifactId>spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>