您的代码在多方面存在缺陷。
-
由于不理解注释并将其与XML混合,您的配置存在缺陷
-
你应该使用
DataSource
Connection
对象,并在使用后正确释放它们
-
控制器中不应该有SQL处理代码
-
您不应该在控制器中构造HTML
您已经定义了
DBQuery
使用接受参数的构造函数初始化,您已使用
@Autowired
这意味着Spring将尝试创建
<context:component-scan />
)并尝试找到一个类型的bean
String
在您的上下文中。那个豆子不在那里,所以它失败了。
此外,您还将得到多个
数据库查询
由于组件扫描和您有一个XML的事实。删除XML配置。此外,组件可以是
@Service
或
@Controller
但不是两者。和
@PropertySource
非
@Configuration
这个班什么都不做。
话虽如此,假设您主要希望首先使用注释,请删除
构造函数,只需创建
setStart
方法它更像是一个
@Repository
还有其他的。
@Repository
public class DBQuery {
@Autowired
private Environment env;
String dbUsername = env.getProperty("db.username");
String dbPassword = env.getProperty("db.password");
String dbUrl = env.getProperty("db.url");
String start;
public ResultSet getAllDataPassport() throws SQLException, ClassNotFoundException{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
Statement statement = conn.createStatement();
String sql = "select * from testing_table";
ResultSet rs = statement.executeQuery(sql);
return rs;
}
}
数据库查询
来自XML的bean以及
ViewAllData
<上下文:组件扫描/>
现在,不是使用
DriverManager
直接来说,您真的应该使用
数据来源
并将其注入到类中。
<context:property-placeholder location="WEB-INF/config.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
虽然
DriverManagerDataSource
是
数据来源
不要在生产中使用它。使用适当的连接池,如
HikariCP
那样的话这里的好处在于,您可以配置它,然后离开您的
数据库查询
照原样。
现在,不是注射
Environment
所有属性都简单地注入
数据来源
进入
数据库查询
对象
@Repository
public class DBQuery {
private final DataSource dataSource;
@Autowired
public DBQuery(DataSource dataSource) {
this.dataSource=dataSource;
}
public ResultSet getAllDataPassport() throws SQLException {
Connection conn = this.dataSource.getConnection();
Statement statement = conn.createStatement();
String sql = "select * from testing_table";
ResultSet rs = statement.executeQuery(sql);
return rs;
}
}
但是,此代码仍然有缺陷,因为您没有关闭
联系
和
ResultSet
(除非你在你的控制器中这样做,这会使它更加有缺陷)。你的
getAllDataPassport
应该会返回一个
List
属于
Passport
对象(或
DataPassport
). 因此,您需要将控制器的部分处理/转换移动到
数据库查询
.
为了使使用JDBC更容易,Spring提供了[
JdbcTemplate
]您可能希望使用它来编写代码,而不是
数据来源
因为这将为您管理资源关闭和异常处理。您可以很容易地使用
RowMapper
要将每行转换为
护照
对象
在xml中添加以下内容
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
把它注入你的
数据库查询
而不是
数据来源
.
@Repository
public class DBQuery {
private final JdbcTemplate jdbcTemplate;
@Autowired
public DBQuery(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<Passport> getAllDataPassport() {
String sql = "select * from testing_table";
return this.jdbcTemplate.query(sql, new PassportRowMapper());
}
}
上面的代码将执行查询,获取并关闭资源,并将行转换为
护照
对象当然,您需要编写
PassportRowMapper
要将每行转换为
护照
.
public class PassportRowMapper implements RowMapper<Passport> {
public Passport mapRow(ResultSet rs, int rowNum) throws SQLException {
Passport p = new Passport();
p.setNumber(rs.getString(1));
return p;
}
}
注:
不要这样做
rs.next
在
这个
使用
处理好了。您只需要将一行转换为
护照
.
现在,您的控制器不再需要进行转换,不再与SQL绑定。对于测试,您现在可以轻松地模拟
数据库查询
并对您的
ViewAllData
控制器。
@Controller
public class ViewAllData {
private final DBQuery dbQuery;
@Autowired
public ViewAllData(DBQuery dbQuery){
this.dbQuery = dbQuery;
}
@RequestMapping("/viewAllData")
public ModelAndView viewData() {
String dataTable;
List<Passport> passports = dbQuery.getAllDataPassports();
return new ModelAndView("viewAllData", "message", dataTable);
}
}
在您的控制器中,看起来您正在转换
List<Passport
变成
我担心它包含一个HTML表。你不应该做这样的事情,你应该从属于你的角度来看待这个逻辑。
@RequestMapping("/viewAllData")
public ModelAndView viewData() {
String dataTable;
List<Passport> passports = dbQuery.getAllDataPassports();
return new ModelAndView("viewAllData", "passports", passports);
}
<table>
<c:forEach items="${passports}" var="passport">
<tr><td>${passport.number}</td></tr>
</c:forEach>
</table>
现在,您已经解耦了视图、模型和控制器。现在,您甚至可以使用相同的控制器导出为PDF、Excel或JSON。而不改变它。
最后提示:使用
InternalResourceViewResolver
而不是平原
UrlBasedViewResolver
<bean id="viewResolver" class="org.springframework.web.servlet.view. InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>