在 Spring Boot 项目中使用 HikariCP 和 Hibernate 的更好方法

Posted

技术标签:

【中文标题】在 Spring Boot 项目中使用 HikariCP 和 Hibernate 的更好方法【英文标题】:Better way to use HikariCP with Hibernate in Spring Boot Project 【发布时间】:2016-05-20 00:01:21 【问题描述】:

我是初学者,我有一个简单的 Spring Boot 项目,这是我第一次使用连接池(在本例中为 HikariCP),我需要您的帮助。它正在工作,但我想知道我是否在 Hibernate 中以正确的方式使用它,或者是否有更好的方法,以及我的 Spring Boot 项目结构是否正确。

编辑:即使我删除了 HikariCPConfig 类,它也能正常工作,我怎么知道连接池是否工作?

项目如下:

- BankManager
   src/main/java
     |
     |__com.manager
        |__BankManagerApplication.java
        |__HikariCPConfig.java
     |__com.manager.dao
        |__ClientRepository.java
     |__com.manager.entities
        |__Client.java
     |__com.manager.service
        |__ClientServiceImpl.java
        |__ClientServiceInterface.java

   src/main/resources
     |__application.properties

BankManagerApplication.java:

@SpringBootApplication

    public class BankManagerApplication 

        public static void main(String[] args)     
            ApplicationContext ctx = SpringApplication.run(BankManagerApplication.class, args);
            ClientServiceInterface service = ctx.getBean(ClientServiceInterface.class);
            service.addClient(new Client("client1"));
            service.addClient(new Client("client2"));
            
    

HikariCPConfig.java:

@Configuration
@ComponentScan
class HikariCPConfig 

   @Value("$spring.datasource.username")
   private String user;

   @Value("$spring.datasource.password")
   private String password;

   @Value("$spring.datasource.url")
   private String dataSourceUrl;

   @Value("$spring.datasource.dataSourceClassName")
   private String dataSourceClassName;

   @Value("$spring.datasource.poolName")
   private String poolName;

   @Value("$spring.datasource.connectionTimeout")
   private int connectionTimeout;

   @Value("$spring.datasource.maxLifetime")
   private int maxLifetime;

   @Value("$spring.datasource.maximumPoolSize")
   private int maximumPoolSize;

   @Value("$spring.datasource.minimumIdle")
   private int minimumIdle;

   @Value("$spring.datasource.idleTimeout")
   private int idleTimeout;

   @Bean
   public HikariDataSource primaryDataSource() 
       Properties dsProps = new Properties();
       dsProps.put("url", dataSourceUrl);
       dsProps.put("user", user);
       dsProps.put("password", password);
       dsProps.put("prepStmtCacheSize",250);
       dsProps.put("prepStmtCacheSqlLimit",2048);
       dsProps.put("cachePrepStmts",Boolean.TRUE);
       dsProps.put("useServerPrepStmts",Boolean.TRUE);

       Properties configProps = new Properties();
          configProps.put("dataSourceClassName", dataSourceClassName);
          configProps.put("poolName",poolName);
          configProps.put("maximumPoolSize",maximumPoolSize);
          configProps.put("minimumIdle",minimumIdle);
          configProps.put("minimumIdle",minimumIdle);
          configProps.put("connectionTimeout", connectionTimeout);
          configProps.put("idleTimeout", idleTimeout);
          configProps.put("dataSourceProperties", dsProps);

      HikariConfig hc = new HikariConfig(configProps);
      HikariDataSource ds = new HikariDataSource(hc);
      return ds;
   

ClientServiceImpl.java

@Service
public class ClientServiceImpl implements ClientServiceInterface 

    @Autowired
    ClientRepository clientRepository; // this class extends JPARepository

    @Override
    public Client addClient(Client c) 
        return clientRepository.save(c);
    

application.properties:

server.port = 8888
spring.jpa.databasePlatform=org.hibernate.dialect.mysql5Dialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update

spring.datasource.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/bank_manager
spring.datasource.username=root
spring.datasource.password=
spring.datasource.poolName=SpringBootHikariCP
spring.datasource.maximumPoolSize=5
spring.datasource.minimumIdle=3
spring.datasource.maxLifetime=2000000
spring.datasource.connectionTimeout=30000
spring.datasource.idleTimeout=30000
spring.datasource.pool-prepared-statements=true
spring.datasource.max-open-prepared-statements=250

提前谢谢你。

【问题讨论】:

【参考方案1】:

你的项目结构是标准的,所以是正确的。

关于光:

Hikari 确实是池化的绝佳选择。我习惯于通过使用您在您的案例中应用的一组较小的参数成功地与 Hikari 合作,但如果它对您有用,那很好。 有关 Hikaru 设置的更多信息,我建议您阅读official wiki,如果您还没有的话。

关于属性加载:

您可以使用一些 SpringBoot 功能来读取 DB 参数并以更少的代码应用到您的运行时 Bean。喜欢:

在 application.properties 中(为您的池参数定义一个自定义前缀“myproject.db”) myproject.db.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource myproject.db.url=jdbc:mysql://localhost:3306/bank_manager myproject.db.username=root ... and the other params below

创建一个 Spring 配置类

@Configuration
public class MyDBConfiguration 

    @Bean(name = "myProjectDataSource")
    @ConfigurationProperties(prefix = "myproject.db")
    public DataSource dataSource()
        //This will activate Hikari to create a new DataSource instance with all parameters you defined with 'myproject.db'
        return DataSourceBuilder.create().build();
    

在您的 ClientRepository 类中:

@Repository
public class ClientRepository 

    //The code below is optional, but will work if you want to use jdbctemplate tied to the DataSource created above. By default all Hibernate Sessions will take the DataSource generated by Spring
    @Bean(name = "myProjectJdbcTemplate")
    public JdbcTemplate jdbcTemplate(@Qualifier("myProjectDataSource") DataSource dataSource)
        return new JdbcTemplate(dataSource);
    

如果您要使用 2 个或更多不同的数据库,还有其他选项可以管理 DataSource bean 创建。您可以更改其他数据库的属性前缀并将 1 个数据源仅注释为 @Primary,当您在 Spring 上下文中拥有超过 1 个数据源时,这是强制性的

【讨论】:

谢谢,帮了大忙。

以上是关于在 Spring Boot 项目中使用 HikariCP 和 Hibernate 的更好方法的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个新的 Spring Boot 项目调用一个 Spring Boot 项目中存在的 Spring Boot api

在spring boot 项目中使用thymeleaf模板;小案例

spring Boot2.在Myecplise上把spring Boot项目打包 war包和jar包

Spring Boot 项目在 IDEA 中 进行单元测试

我们可以在一个项目中同时使用 Java Spring mvc 和 Spring Boot 吗?

在spring boot 项目中使用thymeleaf模板