springboot中通过mybatis访问数据,打成jar包后,就出现数据库url未空的异常。

问题是这样的,我刚接触springboot,做了一个springboot的工程,需要通过mybatis访问oracle数据库,数据库的连接信息写在application.properties文件的spring.datasource中。在eclipse上直接运行程序,数据库访问正常,但是打成jar包后,读数据出现异常:
    org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: The url cannot be null  就不能读取数据库。

    我解开jar包看,Application.properties也在classes路径下的。
    另外,application类中设置数据源是这么写的:
 @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
        System.out.println(dataSource.getUrl());
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean() throws Exception {

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource());
我把dataSource里面的url打印出来看,不管是在eclipse运行的时候,还是jar包运行的时候都是null,但eclipse运行时虽然是null,但功能正常。

    网上搜索了很多帖子没有能解决这个问题,请专家帮忙看看也。谢谢。

DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource()你这样直接new,里面的属性从配置文件读不到的,你可以在你的配置类中加一些创建dataSource必须要内容,例如url,使用 @Value("JNDI_DATASOURCE_NAME") private String jndiName的方式,把application.properties中的配置注入进来,然后在你new数据源是,把对应的值set进去

代码没看懂,你new一个dataSource,然后直接getUrl()这能获取到url才怪了啊。Url肯定要你自己先设置好的啊,不管是在配置文件里配置dataSource的时候,
还是你通过代码初始化dataSource的时候

把配置文件可以发出来

你可以这么玩,单独写个配置类,里面的东西不用管,你要在yml里配置会覆盖他
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidProperties {

private String url = "jdbc:mysql://127.0.0.1:3306/guns?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull";

private String username = "root";

private String password = "root";

private String driverClassName = "com.mysql.jdbc.Driver";

private Integer initialSize = 2;

private Integer minIdle = 1;

private Integer maxActive = 20;

private Integer maxWait = 60000;

private Integer timeBetweenEvictionRunsMillis = 60000;

private Integer minEvictableIdleTimeMillis = 300000;

private String validationQuery = "SELECT 'x'";

private Boolean testWhileIdle = true;

private Boolean testOnBorrow = false;

private Boolean testOnReturn = false;

private Boolean poolPreparedStatements = true;

private Integer maxPoolPreparedStatementPerConnectionSize = 20;

private String filters = "stat";

public void coinfig(DruidDataSource dataSource) {

    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);

    dataSource.setDriverClassName(driverClassName);
    dataSource.setInitialSize(initialSize);     //定义初始连接数
    dataSource.setMinIdle(minIdle);             //最小空闲
    dataSource.setMaxActive(maxActive);         //定义最大连接数
    dataSource.setMaxWait(maxWait);             //最长等待时间

    // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

    // 配置一个连接在池中最小生存的时间,单位是毫秒
    dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    dataSource.setValidationQuery(validationQuery);
    dataSource.setTestWhileIdle(testWhileIdle);
    dataSource.setTestOnBorrow(testOnBorrow);
    dataSource.setTestOnReturn(testOnReturn);

    // 打开PSCache,并且指定每个连接上PSCache的大小
    dataSource.setPoolPreparedStatements(poolPreparedStatements);
    dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);

    try {
        dataSource.setFilters(filters);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

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 String getDriverClassName() {
    return driverClassName;
}

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

public Integer getInitialSize() {
    return initialSize;
}

public void setInitialSize(Integer initialSize) {
    this.initialSize = initialSize;
}

public Integer getMinIdle() {
    return minIdle;
}

public void setMinIdle(Integer minIdle) {
    this.minIdle = minIdle;
}

public Integer getMaxActive() {
    return maxActive;
}

public void setMaxActive(Integer maxActive) {
    this.maxActive = maxActive;
}

public Integer getMaxWait() {
    return maxWait;
}

public void setMaxWait(Integer maxWait) {
    this.maxWait = maxWait;
}

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 String getValidationQuery() {
    return validationQuery;
}

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

public Boolean getTestWhileIdle() {
    return testWhileIdle;
}

public void setTestWhileIdle(Boolean testWhileIdle) {
    this.testWhileIdle = testWhileIdle;
}

public Boolean getTestOnBorrow() {
    return testOnBorrow;
}

public void setTestOnBorrow(Boolean testOnBorrow) {
    this.testOnBorrow = testOnBorrow;
}

public Boolean getTestOnReturn() {
    return testOnReturn;
}

public void setTestOnReturn(Boolean testOnReturn) {
    this.testOnReturn = testOnReturn;
}

public Boolean getPoolPreparedStatements() {
    return poolPreparedStatements;
}

public void setPoolPreparedStatements(Boolean poolPreparedStatements) {
    this.poolPreparedStatements = poolPreparedStatements;
}

public Integer getMaxPoolPreparedStatementPerConnectionSize() {
    return maxPoolPreparedStatementPerConnectionSize;
}

public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) {
    this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}

public String getFilters() {
    return filters;
}

public void setFilters(String filters) {
    this.filters = filters;
}

}

 @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
        System.out.println(dataSource.getUrl());
        return dataSource;
    }

你把这个注释掉试试,spring boot会自动配置dataSource.

然后在重新打包试试,另外你是用的maven打包的吗

把你的配置类发一发,你手否是用了配置注入了

你new的是Tomcat的,不是SpringBoot的。一般来说,在你继承了SpringBoot和mybatis的maven后,不需要手动注入数据源的。
下面是我用SpringBoot双数据源时,获取数据源的写法:

1.4.3的boot版本:

    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

2.0.0的boot版本:

 public DataSource primaryDataSource() {
        return primaryDataSourceProperties().initializeDataSourceBuilder().build();
                }
        ```