本文导读
- 《Spring Boot 数据库访问 简介》中已经介绍,Spring Boot 可以通过多种方式访问各种数据库,本文将介绍 Spring Boot 内部集成的 JDBC 类访问 Mysql 数据库
- 为了更加清晰明了,本文将新建项目进行说明。
环境准备
新建项目
pom. xml 默认内容
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>www.wmx.com.horse</groupId>
<artifactId>horse</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>horse</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 引入Spring封装的jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 引入html模板引擎Thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 因为web项目启动模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入mysql数据库连接驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 引入Spring Boot 测试模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Spring Boot 打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
mysql 数据库
- 此 Mysql 数据是 CentOS 7.2 中的 Docker 容器中,所以用了 CentOS 的 3307 端口映射了 Docker 容器的 3306 端口,CentOS 主机 ip 为 192.168.58.129
- 账号 root、密码 root
数据库 CRUD
全局配置文件
spring:
datasource:
username: root
password: root
url: jdbc:mysql://192.168.58.129:3307/horse?characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
- 配置的内容以及意义就如同以前在 Sping 核心配置文件 beans.xml 中配置时是一样的
- 到这里就已经可以操作数据库了,因为 Spring Boot 都已经自动配置好了,如 Spring Boot 默认已经提供了数据源
- 关于上面的数据源配置内容,都可以从 Spring Boot 官方文档 查看
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.continue-on-error=false # Whether to stop if an error occurs while initializing the database.
spring.datasource.data= # Data (DML) script resource references.
spring.datasource.data-username= # Username of the database to execute DML scripts (if different).
spring.datasource.data-password= # Password of the database to execute DML scripts (if different).
spring.datasource.dbcp2.*= # Commons DBCP2 specific settings
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
spring.datasource.generate-unique-name=false # Whether to generate a random datasource name.
spring.datasource.hikari.*= # Hikari specific settings
spring.datasource.initialization-mode=embedded # Initialize the datasource with available DDL and DML scripts.
spring.datasource.jmx-enabled=false # Whether to enable JMX support (if provided by the underlying pool).
spring.datasource.jndi-name= # JNDI location of the datasource. Class, url, username & password are ignored when set.
spring.datasource.name= # Name of the datasource. Default to "testdb" when using an embedded database.
spring.datasource.password= # Login password of the database.
spring.datasource.platform=all # Platform to use in the DDL or DML scripts (such as schema-${platform}.sql or data-${platform}.sql).
spring.datasource.schema= # Schema (DDL) script resource references.
spring.datasource.schema-username= # Username of the database to execute DDL scripts (if different).
spring.datasource.schema-password= # Password of the database to execute DDL scripts (if different).
spring.datasource.separator=; # Statement separator in SQL initialization scripts.
spring.datasource.sql-script-encoding= # SQL scripts encoding.
spring.datasource.tomcat.*= # Tomcat datasource specific settings
spring.datasource.type= # Fully qualified name of the connection pool implementation to use. By default, it is auto-detected from the classpath.
spring.datasource.url= # JDBC URL of the database.
spring.datasource.username= # Login username of the database.
spring.datasource.xa.data-source-class-name= # XA datasource fully qualified name.
spring.datasource.xa.properties= # Properties to pass to the XA data source.
- 也可以从 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties 数据源配置文件类中进行查看
默认数据源
package com.lct.www;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@RunWith(SpringRunner.class)
@SpringBootTest
public class HorseApplicationTests {
/**
* Spring Boot 默认已经配置好了数据源,程序员可以直接 DI 注入然后使用即可
*/
@Resource
DataSource dataSource;
@Test
public void contextLoads() throws SQLException {
System.out.println("数据源>>>>>>" + dataSource.getClass());
Connection connection = dataSource.getConnection();
System.out.println("连接>>>>>>>>>" + connection);
System.out.println("连接地址>>>>>" + connection.getMetaData().getURL());
connection.close();
}
}
- 运行之后控制台核心输出如下:
数据源>>>>>>class com.zaxxer.hikari.HikariDataSource
2018-08-19 09:31:31.689 INFO 8948 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2018-08-19 09:31:31.986 INFO 8948 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
连接>>>>>>>>>HikariProxyConnection@280862192 wrapping com.mysql.jdbc.JDBC4Connection@3ae0b770
连接地址>>>>>jdbc:mysql://192.168.58.129:3307/horse
2018-08-19 09:31:31.996 INFO 8948 --- [ Thread-2] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@dc7df28: startup date [Sun Aug 19 09:31:29 CST 2018]; root of context hierarchy
2018-08-19 09:31:31.998 INFO 8948 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2018-08-19 09:31:32.001 INFO 8948 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.Process finished with exit code 0
- 可以看出 Spring Boot 2.0.4 默认使用 com.zaxxer.hikari.HikariDataSource 数据源
- 而以前版本,如 Spring Boot 1.5 默认使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源;
- HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀
- HikariDataSource 的内容本文暂时不做延伸
- 有了数据库连接,显然就可以 CRUD 操作数据库了
CRUD 数据库
- 有了数据源(com.zaxxer.hikari.HikariDataSource),然后拿到l了数据库连接(java.sql.Connection),自然就可以使用连接和原生的 JDCB 语句来操作数据库
- 即使不使用第三方第数据库操作框架,如 MyBatis、Hibernate 、JDBC Utils 等,Spring 本身也对 原生的 JDBC 做了轻量级的封装,即 org.springframework.jdbc.core.JdbcTemplate。这原本是 Spring 的知识点!
- 数据库操作的所有 CRUD 方法都在 JdbcTemplate 中,有了 JdbcTemplate 就能更加轻松的操作数据库。
- Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,程序员只需自己注入即可使用
- JdbcTemplate 的自动配置原理是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration 类
PhoneController
- 为了尽可能符合实际开发,新建一个控制层,通过浏览器访问来进行 CRUD,但是不再进行细致的分层,如 dao、service、domain 等都省略
package com.lct.www.controller;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* Created by Administrator on 2018/8/19 0019.
*/
@Controller
public class PhoneController {
/**
* JdbcTemplate 是 core 包的核心类,用于简化 JDBC 操作,还能避免一些常见的错误,如忘记关闭数据库连接
* Spring Boot 默认提供了数据源,默认提供了 org.springframework.jdbc.core.JdbcTemplate
* JdbcTemplate 中会自己注入数据源,使用起来也不用再自己来关闭数据库连接
*/
@Resource
JdbcTemplate jdbcTemplate;
/**
* 查询 phone 表所有数据
*
* @return
*/
@ResponseBody
@GetMapping("phoneList")
public List<Map<String, Object>> userList() {
/**
* 查询 phone 表所有数据
* List 中的1个 Map 对应数据库的 1行数据
* Map 中的 key 对应数据库的字段名,value 对应数据库的字段值
*/
List<Map<String, Object>> mapList = jdbcTemplate.queryForList("SELECT * FROM phone");
return mapList;
}
/**
* 新增 phone 数据
*
* @return
*/
@GetMapping("savePhone")
public String savePhone() {
String sql = "INSERT INTO phone(number,region) VALUES (?,?)";
Object[] objects = new Object[2];
objects[0] = "18673886425";
objects[1] = "湖南";
jdbcTemplate.update(sql, objects);
return "forward:/phoneList";
}
/**
* 修改 phone 数据
*
* @return
*/
@GetMapping("updatePhone")
public String updatePhone() {
String sql = "UPDATE phone SET number=? WHERE pid=?";
Object[] objects = new Object[2];
objects[0] = "18666668888";
objects[1] = "1";
jdbcTemplate.update(sql, objects);
return "forward:/phoneList";
}
/**
* 删除 phone 数据
* update 方法可以做查询以外的 增加、修改、删除操作
*
* @return
*/
@GetMapping("deletePhone")
public String deletePhone() {
String sql = "DELETE FROM phone WHERE number=?";
Object[] objects = new Object[1];
objects[0] = "18673886425";
jdbcTemplate.update(sql, objects);
return "forward:/phoneList";
}
}
测试结果
- 查询:http://localhost:8080/phoneList
- 添加:http://localhost:8080/savePhone
- 修改:http://localhost:8080/updatePhone
- 删除:http://localhost:8080/deletePhone
- 启动应用成功
some templates or check your Thymeleaf configuration)
2018-08-19 12:15:23.522 INFO 14052 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-08-19 12:15:23.525 INFO 14052 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'dataSource' has been autodetected for JMX exposure
2018-08-19 12:15:23.532 INFO 14052 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2018-08-19 12:15:23.573 INFO 14052 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-08-19 12:15:23.577 INFO 14052 --- [ main] com.lct.www.HorseApplication : Started HorseApplication in 3.863 seconds (JVM running for 4.455)
自动配置原理
- 自动配置都在 org.springframework.boot.autoconfigure.jdbc 包下可以找到
DataSourceConfiguration
- org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration 数据源配置类作用是根据逻辑判断之后,添加数据源
- SpringBoot 默认支持如下数据源;
com.zaxxer.hikari.HikariDataSource (Spring Boot 2.0 以上,默认使用此数据源)
org.apache.tomcat.jdbc.pool.DataSource
org.apache.commons.dbcp2.BasicDataSource
- 可以使用 spring.datasource.type 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。默认情况下,它是从类路径自动检测的。
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
name = {"spring.datasource.type"}
)
static class Generic {
Generic() {
}
@Bean
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}