春季启动 jdbc 连接

Posted

技术标签:

【中文标题】春季启动 jdbc 连接【英文标题】:Spring boot jdbc Connection 【发布时间】:2015-06-26 02:49:04 【问题描述】:

我正在尝试配置 Spring Boot,以便将 tomcat 连接池连接到我的生产数据库。 我的应用程序不是网络应用程序(我也很难告诉春天)。

我有一个 Startup 课程和另外 3 个课程

代码

@Configuration

@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)

public class Starter 

private static Logger logger;

@Autowired
private static MyController controller;

public static void main(String[] args) 

//      SpringApplication.setWebEnvironment(false);

    SpringApplication.run(Starter.class, args);

    LogbackConfigLoader lcl = new LogbackConfigLoader();
    if (lcl.init()) 
        logger = LoggerFactory.getLogger(Starter.class);
        logger.debug("Initialized....");
    
    else
        logger = LoggerFactory.getLogger(Starter.class);
    


    logger.info(controller.getProva());





这里是配置 `

@Configuration

@ConfigurationProperties(prefix="datasource.NIS")

public class NISDBConfiguration 

private String jdbcInterceptors;
private long validationInterval = 30000;

private org.apache.tomcat.jdbc.pool.DataSource pool;

@Value("$driver-class-name")
private String driverClassName;

@Value("$url")
private String url;

@Value("$username")
private String username;

@Value("$password")
private String password;

@Value("$maxActive")
private int maxActive = 30;

@Value("$maxIdle")
private int maxIdle = 8;

@Value("$minIdle")
private int minIdle = 8;

@Value("$initialSize")
private int initialSize = 10;

private String validationQuery;

private boolean testOnBorrow;

private boolean testOnReturn;

private boolean testWhileIdle;

private Integer timeBetweenEvictionRunsMillis;

private Integer minEvictableIdleTimeMillis;

private Integer maxWaitMillis;

public String getJdbcInterceptors() 
    return jdbcInterceptors;


public void setJdbcInterceptors(String jdbcInterceptors) 
    this.jdbcInterceptors = jdbcInterceptors;


public long getValidationInterval() 
    return validationInterval;


public void setValidationInterval(long validationInterval) 
    this.validationInterval = validationInterval;


public org.apache.tomcat.jdbc.pool.DataSource getPool() 
    return pool;


public void setPool(org.apache.tomcat.jdbc.pool.DataSource pool) 
    this.pool = pool;


public String getDriverClassName() 
    return driverClassName;


public void setDriverClassName(String driverClassName) 
    this.driverClassName = driverClassName;


public String getUrl() 
    return url;


public void setUrl(String url) 
    this.url = url;


public String getUsername() 
    return username;


public void setUsername(String username) 
    this.username = username;


public String getPassword() 
    return password;


public void setPassword(String password) 
    this.password = password;


public int getMaxActive() 
    return maxActive;


public void setMaxActive(int maxActive) 
    this.maxActive = maxActive;


public int getMaxIdle() 
    return maxIdle;


public void setMaxIdle(int maxIdle) 
    this.maxIdle = maxIdle;


public int getMinIdle() 
    return minIdle;


public void setMinIdle(int minIdle) 
    this.minIdle = minIdle;


public int getInitialSize() 
    return initialSize;


public void setInitialSize(int initialSize) 
    this.initialSize = initialSize;


public String getValidationQuery() 
    return validationQuery;


public void setValidationQuery(String validationQuery) 
    this.validationQuery = validationQuery;


public boolean isTestOnBorrow() 
    return testOnBorrow;


public void setTestOnBorrow(boolean testOnBorrow) 
    this.testOnBorrow = testOnBorrow;


public boolean isTestOnReturn() 
    return testOnReturn;


public void setTestOnReturn(boolean testOnReturn) 
    this.testOnReturn = testOnReturn;


public boolean isTestWhileIdle() 
    return testWhileIdle;


public void setTestWhileIdle(boolean testWhileIdle) 
    this.testWhileIdle = testWhileIdle;


public Integer getTimeBetweenEvictionRunsMillis() 
    return timeBetweenEvictionRunsMillis;


public void setTimeBetweenEvictionRunsMillis(
        Integer timeBetweenEvictionRunsMillis) 
    this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;


public Integer getMinEvictableIdleTimeMillis() 
    return minEvictableIdleTimeMillis;


public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) 
    this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;


public Integer getMaxWaitMillis() 
    return maxWaitMillis;


public void setMaxWaitMillis(Integer maxWaitMillis) 
    this.maxWaitMillis = maxWaitMillis;
 

@Bean(name = "dsNIS") 
public DataSource dataSource()  
    this.pool = new org.apache.tomcat.jdbc.pool.DataSource();
    this.pool.setDriverClassName(getDriverClassName());
    this.pool.setUrl(getUrl());
    this.pool.setUsername(getUsername());
    this.pool.setPassword(getPassword());
    this.pool.setInitialSize(getInitialSize());
    this.pool.setMaxActive(getMaxActive());
    this.pool.setMaxIdle(getMaxIdle());
    this.pool.setMinIdle(getMinIdle());
    this.pool.setTestOnBorrow(isTestOnBorrow());
    this.pool.setTestOnReturn(isTestOnReturn());
    this.pool.setTestWhileIdle(isTestWhileIdle());

    if (getTimeBetweenEvictionRunsMillis() != null) 
        this.pool
                .setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
    
    if (getMinEvictableIdleTimeMillis() != null) 
        this.pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
    
    this.pool.setValidationQuery(getValidationQuery());
    this.pool.setValidationInterval(this.validationInterval);
    if (getMaxWaitMillis() != null) 
        this.pool.setMaxWait(getMaxWaitMillis());
    
    if (this.jdbcInterceptors != null) 
        this.pool.setJdbcInterceptors(this.jdbcInterceptors);
    
    return this.pool;

 

@PreDestroy
public void close() 
    if (this.pool != null) 
        this.pool.close();
    


@Bean(name = "jdbcNIS") 
public JdbcTemplate jdbcTemplate(DataSource dsNIS)  
    return new JdbcTemplate(dsNIS); 

`

存储库

package org.hp.data;

@Repository

public class NisRepository 

protected final Logger log = LoggerFactory.getLogger(getClass()); 


@Autowired 
@Qualifier("jdbcNIS") 
protected JdbcTemplate jdbc; 


public String getItem(long id)  
    return jdbc.queryForObject("SELECT * FROM sb_item WHERE id=?", itemMapper, id); 
 

private static final RowMapper<String> itemMapper = new RowMapper<String>() 
    @Override
    public String mapRow(ResultSet rs, int rowNum) throws SQLException  
        String item = rs.getString("title"); 
        return item; 
     
;


public JdbcTemplate getJdbc() 
    return jdbc;


public void setJdbc(JdbcTemplate jdbc) 
    this.jdbc = jdbc;
 

控制器

@Controller
public class MyController 


@Autowired 
private NisRepository items; 

public NisRepository getItems() 
    return items;


public void setItems(NisRepository items) 
    this.items = items;


public String getProva()
    return items.getItem(10);

但我在运行 NullPointerException 的应用程序时总是会出现异常,因为 MyController 不是自动装配的并且始终为空。

我也尝试用 new 创建一个新实例(但我认为这是不正确的,因为 spring mvc 模式)。

这里有什么问题?

提前致谢

【问题讨论】:

Spring 不会自动装配静态字段。它只自动装配 Spring bean 的实例字段。如果您不希望您的应用程序被视为 Web 应用程序,为什么要使用 @Controller,它用于注释 Spring MVC(即 Web)控制器? 我是 Spring 新手,很抱歉我的明显问题。事实上,我这里唯一需要的只是一个到数据库的连接池,以便并行执行一些任务。 我试图修改 MyController 类删除 @Controller 注释。我还从 Starter 类中删除了静态字段并添加了 MyController controller = new MyController(); logger.info(controller.getProva()); 但仍然在 MyController 内的 NisRepository 自动装配变量上获得 NullPointer 【参考方案1】:

您正在使用 Spring Boot,但正在努力不使用它。您还声明您没有使用 Web 应用程序,但为什么您有 @Controller

要解决您的问题,请删除 DataSourceJdbcTemplate 的配置,Spring Boot 将为您配置这些。这基本上意味着删除您的 NISDBConfiguration 类。只需将正确的属性添加到 application.properties 文件即可。

spring.datasource.driver-class-name=<your-driver-here>
spring.datasource.url=<your-url>
spring.datasource.username=<your-username>
spring.datasource.password=<your-password>

当然还有您需要的其他属性,请查看the reference guide 了解更多属性。

从存储库中的JdbcTemplate 属性中删除@Qualifier,您也不需要getter 和setter。我建议使用基于构造函数的注入。

package org.hp.data;

@Repository
public class NisRepository 

    protected final Logger log = LoggerFactory.getLogger(getClass()); 

    protected final JdbcTemplate jdbc; 

    @Autowired
    public NisRepository(JdbcTemplate jbc) 
        this.jdbc=jdbc;
    

    public String getItem(long id)  
        return jdbc.queryForObject("SELECT * FROM sb_item WHERE id=?", itemMapper, id); 
     


    private static final RowMapper<String> itemMapper = new RowMapper<String>() 
        @Override
        public String mapRow(ResultSet rs, int rowNum) throws SQLException  
            String item = rs.getString("title"); 
            return item; 
         
    ;


如果您没有 Web 应用程序,请将 @Controller 替换为 @Service

然后重写你的入门类。

@SpringBootApplication
public class Starter 

    private static Logger logger;

    public static void main(String[] args) 

    //      SpringApplication.setWebEnvironment(false);

        ApplicationContext ctx = SpringApplication.run(Starter.class, args);

        LogbackConfigLoader lcl = new LogbackConfigLoader();
        if (lcl.init()) 
            logger = LoggerFactory.getLogger(Starter.class);
            logger.debug("Initialized....");
        
        else
            logger = LoggerFactory.getLogger(Starter.class);
        

        MyController controller = ctx.getBean(MyController.class);
        logger.info(controller.getProva());

    



看起来您还试图绕过这里的弹簧靴配置加载?尝试使用框架而不是反对它。

如果您没有 Web 应用程序,请不要在依赖项中包含 spring-boot-starter-web,并确保其中没有任何其他与 Web 相关的内容。 Spring Boot 自动检测 Web 环境并尝试为此引导类,如果这些类不存在,它将作为纯 Java 应用程序运行。

【讨论】:

我需要配置 2 个不同的数据源。我通过更好地研究框架,特别是 Spring Boot 解决了我的问题。我为每个数据源配置使用了一个 Bean 类,并使用 application.properties (具有不同的前缀)注入配置。之后,我为我的应用程序中的每个 DAO 创建了一个 JDBCTemplate,并且一切正常。感谢您的帮助和建议。

以上是关于春季启动 jdbc 连接的主要内容,如果未能解决你的问题,请参考以下文章

春季启动中的postgresql错误

春季启动错误突然没有互联网连接

春季启动时出现Cors错误,将其与反应连接并尝试在tomcat或jboss服务器上部署?

IndexOutOfBoundsException 春季批处理和春季启动

数据库重新启动后尝试重新连接 jdbc 池数据源

Spark 到 JDBC:Py4JJavaError - 连接已启动,但没有一个提供者