Spring Boot – JDBC
今天,大多数应用程序都需要一个数据库,例如存储用户详细信息——进一步还用于身份验证、存储产品、订单信息等。在这种情况下,在使用Java应用程序时,我们使用JDBC API 。 JDBC(Java数据库连接)是一种标准 API(应用程序编程接口),使Java程序可以访问 DBMS(数据库管理系统)。
JDBC由两部分组成,如下表所示: Parts Description JDBC interfaces JDBC driversjava.sql / javax.sql packages has classes/interfaces of JDBC API. JDBC Driver allows java programs to interact with the database.
Spring Boot 提供了许多使用数据库的方法(例如 - JdbcTemplate),而无需 JDBC 所需的繁琐工作。您可以使用原始 JDBC 手动配置工作。
要使用 Spring-Boot 使用数据库,我们需要添加以下依赖项
A. JDBC API
数据库连接 API 指定客户端如何连接和查询数据库。
Maven - pom.xml
org.springframework.boot
spring-boot-starter-jdbc
B. MySQL 驱动程序
MySQL JDBC 和 R2DBC 驱动程序与数据库一起工作。
Maven - pom.xml
mysql
mysql-connector-java
runtime
执行:
A. pom.xml(配置)
XML
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.6.3
sia
GFG
0.0.1-SNAPSHOT
GFG
Demo project for Spring Boot
11
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
runtime
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-jdbc
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-security
org.springframework.security
spring-security-test
test
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
Java
// Java Program to Illustrate Boot of Spring Application
package gfg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// Annotation
@SpringBootApplication
// Application(Main) Class
public class GfgApplication {
// Main driver method
public static void main(String[] args)
{
SpringApplication.run(GfgApplication.class, args);
}
}
Java
// Java Program Illustrating Configuration of
// DataSourceConfiguration of DataSource
package gfg;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// Annotation
@Configuration
// Class
public class ConfigDataSource {
@Bean public static DataSource source()
{
DataSourceBuilder> dSB
= DataSourceBuilder.create();
dSB.driverClassName("com.mysql.jdbc.Driver");
// MySQL specific url with database name
dSB.url("jdbc:mysql://localhost:3306/userdetails");
// MySQL username credential
dSB.username("user");
// MySQL password credential
dSB.password("password");
return dSB.build();
}
}
Java
// Java Program Illustrating User Credentials to
// be Stored in the Database
package geek.details;
import lombok.Data;
// Annotation for Getter/Setter methods
@Data
public class UserDetails {
String user;
String userName;
String password;
}
Java
// Java Program Illustrating Utility class for Connecting
// and Querying the Database
package gfg;
import geek.details.UserDetails;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
// Annotation to provide logging feature
@Slf4j
// Class
public class JDBC {
public int insert(UserDetails user)
{
DataSource dataSource = null;
Connection connection = null;
PreparedStatement prepStatement = null;
int result = 0;
try {
// Get the configured datasourse
dataSource = ConfigDataSource.source();
// Attempt for connection to MySQL
connection = dataSource.getConnection();
prepStatement = connection.prepareStatement(
"insert into user (user,username,password) values (?,?,?)");
prepStatement.setString(1, user.getUser());
prepStatement.setString(2, user.getUserName());
BCryptPasswordEncoder bCryptPasswordEncoder
= new BCryptPasswordEncoder(
10, new SecureRandom());
String encodedPassword
= bCryptPasswordEncoder.encode(
user.getPassword());
prepStatement.setString(3, encodedPassword);
result = prepStatement.executeUpdate();
}
catch (SQLException e) {
log.getName();
}
return result;
}
}
Java
// Java Program to Illustrate Controller of Spring Application
package gfg;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import geek.details.UserDetails;
@Controller
@RequestMapping("/jdbc")
public class JdbcController {
@GetMapping
public String get(Model model) {
// Add object to be bound by user provided details
model.addAttribute("obj", new UserDetails());
return "template";
}
@PostMapping
public String post(@ModelAttribute("obj") UserDetails user, Model model) {
JDBC SQL = new JDBC();
int result = SQL.insert(user);
if(result == 1)
model.addAttribute("message", "Successful JDBC connection and execution of SQL statement");
else
model.addAttribute("message", "Query not submitted!");
return "Status";
}
}
HTML
GFG
Register Geek
HTML
GFG
STATUS
message will print here
B. Spring应用程序的启动(Java)
Java
// Java Program to Illustrate Boot of Spring Application
package gfg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// Annotation
@SpringBootApplication
// Application(Main) Class
public class GfgApplication {
// Main driver method
public static void main(String[] args)
{
SpringApplication.run(GfgApplication.class, args);
}
}
C. DataSource的配置(Java)
DataSourceBuilder
- org.springframework.boot.jdbc.DataSourceBuilder
- public final class DataSourceBuilder extends Object
DataSourceBuilder 类的方法
Method | Description |
---|---|
create() | Creates a new instance of DataSourceBuilder. |
driverClassName(String driverClassName) | Specifies the driver class name which is to be used for building the datasource. |
url(String url) | Specifies the URL which is to be used for building the datasource. |
username(String username) | Specifies the username which is to be used for building the datasource. |
password(String password) | Specifies the password which is to be used for building the datasource. |
build() | Returns a newly built DataSource instance. |
此构建器支持以下池化数据源实现。 Name Description Hikari Tomcat JDBC Pool Apache DBCP2 Oracle UCPcom.zaxxer.hikari.HikariDataSource org.apache.tomcat.jdbc.pool.DataSource org.apache.commons.dbcp2.BasicDataSource oracle.ucp.jdbc.PoolDataSourceImpl
Note: The first available pool implementation is used when no type has been explicitly set.
例子:
Java
// Java Program Illustrating Configuration of
// DataSourceConfiguration of DataSource
package gfg;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// Annotation
@Configuration
// Class
public class ConfigDataSource {
@Bean public static DataSource source()
{
DataSourceBuilder> dSB
= DataSourceBuilder.create();
dSB.driverClassName("com.mysql.jdbc.Driver");
// MySQL specific url with database name
dSB.url("jdbc:mysql://localhost:3306/userdetails");
// MySQL username credential
dSB.username("user");
// MySQL password credential
dSB.password("password");
return dSB.build();
}
}
Note : Driver class name – ‘com.mysql.jdbc.Driver’ has been deprecated. It would not give error because the driver is automatically loaded and manual loading is not necessary. The new driver class name is ‘com.mysql.cj.jdbc.Driver‘.
D.要存储在数据库中的用户凭据(Java)
One can add the ‘Lombok’ library to skip Getter/Setter methods, construct No-Arguments constructor, the constructor for final fields, etc.
Maven – pom.xml
org.projectlombok
lombok
true
例子:
Java
// Java Program Illustrating User Credentials to
// be Stored in the Database
package geek.details;
import lombok.Data;
// Annotation for Getter/Setter methods
@Data
public class UserDetails {
String user;
String userName;
String password;
}
E.连接和查询数据库的实用程序类(Java)
出于许多安全原因,密码编码是必须的。要使用 Spring Security,请添加以下依赖项:
Maven – pom.xml
org.springframework.boot
spring-boot-starter-security
org.springframework.security
spring-security-test
test
先决条件如下:
- 添加上述依赖项后,默认情况下会激活登录页面。
- 默认用户名是 - 'user'
- 密码由 Spring Security 自动生成,并在启动应用程序后显示在控制台上。
Note: Generated password becomes invalid for the next iteration/Running the application as the new password gets generated but the username remains same.
- 对于编码,Spring 提供了许多方法,例如“BCryptPasswordEncoder”。
- 它是使用 BCrypt 强哈希算法的 PasswordEncoder 的实现。
- 可以修改版本、强度和 SecureRandom 实例。
- org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
- public class BCryptPasswordEncoder extends java.lang.Object implements PasswordEncoder
BCryptPasswordEncoder 类的构造函数
Constructor | Description |
---|---|
BCryptPasswordEncoder( ) | Default constructor. |
BCryptPasswordEncoder( int strength ) | Strength is the log rounds to use between 4 to 31. Default is 10. |
BCryptPasswordEncoder( int strength, SecureRandom random ) | The secure random instance to be used. |
BCryptPasswordEncoder( BCryptVersion version ) | Version of BCrypt – 2a, 2b, 2y. |
BCryptPasswordEncoder( BCryptVersion version, int strength ) | Bcrypt versions / log rounds. |
BCryptPasswordEncoder( BCryptVersion version, int strength, SecureRandom random ) | Bcrypt versions / log rounds / Secure Random instance. |
BCryptPasswordEncoder( BCryptVersion version, SecureRandom random ) | Bcrypt versions / Secure Random instance. |
BCryptPasswordEncoder 类的方法
Method | Description |
---|---|
encode(CharSequence rawPassword) | Encodes a raw password provided with SHA-1 or greater hash combined with 8-Byte or greater randomly generated salt value. |
matches(CharSequence rawPassword, String encodedPassword) | Verifies the stored encoded password matches the submitted encoded raw password. Returns true if matched otherwise false. |
upgradeEncoding(String encodedPassword) | Returns true if the encoded password should be encoded again for better security, else false. The default implementation always returns false. |
例子:
Java
// Java Program Illustrating Utility class for Connecting
// and Querying the Database
package gfg;
import geek.details.UserDetails;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
// Annotation to provide logging feature
@Slf4j
// Class
public class JDBC {
public int insert(UserDetails user)
{
DataSource dataSource = null;
Connection connection = null;
PreparedStatement prepStatement = null;
int result = 0;
try {
// Get the configured datasourse
dataSource = ConfigDataSource.source();
// Attempt for connection to MySQL
connection = dataSource.getConnection();
prepStatement = connection.prepareStatement(
"insert into user (user,username,password) values (?,?,?)");
prepStatement.setString(1, user.getUser());
prepStatement.setString(2, user.getUserName());
BCryptPasswordEncoder bCryptPasswordEncoder
= new BCryptPasswordEncoder(
10, new SecureRandom());
String encodedPassword
= bCryptPasswordEncoder.encode(
user.getPassword());
prepStatement.setString(3, encodedPassword);
result = prepStatement.executeUpdate();
}
catch (SQLException e) {
log.getName();
}
return result;
}
}
F. Spring Application的控制器(Java)
Java
// Java Program to Illustrate Controller of Spring Application
package gfg;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import geek.details.UserDetails;
@Controller
@RequestMapping("/jdbc")
public class JdbcController {
@GetMapping
public String get(Model model) {
// Add object to be bound by user provided details
model.addAttribute("obj", new UserDetails());
return "template";
}
@PostMapping
public String post(@ModelAttribute("obj") UserDetails user, Model model) {
JDBC SQL = new JDBC();
int result = SQL.insert(user);
if(result == 1)
model.addAttribute("message", "Successful JDBC connection and execution of SQL statement");
else
model.addAttribute("message", "Query not submitted!");
return "Status";
}
}
模板(百里香叶)
A.template.html :获取用户数据并绑定到UserDetails对象
HTML
GFG
Register Geek
输出:
B. Status.html
显示 JDBC 操作的消息
HTML
GFG
STATUS
message will print here
输出:
C. MySQL 数据库
输出:
Note: Spring-Boot offers many convenient ways of working with data, e.g Spring Data JPA – which has default implementation of Hibernate. We can use them to make advantage of Java Persistence API (JPA) for object/relational mapping and to avoid cumbersome efforts.