声明:删除springmvc的jar配置改成springboot的,若别的组件依赖springboot该升级就升级,该删掉就删掉,此文章只记录升级后的坑,升级springboot所需的jar请自行百度。
一.Hibernate的坑
概念:jpa和Hibernate的关系,jpa是接口,Hibernate是实现。
升级后yml文件配置数据库的代码
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://**:3306/**?autoReconnect=true
username: ******
password: ******
因为老代码没用Hibernate直接操作数据库,而是用Session操作的数据库,代码如下:
@Autowired
@Qualifier("sessionFactory")
private SessionFactory sessionFactory;
public Session getSession() {
return this.sessionFactory.getCurrentSession();
}
所以yml配置文件无法直接使用,需要重新配置数据源,若不配做则会报sessionFactory为null。
重新配置数据源如下代码:
import com.zaxxer.hikari.HikariDataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
public class HibernateDataSourceConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(DataSourceProperties properties) {
// DataSource build = DataSourceBuilder.create(properties.getClassLoader())
// .type(HikariDataSource.class)
// .driverClassName(properties.determineDriverClassName())
// .url(properties.determineUrl())
// .username(properties.determineUsername())
// .password(properties.determinePassword())
// .build();
// return build;
HikariDataSource dataSource = hikariDataSource();
dataSource.setDriverClassName(properties.determineDriverClassName());
dataSource.setJdbcUrl(properties.determineUrl());
dataSource.setUsername(properties.determineUsername());
dataSource.setPassword(properties.determinePassword());
return dataSource;
}
private HikariDataSource hikariDataSource(){
HikariDataSource dataSource = new HikariDataSource();
dataSource.setMinimumIdle(0);
dataSource.setMaximumPoolSize(10);
dataSource.setAutoCommit(true);
dataSource.setIdleTimeout(10000);
dataSource.setPoolName("DatebookHikariCP");
dataSource.setMaxLifetime(30000);
dataSource.setConnectionTimeout(1000);
dataSource.setConnectionTestQuery("SELECT 1");
return dataSource;
}
@Bean(name = "entityManagerFactoryBean")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder,@Qualifier("dataSource") DataSource dataSource){
return builder.dataSource(dataSource)
.properties(getVendorProperties(dataSource))
//设置实体类所在位置
.packages("***")
.persistenceUnit("")
.build();
}
private Map<String,Object> getVendorProperties(DataSource dataSource){
// return jpaProperties.getHibernateProperties(dataSource);
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
/**
* EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory
* 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session,
* mybatis的sqlSession.
* @param builder
* @return
*/
@Bean(name = "entityManagerFactory")
public EntityManagerFactory entityManagerFactory(EntityManagerFactoryBuilder builder,@Qualifier("dataSource") DataSource dataSource){
return this.entityManagerFactoryBean(builder,dataSource).getObject();
}
@Bean(name = "sessionFactory")
public SessionFactory sessionFactory(EntityManagerFactoryBuilder builder,@Qualifier("dataSource") DataSource dataSource){
return this.entityManagerFactory(builder,dataSource).unwrap(SessionFactory.class);
}
/**
* 配置事物管理器
*/
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder,@Qualifier("dataSource") DataSource dataSource){
return new JpaTransactionManager(entityManagerFactory(builder,dataSource));
}
}
数据源是用Hikari管理,但直接在yml配置Hikari参数不生效,所以Hikari参数写在代码中了。
二.GeneratedValue的坑
@Id
@GeneratedValue
@Column(
name = "ID",
updatable = false
)
private Long id;
以上的代码是老代码的配置,GeneratedValue中strategy默认配置是AUTO,所以直接执行保存会报错Table ‘xxx.hibernate_sequence’ doesn’t exist,因为升级spring-boot-starter-data-jpa使用了hibernate5,解决方法:以下两种
spring:
jpa:
hibernate:
use-new-id-generator-mappings: false
@GeneratedValue(strategy = GenerationType.IDENTITY)
三.request.getParameterMap的坑
如上图,request.getParameterMap()在springmvc中可以获取到Content-Type: application/x-www-form-urlencoded中的值,但在springboot2中无法获取。若在springboot2中获取到值需要以下改造。
Enumeration<String> keys = request.getParameterNames();
Map<String, String[]> resMap = new HashMap<>();
while (keys.hasMoreElements()){
String key = keys.nextElement();
String[] value = request.getParameterValues(key);
resMap.put(key,value);
}
经历一天的改造,终于结束,但是不确定会不会有别的坑,需要多测试。