今天学习使用Spring Boot框架的时候连接线上数据库,Accessing Relational Data using JDBC with Spring,如果按照这个tutorial可以在15分钟之内完成数据库的连接。然而这个连接的仅仅是本地的一个数据库,Spring Boot spots H2,是一个本地内存级的关系数据库。我们要连接的是线上已存在的mysql,该怎么做呢? 在网上也看到很多人遇到和我相同的问题,所以记录一下,希望对你有帮助。
spring Boot使用的jdbc连接数据库,所以首先,你需要添加如下依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
然后你需要配置你的数据库ip地址,端口号,用户名和密码。 找到application.properties文件,添加如下信息
//(其中端口如果不指定会使用mysql的默认端口号,示例: //127.0.0.1/studentInfo) 此行拷贝请去掉 spring.datasource.url=jdbc:mysql://ip地址/端口号/数据库名称 spring.datasource.username=name spring.datasource.password=password //这个可以不要,因为从url里,他可以知道需要哪个驱动,此行拷贝请去掉 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
然后在需要使用的DAO的实现里,注入JdbcTemplate就能放心的使用了,是不是很方便?
@Autowired private JdbcTemplate jdbcTemplate;
以上是spring.io官方网站给出的提示信息,你以为就这样简单就完成了吗?那么就没有这篇文章存在的价值了。 如果不出意外,你会碰到以下报错:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'docWhoDAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.jdbc.core.JdbcTemplate com.taobao.search.admin.DAO.impl.DocWhoDAOImpl.jdbcTemplate; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalStateException: Cannot load driver class: com.mysql.jdbc.Driver
如果你的application.properties里配置了spring.datasource.driver-class-name=com.mysql.jdbc.Driver这条信息,他会在启动阶段报错,否则他会在你刷新页面的时候出现,看信息应该是没有找到mysql的驱动。
有一种做法是添加在容器内,检查下你的tomcat里的lib里有没有mysql-connector-java.jar,你可以下载一个放进去,我没有测试。因为这样做的坏处是,你部署的时候,不能使用统一的tomcat包,需要自己放进去一个jar,所以我的做法是在pom中添加mysql的依赖。
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.27</version> </dependency>
到这里问题就解决了。 参考JdbcTemplate的API,我们试着使用query方法。这个类提供了很多方法非常方便,但是JavaAPI不像php文档,没有使用示例,看起来晦涩难懂。ps:看过php手册的人应该知道,每个方法都有示例,并且还有评论,评论里把遇到的坑都写出来了。而百度上千篇一律都是过过时的JdbcTemplate的API. 我试着使用queryForList的方法:
public class WirelessDetectorWhiteKist { String id ; String username; String age; } public boolean checkSalt(String name) { List<User> abc = jdbcTemplate.queryForList("select * from " + tableName + " where username= ? ", User.class, name); }
我的目的很明显,我需要查询的所有名字叫(小明)的用户信息。所以返回值是一个User对象的List。我把User.Class设置为第二个参数,name=“小明”作为第三个参数,以期望返回一个个的User对象。
这个时候会报错误:
Incorrect column count: expected 1, actual 3;
是因为对这个函数理解错误,我以为查询出来的会自动的转成User这种类型的。其实函数的本意是,只返回其中的一列(例如age),
所以改成如下:
List<String> ages = jdbcTemplate.queryForList("select age from " + tableName + " where username= ? ", String.class, id); }
如果要返回一列所有的信息怎么办呢?可以使用返回list<map>类型的:
List<Map<String, Object>> users = jdbcTemplate.queryForList("select * from " + tableName + " where id= ? ", id); }
这个时候没一行记录是List的一个元素,然后map中String代表了列名,而Object则是数据库里存储的值。
以上是我遇到的问题,希望对你有帮助。