27.集成JdbcTemplate

 

项目工程目录:

1.pom.xml

使用druid数据源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>14_springboot_jdbctemplate</artifactId>
<version>1.0</version>
<name>14_springboot_jdbctemplate</name>
<description>Spring Boot jdbcTemplate</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

2.application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 数据源配置信息
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo_filesystem
username: root
password: 123456
initial-size: 3
min-idle: 2
max-active: 10
max-wait: 15000

stat-view-servlet:
login-username: admin
login-password: 123456
# allow和deny可以为空
allow: 192.168.10.25,127.0.0.1,192.168.30.23,192.168.5.26
deny:
url-pattern: /druid/*
# 默认为false,不开启
enabled: true

3.entity

MyFile.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.example.demo.entity;

import java.util.Date;

public class MyFile {
private Integer fileId;

private String originalName;

private Date createtime;

private Integer size;

private String contentType;

private String path;

private Integer directoryId;

private String tag;

private String directoryName;

public Integer getFileId() {
return fileId;
}

public void setFileId(Integer fileId) {
this.fileId = fileId;
}

public String getOriginalName() {
return originalName;
}

public void setOriginalName(String originalName) {
this.originalName = originalName == null ? null : originalName.trim();
}

public Date getCreatetime() {
return createtime;
}

public void setCreatetime(Date createtime) {
this.createtime = createtime;
}

public Integer getSize() {
return size;
}

public void setSize(Integer size) {
this.size = size;
}

public String getContentType() {
return contentType;
}

public void setContentType(String contentType) {
this.contentType = contentType == null ? null : contentType.trim();
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path == null ? null : path.trim();
}

public Integer getDirectoryId() {
return directoryId;
}

public void setDirectoryId(Integer directoryId) {
this.directoryId = directoryId;
}

public String getTag() {
return tag;
}

public void setTag(String tag) {
this.tag = tag == null ? null : tag.trim();
}

public String getDirectoryName() {
return directoryName;
}

public void setDirectoryName(String directoryName) {
this.directoryName = directoryName;
}
}

MyDirectory.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.example.demo.entity;

public class MyDirectory {
private Integer directoryId;

private String directoryName;

private String remark;

private Integer userId;

public MyDirectory() {
super();
}

public MyDirectory(Integer directoryId, String directoryName, String remark, Integer userId) {
super();
this.directoryId = directoryId;
this.directoryName = directoryName;
this.remark = remark;
this.userId = userId;
}

public Integer getDirectoryId() {
return directoryId;
}

public void setDirectoryId(Integer directoryId) {
this.directoryId = directoryId;
}

public String getDirectoryName() {
return directoryName;
}

public void setDirectoryName(String directoryName) {
this.directoryName = directoryName == null ? null : directoryName.trim();
}

public String getRemark() {
return remark;
}

public void setRemark(String remark) {
this.remark = remark == null ? null : remark.trim();
}

public Integer getUserId() {
return userId;
}

public void setUserId(Integer userId) {
this.userId = userId;
}

@Override
public String toString() {
return "MyDirectory [directoryId=" + directoryId + ", directoryName=" + directoryName + ", remark=" + remark
+ ", userId=" + userId + "]";
}

}

4.测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.example.demo;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import com.example.demo.entity.MyDirectory;

@SpringBootTest
class ApplicationTests {

@Autowired
private JdbcTemplate jdbcTemplate;

@Test
void contextLoads() {
System.out.println("jdbcTemplate = " + jdbcTemplate);
String sql = "select count(*) from t_file";
Long count = jdbcTemplate.queryForObject(sql, Long.class);
System.out.println("count = " + count);
// jdbcTemplate = org.springframework.jdbc.core.JdbcTemplate@7c5d1d25
// count = 10
}

@Test
void getDirectoryById() {
String sql = "select * from t_directory where directory_id = ?";
Integer queryParamDirectoryId = 1;
MyDirectory myDirectoryObj = jdbcTemplate.queryForObject(sql, new RowMapper<MyDirectory>() {

@Override
public MyDirectory mapRow(ResultSet rs, int rowNum) throws SQLException {
Integer directoryId = rs.getInt("directory_id");
String directoryName = rs.getString("directory_name");
String remark = rs.getString("remark");
Integer userId = rs.getInt("user_id");
MyDirectory myDirectory = new MyDirectory(directoryId, directoryName, remark, userId);
return myDirectory;
}

}, queryParamDirectoryId);

System.out.println("myDirectoryObj = " + myDirectoryObj);
// myDirectoryObj = MyDirectory [directoryId=1, directoryName=home, remark=home目录, userId=1]

}

}

5.原理

class JdbcTemplateAutoConfiguration -> class jdbcTemplate

JdbcTemplateAutoConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package org.springframework.boot.autoconfigure.jdbc;

import javax.sql.DataSource;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

@AutoConfiguration(after = DataSourceAutoConfiguration.class)
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
// @ConditionalOnSingleCandidate(DataSource.class): 要求为单数据源
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(JdbcProperties.class)
// 导入JdbcTemplateConfiguration类
@Import({ DatabaseInitializationDependencyConfigurer.class, JdbcTemplateConfiguration.class,
NamedParameterJdbcTemplateConfiguration.class })
public class JdbcTemplateAutoConfiguration {

}

JdbcTemplateConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package org.springframework.boot.autoconfigure.jdbc;

import javax.sql.DataSource;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(JdbcOperations.class)
class JdbcTemplateConfiguration {

@Bean
// @Primary表示当存在多个JdbcTemplate的实例时,该选用该方法返回的JdbcTemplate实例
@Primary
JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
JdbcProperties.Template template = properties.getTemplate();
jdbcTemplate.setFetchSize(template.getFetchSize());
jdbcTemplate.setMaxRows(template.getMaxRows());
if (template.getQueryTimeout() != null) {
jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds());
}
return jdbcTemplate;
}

}