主要介绍在springboot基础下配置数据源和通过JdbcTemplate访问数据库。
1.引入依赖
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2.配置数据源
在配置文件application.properties文件中配置数据源信息。
2.1使用默认数据源
spring.datasource.url = jdbc:mysql://localhost:3306/db_study?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
可以不指定 driver-class-name,因为 spring boot 会自动识别 url。spring-boot-starter-jdbc 默认使用tomcat-jdbc数据源。
2.2其他数据源
如果你想使用其他的数据源,比如使用了阿里巴巴的数据池管理,你应该额外添加以下依赖.
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.19</version>
</dependency>
同时需要修改启动类,为其配置数据源。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired
private Environment env;
//destroy-method="close"的作用是当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用.
@Bean(destroyMethod = "close")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));//用户名
dataSource.setPassword(env.getProperty("spring.datasource.password"));//密码
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setInitialSize(2);//初始化时建立物理连接的个数
dataSource.setMaxActive(20);//最大连接池数量
dataSource.setMinIdle(0);//最小连接池数量
dataSource.setMaxWait(60000);//获取连接时最大等待时间,单位毫秒。
dataSource.setValidationQuery("SELECT 1");//用来检测连接是否有效的sql
dataSource.setTestOnBorrow(false);//申请连接时执行validationQuery检测连接是否有效
dataSource.setTestWhileIdle(true);//建议配置为true,不影响性能,并且保证安全性。
dataSource.setPoolPreparedStatements(false);//是否缓存preparedStatement,也就是PSCache
return dataSource;
}
}
这样就算自己配置了一个DataSource,Spring Boot会智能地选择我们自己配置的这个DataSource实例。
3.数据库脚本
# Host: localhost (Version 5.5.57)
# Date: 2019-01-16 14:56:03
# Generator: MySQL-Front 6.1 (Build 1.26)
#
# Structure for table "sys_user"
#
CREATE TABLE `sys_user` (
`id` varchar(36) NOT NULL COMMENT '主键',
`usercode` varchar(32) NOT NULL COMMENT '账号',
`username` varchar(64) NOT NULL COMMENT '姓名',
`password` varchar(32) NOT NULL COMMENT '密码',
`salt` varchar(64) DEFAULT NULL COMMENT '盐',
`locked` char(1) DEFAULT NULL COMMENT '账号是否锁定,1:锁定,0未锁定',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#
# Data for table "sys_user"
#
INSERT INTO `sys_user` VALUES ('lisi','lisi','李四','bf07fd8bbc73b6f70b8319f2ebb87483','uiwueylm','0'),('zhangsan','zhangsan','张三','e10adc3949ba59abbe56e057f20f883e','eteokues','0');
4.使用JdbcTemplate
Spring的JdbcTemplate是自动配置的,可以直接使用@Autowired
来注入到你自己的bean中来使用。
4.1目录结构
4.2实体对象
public class User {
private String id;
private String usercode;
private String username;
private String password;
private String salt;
private String locked;
//省略get、set方法和toString()方法
}
4.3Controller层
//注意,此处若使用其他模板,则可用Controller
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("")
public String userinfo(){
return "userinfo";
}
@RequestMapping("/list")
public String list(){
logger.info("-------------list start-------------");
List<User> list = userService.getAllUsers();
logger.info("-------------list end-------------");
return list.toString();
}
}
4.4Service层
接口
public interface UserService {
/** 新增一个用户 */
void create(User user);
/**根据name删除一个用户*/
void deleteByName(String name);
/**获取所有用户信息*/
List<User> getAllUsers();
/** 获取用户总量 */
Integer getAllUserCount();
/*** 删除所有用户*/
void deleteAllUsers();
}
实现类
@Service("userService")
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public List<User> getAllUsers(){
logger.info("-------------UserServiceImpl getAllUsers start-------------");
List<User> list = userDao.getAllUsers();
logger.info("-------------UserServiceImpl getAllUsers start-------------");
return list;
}
//其他方法省略
}
4.5Dao层(即持久层,JdbcTemplate在此处应用,需要在实现类中注入)
接口:与Service层接口可以一致。
实现类:
@Repository
public class UserDaoImpl implements UserDao{
@Autowired
private JdbcTemplate jdbcTemplate;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void create(User user) {
jdbcTemplate.update("insert into sys_USER(id, usercode,username,password,salt,locked) values(?, ?,?,?,?,?)",
user.getId(), user.getUsercode(),user.getUsername(),user.getPassword(),user.getSalt(),user.getLocked());
}
@Override
public void deleteByName(String name) {
jdbcTemplate.update("delete from sys_USER where username = ?", name);
}
@Override
public List<User> getAllUsers() {
logger.info("-------------UserDaoImpl getAllUsers start-------------");
List<Map<String,Object>> list = jdbcTemplate.queryForList("SELECT * FROM SYS_USER ");
List<User> userlist = new ArrayList<User>();
for (Map<String,Object> map : list){
User user = new User();
user.setId((String) map.get("id"));
user.setUsercode((String) map.get("usercode"));
user.setUsername((String) map.get("username"));
user.setPassword((String) map.get("password"));
user.setSalt((String) map.get("salt"));
user.setLocked((String) map.get("locked"));
userlist.add(user);
}
logger.info("-------------UserDaoImpl getAllUsers end-------------");
return userlist;
}
@Override
public Integer getAllUserCount() {
return jdbcTemplate.queryForObject("select count(1) from sys_USER", Integer.class);
}
@Override
public void deleteAllUsers() {
jdbcTemplate.update("delete from sys_USER");
}
在此实现类中注意queryForList其返回值的类型是List<Map<String,Object>>,其内部Map键表示列名,值表示列植。
更多数据访问的操作可以参考JdbcTemplate API。
4.5启动测试输出
浏览器访问输出
控制台输出:
4.6将数据源按前面的自定义后启动并访问项目
控制台输出如下
5.学习中的问题:
1.mysql连接驱动异常
异常错误:
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
分析:
application.properties配置文件中,mysql配置驱动信息为
##配置数据源
spring.datasource.url=jdbc:mysql://localhost:3306/db_study?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
需要将其修改为如下所示,注意driver-class-name的配置
##配置数据源
spring.datasource.url=jdbc:mysql://localhost:3306/db_study?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
修改完成后,再次启动项目,仍报错,错误信息为
java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
由提示可看到,问题点在于系统时间错误,修改配置url,增加参数serverTimezone=GMT%2B8
spring.datasource.url=jdbc:mysql://localhost:3306/db_study?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
2.jdbcTemplate调用queryForList方法异常
public List<User> getAllUsers(){
return jdbcTemplate.queryForList("SELECT * FROM SYS_USER ",User.class);
}
如上方法,访问时会报异常。
org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count: expected 1, actual 6
参考解决方案:https://www.cnblogs.com/AloneSword/p/4104146.html
或上面例子中的方法也可。
6.总结
springboot关于持久化或者说访问数据库的操作基本步骤为:
①添加所需的依赖
②在配置文件application.properties中添加链接信息。