java Spring Web App - 简单的 JDBC 模板建议?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4684102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Web App - Simple JDBC Template Advice?
提问by Chris
Quick question based on a spring web app i am creating.
基于我正在创建的 Spring Web 应用程序的快速问题。
How do you go about setting up the context of the application so that you do not need to set the datasource parameters for simpleJDBC all the time and can call getSimpleJDBCTemplate().queryfor.... and it be set up with the datasource.
你如何设置应用程序的上下文,这样你就不需要一直为 simpleJDBC 设置数据源参数,并且可以调用 getSimpleJDBCTemplate().queryfor.... 并与数据源一起设置。
This is how i currently have it and it seems to go against inversion of control that spring is meant to provide as this is in every dao!
这就是我目前拥有它的方式,它似乎违背了 spring 旨在提供的控制反转,因为这在每个 dao 中!
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml");
DataSource dataSource = (DataSource) ac.getBean("dataSource");
SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
ApplicationContext
应用上下文
<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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:properties.properties"/>
</bean>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
<bean name="SimpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg><ref bean="dataSource"/></constructor-arg>
</bean>
<context:annotation-config/>
</beans>
Latest Stack Trace from Tomcat log
来自 Tomcat 日志的最新堆栈跟踪
13-Jan-2011 20:15:18 com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
ptc.jersey.spring
13-Jan-2011 20:15:18 com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class ptc.jersey.spring.resources.LoginResource
13-Jan-2011 20:15:18 com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
13-Jan-2011 20:15:19 com.sun.jersey.spi.spring.container.servlet.SpringServlet getContext
INFO: Using default applicationContext
13-Jan-2011 20:15:19 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.4 09/11/2010 10:30 PM'
13-Jan-2011 20:15:21 com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NullPointerException
at ptc.jersey.spring.daoImpl.UserDaoImpl.getUser(UserDaoImpl.java:43)
web.xml
网页.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:ApplicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>Jersey Spring Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>ptc.jersey.spring</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Spring Web Application</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
</web-app>
Any help would be great Thanks Chris
任何帮助都会很棒谢谢克里斯
回答by Timo Westk?mper
Why don't you declare the SimpleJdbcTemplate instance as well in the application context file?
为什么不在应用程序上下文文件中声明 SimpleJdbcTemplate 实例?
For example with these bean declarations
例如使用这些 bean 声明
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.gjt.mm.mysql.Driver"/>
<property name="url" value="dburl"/>
<property name="username" value="dbusername"/>
<property name="password" value="password"/>
</bean>
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg><ref bean="dataSource"/></constructor-arg>
</bean>
And in your web.xml to load the application context
并在您的 web.xml 中加载应用程序上下文
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:ApplicationContext.xml</param-value>
</context-param>
回答by Axel Fontaine
Declare the SimpleJdbcTemplate bean in the context:
在上下文中声明 SimpleJdbcTemplate bean:
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
and use it like this:
并像这样使用它:
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml");
SimpleJdbcTemplate simpleJdbcTemplate = (SimpleJdbcTemplate) ac.getBean("jdbcTemplate");
or in a DAO:
或在 DAO 中:
@Autowired
private SimpleJdbcTemplate simpleJdbcTemplate;
It is thread-safe, and therefore reusable.
它是线程安全的,因此可以重用。
回答by Esko
What I'd recommend is that you declare your DataSource
as bean and alsothe classes which need it and use dependency injection to introduce the DataSource
to your class. As an example, your bean definition could look like this:
我建议你的是,你宣布你DataSource
为bean并还其需要和使用依赖注入引进的类DataSource
到类。例如,您的 bean 定义可能如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans">
<bean id="dataSource" class="...">
<!-- your dataSource config here -->
</bean>
<bean id="yourClassThatNeedsDataSource" class="com.stackoverflow.q4684102.Example">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
and the accompanying class
和伴随的班级
package com.stackoverflow.q4684102;
import javax.jdbc.DataSource;
import org.springframework.jdbc.core.simple.*;
public class Example implements YourDaoInterface {
private SimpleJdbcOperations jdbc;
public void setDataSource(DataSource ds) {
jdbc = new SimpleJdbcTemplate(ds);
}
// your DAO methods here
}
Why do it this way instead of creating a bean out of the SimpleJdbcTemplate itself?
为什么要这样做而不是从 SimpleJdbcTemplate 本身创建一个 bean?
No difference, really - some people like it the other way, some others like it this way - you wan't have a huge XML with loads of bean definitions for intermediate objects if you do it this way, that's for sure. That, of course, is up to you to decide on how you want to design your software.
没有区别,真的 - 有些人喜欢另一种方式,有些人喜欢这种方式 - 如果你这样做,你不会有一个巨大的 XML,其中包含大量用于中间对象的 bean 定义,这是肯定的。当然,这由您决定如何设计您的软件。
回答by Tapasvi
If you create SimpleJdbcTemplate inside setDataSource then you are creating a template per Dao instance. If you configure as a bean and inject into the Dao, then you can resuse the same template across the Daos - which is recommended, because its threadsafe.
如果您在 setDataSource 中创建 SimpleJdbcTemplate ,那么您正在为每个 Dao 实例创建一个模板。如果您配置为 bean 并注入到 Dao,那么您可以在 Daos 中重复使用相同的模板 - 这是推荐的,因为它是线程安全的。