【发布时间】:2022-01-07 22:12:31
【问题描述】:
在开始一个新项目时,我被阻止了,因为我无法通过 Spring 和 myBatis 访问数据库。我不明白为什么。
- 我已经设置了我的 application.properties(通过从我的另一个 项目)。
- 我已经通过 java-class 设置了 MyBatis-@Configuration (DefaultDataAccessConfig.java)
- 我已经通过 xml 文件设置了我的 Spring 上下文(也几乎与 之前)。
- 我的 MainClass 设置也和以前一样。
通过 MainClass 访问时出现错误。
当通过我的 JUnit5-Test 访问时我很好。
所有 spring 设置工作正常,类被实例化并且可以访问。但是在存储数据时,程序失败了,因为缺少 dataSource 和缺少 dataSourceClassName 和缺少 jdbcUrl(我调试了它,也不存在)。我的测试调用了通过 MainClass 调用时失败的相同方法。 我不知道为什么 myBatis 在 MainClass 启动期间没有正确设置。
我盯着配置看,不知道出了什么问题。 看起来是这样的:
application.properties
server.port = 8192
logging.level.root=WARN
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.jdbcUrl=jdbc:mysql://DESKTOP-IOL7CPB.fritz.box:3306/smarthome?useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=*******
spring.datasource.password=*******
spring.datasource.maximum-pool-size=30
# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=60000
# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=50
# Validate the connection before borrowing it from the pool.
spring.datasource.tomcat.test-on-borrow=true
DefaultDataAccessConfig.java
package de.gombers.smarthome.fritzbox.mybatis.configuration;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandler;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
@MapperScan({
"de.gombers.smarthome.fritzbox.mybatis"})
public class DefaultDataAccessConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(@Autowired @Qualifier("myDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactory.setDataSource(dataSource);
Resource[] resources = resolver.getResources("classpath*:mybatis/*-mapper.xml");
sessionFactory.setMapperLocations(resources);
@SuppressWarnings("rawtypes")
TypeHandler[] typeHandlers = { new CustomDateTypeHandler() };
sessionFactory.setTypeHandlers(typeHandlers);
return sessionFactory.getObject();
}
@Bean
@ConfigurationProperties("spring.datasource")
public HikariDataSource myDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean
public SqlSession sqlSession(@Autowired SqlSessionFactory sqlSessionFactory) {
return sqlSessionFactory.openSession();
}
}
/context/smartHome.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- enable autowire -->
<context:component-scan
base-package="de.gombers.smarthome" />
</beans>
主类
@Service
public class GatherStatisticsMain {
private static final Logger LOGGER = LoggerFactory.getLogger(GatherStatisticsMain.class);
private final static String contextxml="/context/smartHome.xml";
@Autowired
private HomeAutomation homeAutomation;
@Autowired
private StoreDevices storeDevices;
public GatherStatisticsMain() {
}
public void process() throws InterruptedException {
final DeviceList devices = homeAutomation.getDeviceListInfos();
storeDevices.process(devices);
}
public static void main(String[] args) throws InterruptedException {
ApplicationContext context = new ClassPathXmlApplicationContext(contextxml);
LOGGER.info("------------" + context.getBeanDefinitionCount());
GatherStatisticsMain main = (GatherStatisticsMain) context.getBean(GatherStatisticsMain.class);
main.process();
}
JUnit5-测试
@SpringBootTest
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:context/smartHome.xml")
@EnableAutoConfiguration
public class DevicesDAOTest {
private static final Logger LOGGER = LoggerFactory.getLogger(Tools.getSimpleClassName());
@Autowired
private DevicesDAO devicesDAO;
@Autowired
private DeviceBuilder devicesBuilder;
@Test
@DisplayName("Add new device")
public void addDeviceTest() throws DatatypeConfigurationException {
DeviceType device = devicesBuilder
.init()
.setIdentifier("Identifier")
.setManufacturer("Manufact")
.setName("Name")
.setProductname("ProductName")
.build();
try {
Optional<DeviceType> oDevice = devicesDAO.getDeviceByIdentifier(device.getIdentifier());
devicesDAO.deleteDeviceByIdentifier(device.getIdentifier());
} catch (Exception e) {
LOGGER.info("No previous occurence of device '{}' to be deleted", device.getIdentifier());
}
devicesDAO.insertDevice(device);
Long count = devicesDAO.getTotalRows();
Long result = 1L;
assertEquals("Size ok", result, count);
}
}
我看到的错误是:
10:06:57.159 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
10:06:57.159 [main] DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7bebcd65] was not registered for synchronization because synchronization is not active
10:06:57.163 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
10:06:57.164 [main] ERROR com.zaxxer.hikari.HikariConfig - HikariPool-1 - dataSource or dataSourceClassName or jdbcUrl is required.
10:06:57.164 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7bebcd65]
Exception in thread "main" org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
### The error may exist in file [E:\$SysProg\GIT\SmallTools\SmartHome\target\classes\mybatis\Devices-mapper.xml]
### The error may involve de.gombers.smarthome.fritzbox.mybatis.objects.DevicesMapper.getDeviceByIdentifier
### The error occurred while executing a query
### Cause: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:79)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:447)
at com.sun.proxy.$Proxy21.selectOne(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:167)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:82)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
at com.sun.proxy.$Proxy22.getDeviceByIdentifier(Unknown Source)
at de.gombers.smarthome.fritzbox.mybatis.objects.DevicesDAO.getDeviceByIdentifier(DevicesDAO.java:35)
at de.gombers.smarthome.fritzbox.mybatis.serializer.StoreDevices.isAlreadyPersisted(StoreDevices.java:56)
at de.gombers.smarthome.fritzbox.mybatis.serializer.StoreDevices.storeDevice(StoreDevices.java:44)
at de.gombers.smarthome.fritzbox.mybatis.serializer.StoreDevices.process(StoreDevices.java:39)
at de.gombers.smarthome.fritzbox.main.GatherStatisticsMain.process(GatherStatisticsMain.java:62)
at de.gombers.smarthome.fritzbox.main.GatherStatisticsMain.main(GatherStatisticsMain.java:78)
【问题讨论】:
-
您正在使用 Spring Boot 但不是...放弃您的数据源 bean 定义,将您的
new ClassPathXmlApplicationContext更改为SpringBootApplication.run(GatherStatisticsMain, args);并重新启动。
标签: spring datasource mybatis hikaricp