gpt4 book ai didi

java - 使用 Spring Boot JdbcTemplate 获取 java.lang.NullPointerException

转载 作者:行者123 更新时间:2023-11-30 02:57:40 28 4
gpt4 key购买 nike

一般信息: Spring Boot 新手,想要通过单元测试测试我的 JDBC 连接。我创建了一个简单的类来连接到我的数据库,并创建了一个简单的测试类来跟进正确的测试用例。

问题:执行jdbcTemplate.getDataSource().getConnection();时连续收到java.lang.NullPointerException;我很难理解为什么。我尝试使用不同的数据库,并确保可以与常规 JDBC 建立连接。我已经提到了 Stack Overflow 上的许多其他问题,但过去两天我仍然停留在这个问题上,没有任何进展。我什至尝试使用不同类型的数据源库,但它们都产生相同的结果。

问题:我该如何解决这个问题?如果有人也能解释为什么会出现这个问题,以及为什么我们需要在企业级使用 Spring JDBC,那就太好了。

<小时/>

我的代码:

DatabaseTableService.java

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.vertica.jdbc.DataSource;

@RestController
@RequestMapping("/databaseServices")
public class DatabaseTableService {

private JdbcTemplate jdbcTemplate;
private DataSource dataSource;


public void setDataSource(DataSource dataSource) {
this.dataSource= dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}


@RequestMapping("/testConnection")
@ResponseBody
public boolean canConnectToDB() {
boolean result;
try {
jdbcTemplate.getDataSource().getConnection();
result = true;
} catch (Exception e) {
e.printStackTrace();
result = false;
}
return result;
}

}

<小时/>

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.company.project"></context:component-scan>

<mvc:annotation-driven/>

<bean id="dataSource"
class="com.vertica.jdbc.DataSource">
<property name="URL" value="DBURLHERE"/>
<property name="userID" value="USERIDHERE"/>
<property name="password" value="PASSWORDHERE"/>
</bean>






<bean id="databaseTableService"
class="com.company.project.services.DatabaseTableService">
<property name="dataSource" ref="dataSource"></property>
</bean>


<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

</beans>
<小时/>

DatabaseTableServiceTest.java

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.vertica.jdbc.DataSource;


@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ApplicationController.class)
@WebAppConfiguration
public class DatabaseTableServiceTest {

@Autowired
private WebApplicationContext webApplicationContext;

private JdbcTemplate jdbcTemplate;
private MockMvc mockMvc;
DatabaseTableService databaseTableServiceObject;
DataSource testDataSource = new DataSource();

@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.build();

databaseTableServiceObject = new DatabaseTableService();
}




@Test
public void setDataSource() throws Exception {
databaseTableServiceObject.setDataSource(testDataSource);
}

@Test
public void validateCanConnectToDB() throws Exception {
Assert.assertTrue(databaseTableServiceObject.canConnectToDB());
}


@After
public void tearDown() throws Exception {
mockMvc = null;
databaseTableServiceObject = null;
testDataSource = null;
}

}
<小时/>

ApplicationController.java

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;


@SpringBootApplication
@ImportResource({"beans.xml"})
@ComponentScan(basePackages = "com.company.project")
public class ApplicationController {

public static void main(String[] args) throws Exception {

SpringApplication.run(ApplicationController.class, args);
}
}
<小时/>

文件夹结构

Folder Structure

<小时/>

Spring应用程序上下文信息 Spring Application Context Information

最佳答案

您正在使用 Spring Boot,接下来请努力不要使用。从您的 ApplicationController 中删除您的 beans.xml@ImportResource (顺便说一句,它不是 Controller ,而是您的实际应用程序,因为您的服务是您的实际控制人)。另外假设您的 ApplicationController 位于同一个包中,您也可以删除 @ComponentScan

然后在您的application.properties中添加以下内容

spring.datasource.url=<your-url>
spring.datasource.username=<your-username>
spring.datasource.password=<your-password>
spring.datasource.type=com.vertica.jdbc.DataSource

spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp

Spring Boot 将为您创建一个 DataSource 和一个 JdbcTemplate,因此无需您自己创建。只需在类中添加 @Autowire JdbcTemplate 即可。

@RestController
@RequestMapping("/databaseServices")
public class DatabaseTableService {

private final JdbcTemplate jdbcTemplate;

@Autowired
public DatabaseTableService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate=jdbcTeplate;
}

@RequestMapping("/testConnection")
@ResponseBody
public boolean canConnectToDB() {
boolean result;
try {
jdbcTemplate.getDataSource().getConnection();
result = true;
} catch (Exception e) {
e.printStackTrace();
result = false;
}
return result;
}
}

现在你的测试,相当困惑。您正在使用 Spring 但自己做事情,所以不确定您想要在那里实现什么。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ApplicationController.class)
@WebAppConfiguration
public class DatabaseTableServiceTest {

@Autowired
private WebApplicationContext webApplicationContext;

private MockMvc mockMvc;
private DatabaseTableService databaseTableServiceObject;

@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.build();
}

@Test
public void setDataSource() throws Exception {
databaseTableServiceObject.setDataSource(testDataSource);
}

@Test
public void validateCanConnectToDB() throws Exception {
Assert.assertTrue(databaseTableServiceObject.canConnectToDB());
}

}

您只需@Autowired即可使用现已完全构建的服务。

最后一件事是您的 canConnectToDB 方法有缺陷。您正在获取连接,但永远不会返回/关闭它。因此,在调用此方法几次后,您的应用程序将停止工作,因为连接池将耗尽或您的数据库停止接受连接。

简而言之,与框架一起工作,而不是反对/围绕框架。阅读文档,而不是试图绕过它。

关于java - 使用 Spring Boot JdbcTemplate 获取 java.lang.NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36796368/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com