Article directory
1. JDBC Overview
1.JDBC
Concept: Full name Java DataBase Connectivity
, that is, Java database connection is a set of APIs that use Java to operate relational databases.
Driver: SUN has specified a set of standard interfaces (JDBC). JDBC defines all the rules for operating relational databases, and the implementation classes of the interfaces are given by the respective database vendors. This set of implementation classes is called a driver. If you want to use the same set of Java code to operate different relational databases, you only need to load the driver corresponding to the database manufacturer.
2.The essence of JDBC:
- An officially defined set of rules for operating all relational databases, that is, the interface
- Various database vendors implement this set of interfaces and provide database driver jar packages.
- You can use this set of interfaces (JDBC) for programming. The actual code executed is the implementation class in the driver jar package.
3. Java database operation process:
- Write Java code
- Java code sends SQL to MySQL server
- The MySQL server receives the SQL statement and executes the SQL statement
- Return the results of SQL statement execution to Java code
2. JDBC Quick Start
2.1 Download the driver jar package
1. First check the MySQL version installed locally. My MySQL version here is8.0.32
mysql -V
2. According to your local MySQL version, go to the MySQL official website to download the corresponding version of the compressed packagezip
MySQL official website download address:https://dev.mysql.com/downloads/connector/j/
ClickArchives
to enter the historical version
After selecting the version and operating system, click Download
to download the zip package
- Version: Select the locally installed database version, here is
8.0.32
- Operating System: Select
Platform Independent
, independent of platform
3. After unzipping the zip
package, take out the jar
package inside. You will get after unzipping it here.mysql-connector-j-8.0.32.jar
2.2 Data preparation
Prepare a tableaccount
and insert two pieces of data as follows:
-- 删除账户表
drop table if exists account;
-- 创建账户表
create table account
(
id int primary key AUTO_INCREMENT comment 'ID',
name varchar(10) comment '姓名',
money double(10, 2) comment '余额'
) comment '账户表';
-- 向账户表插入数据
insert into account(name, money) VALUES ('张三', 2000), ('李四', 2000);
-- 查询账户表
select * from account;
2.3 Create project
1. Create a new project, define the name of the project, and specify the location.
2. The generated project structure is as follows. First delete the src
folderMain.java
, and then create a new directory under the project, usually named < /span> packages. lib
, used to store jar
Drag the downloaded mysql-connector-j-8.0.32.jar
to the lib
directory. The final project structure is as follows:
3. Right-click the lib
directory, click Add as Library
, and add the jar
package as a library file
When adding as a library file, there are three options:
- Global Library: Valid globally
- Project Library: The project is valid
- Module Library: The module is valid
4. Create a new file in the src
folder and name it herejava
JDBCDemo
2.4 Writing code
Writing code is divided into the following seven steps:
- Register driver
- Get connection
- Define SQL statement
- Get execution SQL object
- Execute SQL
- Process the returned results
- Release resources
Copy the following code into JDBCDemo.java
and run:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima"; // 数据库URL
String username = "root"; // 用户名
String password = "123456"; // 密码
Connection conn = DriverManager.getConnection(url, username, password);
// 3.定义sql
String sql = "update account set money = 3000 where id = 1";
// 4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
// 5.执行sql
int count = stmt.executeUpdate(sql); // 受影响的行数
// 6.处理结果
System.out.println(count);
// 7.释放资源
stmt.close();
conn.close();
}
}
After the operation is completed, query the account
table and find that Zhang San’s balance becomes 3000
, indicating that the JDBC
operation was successful. Here:
3. Detailed explanation of JDBC API
3.1 DriverManager
The role of DriverManager (driver management class):
- Register driver
- Get database connection
1. Register driver: The registerDriver(Driver driver)
method is used to register the driver
The Driver class provided by MySQL implements the source code for registering the driver as follows:
The DriverManager
object's registerDriver()
method has been executed in the static code block in this class to register the driver, then we only need to load < /span> class. method can load the Driver
class, the static code block will be executed. The Class.forName()
Driver
Class.forName("com.mysql.jdbc.Driver"); // 注册驱动
Note: For driver packages after MySQL 5, you can omit the step of registering the driver, and the driver class in the META-INF/services/java.sql.Driver file in the jar package will be automatically loaded.
2. Obtain database connection:getConnection()
Method
getConnection(String url, String user, String password);
Parameter Description:
- url: database connection path
- grammar:
jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…
- Example:
jdbc:mysql://127.0.0.1:3306/itheima
- grammar:
- user: username
- poassword: password
Note:
1. If you are connecting to the local mysql server and the default port of the mysql service is 3306, the url can be abbreviated as: jdbc:mysql:///database name ?Parameter key-value pair
2. Configure the useSSL=false parameter in the url and disable the secure connection method to solve the warning prompt
3.2 Connection
The role of Connection (database connection object):
- Get the object that executes SQL
- management affairs
3.2.1 Obtain execution SQL object
1. Ordinary execution of SQL objects
Statement createStatement()
2. Precompile SQL execution SQL object: prevent SQL injection
PreparedStatement prepareStatement(sql)
3. Object that executes stored procedures
CallableStatement prepareCall(sql)
3.2.2 Management matters
Operation commands for MySQL transaction management:
- Open transaction:
BEGIN
orSTART TRANSACTION
- Commit transaction:
COMMIT
- Rollback transaction:
ROLLBACK
Note: MySQL automatically commits transactions by default
Three corresponding methods are defined in the Connection interface:
1. Open the transaction: setAutoCommit(boolean autoCommit)
The parameter autoCommit
indicates whether to automatically submit the transaction, true indicates automatic submission of the transaction, and false indicates manual submission of the transaction. To start a transaction, you need to set this parameter to false.
2. Submit the transaction:commit()
3. Rollback transaction:rollback()
The code is implemented as follows:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
//3. 定义sql
String sql1 = "update account set money = 3000 where id = 1";
String sql2 = "update account set money = 3000 where id = 2";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
try {
// ============开启事务==========
conn.setAutoCommit(false);
//5. 执行sql
int count1 = stmt.executeUpdate(sql1);//受影响的行数
//6. 处理结果
System.out.println(count1);
int i = 3/0; // 构造程序异常,如需正常运行,注释该行即可
//5. 执行sql
int count2 = stmt.executeUpdate(sql2);//受影响的行数
//6. 处理结果
System.out.println(count2);
// ============提交事务==========
//程序运行到此处,说明没有出现任何问题,则需提交事务
conn.commit();
} catch (Exception e) {
// ============回滚事务==========
//程序在出现异常时会执行到这个地方,此时就需要回滚事务
conn.rollback();
e.printStackTrace();
}
//7. 释放资源
stmt.close();
conn.close();
}
}
3.3 Statement
The purpose of the Statement object is to execute SQL statements. Different types of SQL statements use different methods.
Methods are classified as follows:
executeUpdate(String sql)
: Execute DDL and DML statements and return the number of affected rows or no content.executeQuery(String sql)
: Execute DQL statement and return a single ResultSet object.
Note: The DQL statement involves the
ResultSet
object, which will be discussed in the3.4
section
3.3.1 Execute DML statements
Execute DML statement: UseexecuteUpdate(String sql)
method to execute DML statement and return the number of affected rows
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 1.注册驱动,mysql8的驱动会自动加载注册,此行可以注释掉
// Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 3.定义sql
String sql = "update account set money = 3000 where id = 1";
// 4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
// 5.执行sql
int count = stmt.executeUpdate(sql); // 执行完DML语句,受影响的行数
// 6.处理结果
if(count > 0){
System.out.println("修改成功~");
}else{
System.out.println("修改失败~");
}
//7. 释放资源
stmt.close();
conn.close();
}
}
3.3.2 Execute DDL statements
Execute DDL statement: UseexecuteUpdate(String sql)
method to execute DDL statement without returning content
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 1.注册驱动,mysql8的驱动会自动加载注册,此行可以注释掉
// Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 3.定义sql
String sql = "alter table account add remark varchar(20)"; // 添加字段remark
// 4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
// 5.执行sql
int count = stmt.executeUpdate(sql); // 执行完DDL语句,可能是0
// 6.处理结果
System.out.println(count);
//7. 释放资源
stmt.close();
conn.close();
}
}
3.4 ResultSet
The role of ResultSet (result set object): encapsulates the results of SQL query statements, ResultSet executeQuery(sql)
executes DQL statements and returns ResultSet objects.
3.4.1 ResultSet object methods
ResultSet
The object provides methods for manipulating query result data:
1.boolean next()
:
- Move the cursor forward one line from the current position
- Determine whether the current line is a valid line
- Returning true indicates that the row is valid, that is, the current row has data
- Returning false indicates that the row is invalid, that is, there is no data in the current row
2.xxx getXxx(参数)
: Get the data of this field, such as String getString(String columnLabel)
, String getString(int columnIndex)
xxx
: represents the data type参数
:- Parameter of type int: column number, starting from 1
- Parameters of type String: name of column
Note: Please note here that the column numbers start from
1
, not0
Example: Initially, the cursor is designated in front of the first row, that is, pointing to the header row. After the next()
method is called, the cursor moves down to the first row of data, and The method returns true.
At this time, you can get the value of the id field of the current row through getInt("id")
, or you can get the value of the name field of the current row through getString("name")
.
If you want to get the data of the next row, you need to continue calling the next()
method, and so on.
3.4.2 Execute DQL statement
Execute DQL statement: UseexecuteQuery(String sql)
method to execute DQL statement and return the result set
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 1.注册驱动,mysql8的驱动会自动加载注册,此行可以注释掉
// Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 3.定义sql
String sql = "select * from account";
// 4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
// 5.执行sql
ResultSet rs = stmt.executeQuery(sql);
// 6.处理结果,遍历rs中的所有数据
// 光标向下移动一行,并且判断当前行是否有数据
while (rs.next()){
// 获取数据 getXxx()
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id);
System.out.println(name);
System.out.println(money);
System.out.println("--------------");
}
//7. 释放资源
rs.close();
stmt.close();
conn.close();
}
}
The running results are as follows:
Compare the query statements in the database as follows:
Note: The method of obtaining data can also be replaced by the following
// 使用参数为列的名称
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
// 使用参数为列的编号
int id = rs.getInt(1);
String name = rs.getString(2);
double money = rs.getDouble(3);
3.4.3 Encapsulating entity classes
Requirement: Query the account table data, encapsulate it as an Account object, and store it in the ArrayList collection.
1. CreateAccount
entity class corresponding toaccount
account table data
public class Account {
private Integer id; // ID
private String name; // 姓名
private Double money; // 余额
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
2. Execute the query statement
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* 查询account账户表数据,封装到Account对象中,并且存储到ArrayList集合中
* 1. 定义实体类Account
* 2. 查询数据,封装到Account对象中
* 3. 将Account对象存入ArrayList集合中
*/
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 1.注册驱动,mysql8的驱动会自动加载注册,此行可以注释掉
// Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 3.定义sql
String sql = "select * from account";
// 4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
// 5.执行sql
ResultSet rs = stmt.executeQuery(sql);
List<Account> accountList = new ArrayList<>(); // 创建集合
// 6.处理结果,遍历rs中的所有数据
while (rs.next()){
Account account = new Account(); // 创建account对象
// 获取数据
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
//给account对象赋值
account.setId(id);
account.setName(name);
account.setMoney(money);
accountList.add(account); // 存入集合
}
System.out.println(accountList);
//7. 释放资源
rs.close();
stmt.close();
conn.close();
}
}
operation result:
[Account{id=1, name='张三', money=3000.0}, Account{id=2, name='李四', money=2000.0}]
3.5 PreparedStatement
The role of PreparedStatement: precompile SQL statements and execute them (to prevent SQL injection problems)
3.5.1 Demonstrate SQL injection
SQL injection: A method of modifying pre-defined SQL statements by manipulating input to execute code and attack the server.
The preparation materials are as follows: Baidu network disk link:https://pan.baidu.com/s/1vzYHt1y4fEvcnyTyiRRDDw, extraction code: d1wy
sql.jar
application.properties
1. Modifyapplication.properties
the file and modify the configuration to your local database user name and password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/itheima?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
2. Open the terminal and enter the command to run the program
java -jar sql.jar
Note:
application.properties
andsql.jar
must be placed in the same directory, otherwise an error will be reported
3. After running, the database will be automatically createdtest
and the tableuser
will be created
user
The contents of the table are as follows: store username and password information
4. Enter http://localhost:8080/login.html
in the browser to enter the login page. First test whether the login page is valid.
Enter the correct username and password: zhangsan
and 123
Entering incorrect username and password:
zhangsan
and1234
abc
and123
5. To demonstrate SQL injection, enter any user name when logging in, but enter a specific string for the password, and find that you can log in successfully.
Enter the username and password as follows: abc
and ' or '1' ='1
3.5.2 Analyzing SQL Injection
The code simulates the process of SQL injection:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户输入的用户名和密码,然后拼接成sql
/*String name = "zhangsan";
String pwd = "123";*/
String name = "abc";
String pwd = "' or '1' = '1";
String sql = "select * from user where username = '"+name+"' and password = '"+pwd+"'";
System.out.println(sql); // select * from user where username = 'abc' and password = '' or '1' = '1'
// 获取Statement对象
Statement stmt = conn.createStatement();
// 执行sql
ResultSet rs = stmt.executeQuery(sql);
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
// 释放资源
rs.close();
stmt.close();
conn.close();
}
}
The above code splices the username and password into a sql statement. The spliced sql statement is as follows:
select * from user where username = 'abc' and password = '' or '1' = '1'
It can be seen from the above statement that the condition username = 'abc' and password = ''
is satisfied or not, and the following after or
is always satisfied. , the final condition is established, and you can log in normally. '1' = '1'
3.5.3 Solve SQL injection
PreparedStatement
: Using the PreparedStatement
object can prevent SQL injection problems.
PreparedStatement
Object usage:
1. Get the PreparedStatement object
// SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
// 通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);
2. Set the parameter value, that is, the value of ?
The parameters in the above sql statement use
?
as placeholders. You must set these?
values before executing the sql.
PreparedStatement
The object provides methods for setting parameter values: setXxx(参数1,参数2)
, such as setString(int parameterIndex, String x)
- Xxx: indicates data type
- parameter:
- Parameter 1: The position number of
?
, starting from 1 - Parameter 2: The value of
?
- Parameter 1: The position number of
3. Execute SQL statements
executeUpdate()
: Execute DDL statements and DML statementsexecuteQuery()
: Execute DQL statement
Note: There is no need to pass the SQL statement when calling these two methods, because the SQL statement has been precompiled when obtaining the SQL statement execution object.
UsePreparedStatement
Modification:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户输入的用户名和密码
String name = "zhangsan";
// String pwd = "123";
String pwd = "' or '1' = '1";
// 定义sql
String sql = "select * from user where username = ? and password = ?";
// 获取PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数 ? 的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
System.out.println(sql);
// 执行sql
ResultSet rs = pstmt.executeQuery();
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
// 释放资源
rs.close();
pstmt.close();
conn.close();
}
}
Running results: SQL injection failed, login failed
PreparedStatement prevents SQL injection by escaping special characters. The escaped SQL statement is as follows:
select * from user where username = 'zhangsan' and password = '\'or \'1\' = \'1'
3.5.4 PreparedStatement principle
PreparedStatement benefits:
- Pre-compiled SQL for higher performance
- Prevent SQL injection: escape sensitive characters
The Java code operation database process is as shown in the figure:
The steps for Java code to operate the database are as follows:
-
Send sql statement to MySQL server
-
The MySQL server will perform the following operations on the sql statement
-
Check SQL statement
Check whether the syntax of the SQL statement is correct
-
Compile SQL statements into executable functions
Checking the SQL and compiling the SQL takes longer than executing the SQL. If we just reset the parameters, checking the SQL statement and compiling the SQL statement will not need to be repeated. This improves performance.
-
Execute SQL statement
-
Next, let’s take a look at the principle by querying the mysql log:
1. Turn on the pre-compilation function
You need to add the following parameters when writing the url:
useServerPrepStmts=true
2. Configure MySQL execution log (effective after restarting the mysql service)
In the MySQL installation path, findmy.ini
, and modify the log-related content as follows:
# General and Slow logging.
log-output=FILE
general-log=1
general_log_file="D:\mysqlLog\mysql.log"
slow-query-log=1
slow_query_log_file="D:\mysqlLog\mysql-slow.log"
long_query_time=2
Win+R
Enter services.msc
Open the service, find the MySQL service and restart it. Check whether the file is generated in the log path just configured. If it is generated, the configuration has taken effect.
3. Write test code
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 获取连接,useServerPrepStmts=true 参数开启预编译功能
String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useServerPrepStmts=true&allowPublicKeyRetrieval=true";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户输入的用户名和密码
String name = "zhangsan";
String pwd = "' or '1' = '1";
// 定义sql
String sql = "select * from user where username = ? and password = ?";
// 获取PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 执行第一次查询
// Thread.sleep(5000);
ResultSet rs = null;
pstmt.setString(1,name);
pstmt.setString(2,pwd);
rs = pstmt.executeQuery();
// 执行第二次查询
pstmt.setString(1,"abc");
pstmt.setString(2,"123");
rs = pstmt.executeQuery();
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
// 释放资源
rs.close();
pstmt.close();
conn.close();
}
}
After running the code, open the mysql.log
file and view the printed content:
Among the three lines of statements in the circle in the picture below, the first line of Prepare
is to precompile the SQL statement. The second and third lines execute the SQL statement twice, and the SQL is not precompiled before the second execution.
Summarize:
- When obtaining the PreparedStatement object, send the sql statement to the mysql server for checking and compilation (these steps are time-consuming)
- You don’t have to go through these steps when executing, and it’s faster.
- If the sql template is the same, it only needs to be checked and compiled once.
4. Database connection pool
4.1 Overview of database connection pool
1. Concept of database connection pool:
- The database connection pool is a container responsible for allocating and managing database connections (Connection)
- It allows an application to reuse an existing database connection instead of establishing a new one.
- Release database connections whose idle time exceeds the maximum idle time to avoid missing database connections caused by not releasing the database connections.
2. Benefits of using database connection pool:
- Resource reuse
- Improve system response speed
- Avoid missing database connections
Before we used connections in our code, we created a Connection object without using it, and it will be destroyed after use. This repeated creation and destruction process consumes computer performance and time. After the database uses the database connection pool, it can achieve the reuse of Connection objects, as shown below:
The connection pool creates some connection objects at the beginning and stores them. When users need to connect to the database, they do not need to create a connection themselves, but only need to obtain a connection from the connection pool for use, and then return the connection object to the connection pool after use. This can reuse resources and save frequent creation. The time it takes for the connection to be destroyed improves the speed of system response.
3. Implementation of database connection pool
Standard interface:DataSource
The official (SUN) standard interface for database connection pools is implemented by third-party organizations. This interface provides the function of obtaining connections:
Connection getConnection()
Then there is no need to obtain the object through the DriverManager
object, but through the connection pool () object. Connection
DataSource
Connection
4. Common database connection pools
DBCP
C3P0
Druid
(commonly used)
4.2 Use of Driud
Druid:
- Druid connection pool is Alibaba's open source database connection pool project
- With powerful functions and excellent performance, it is one of the best database connection pools in Java language.
The steps to use Driud are as follows:
- Import the jar package, such as druid-1.2.9.jar
- Define configuration file
- Load configuration file
- Get the database connection pool object
- Get connection
1.jar package download
Driud jar package download address:https://repo1.maven.org/maven2/com/alibaba/druid/
Scroll to the end, find the latest version of the jar package, and click to download:druid-1.2.9.jar
2. Import the jar package, that is, drag druid-1.2.9.jar
into the project's lib
folder and add it as a library file
In the 3.src directory, create a new driud.properties
configuration file
4. Writedriud.properties
configuration file with the following content:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false&useServerPrepStmts=true
username=root
password=123456
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
5. Write druid code
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
/**
* Druid数据库连接池演示
*/
public class JDBCDemo {
public static void main(String[] args) throws Exception {
// 获取用户当前的工作目录
// System.out.println(System.getProperty("user.dir"));
// 1.导入jar包
// 2.定义配置文件
// 3.加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("src/driud.properties"));
// 4.获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 5.获取数据库连接 Connection
Connection connection = dataSource.getConnection();
System.out.println(connection); // 获取到了连接后就可以继续做其他操作了
}
}
Tips: You can use
System.getProperty("user.dir")
to get the user's current working directory to know the relative path of the loaded file.
5. Case exercises
5.1 Data preparation
Requirements: Complete the addition, deletion, modification and query operations of product brand data
- Query: Query all data
- Add: add brand
- Modify: modify according to id
- Delete: delete based on id
1.Create database tabletb_brand
-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand (
id int primary key auto_increment, -- id主键
brand_name varchar(20), -- 品牌名称
company_name varchar(20), -- 企业名称
ordered int, -- 排序字段
description varchar(100), -- 描述信息
status int -- 状态:0:禁用 1:启用
);
-- 向tb_brand表插入数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
('小米', '小米科技有限公司', 50, 'are you ok', 1);
-- 查询tb_brand表
select * from tb_brand;
2. Create entity classes under the pojo packageBrand
package com.itheima.pojo;
/**
* 品牌
* 在实体类中,基本数据类型建议使用其对应的包装类型
*/
public class Brand {
private Integer id; // id 主键
private String brandName; // 品牌名称
private String companyName; // 企业名称
private Integer ordered; // 排序字段
private String description; // 描述信息
private Integer status; // 状态:0:禁用 1:启用
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Integer getOrdered() {
return ordered;
}
public void setOrdered(Integer ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "Brand{" +
"id=" + id +
", brandName='" + brandName + '\'' +
", companyName='" + companyName + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
The project structure is as follows:
5.2 Query all
/**
* 查询所有
* 1. SQL:select * from tb_brand;
* 2. 参数:不需要
* 3. 结果:List<Brand>
*/
@Test
public void selectAll() throws Exception{
// 加载配置文件,并获取连接池对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/driud.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义sql
String sql = "select * from tb_brand";
// 获取PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 执行查询语句
ResultSet rs = pstmt.executeQuery();
List<Brand> brandList = new ArrayList<>();
Brand brand = null;
while (rs.next()){
// 获取数据
int id = rs.getInt("id");
String brandName = rs.getString("brand_name");
String companyName = rs.getString("company_name");
int ordered = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
//封装Brand对象
brand = new Brand();
brand.setId(id);
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(ordered);
brand.setDescription(description);
brand.setStatus(status);
// 存入集合
brandList.add(brand);
}
System.out.println(brandList);
// 释放资源
rs.close();
pstmt.close();
conn.close();
}
The running results are as follows:
5.3 Add data
/**
* 添加
* 1. SQL:insert into tb_brand(brand_name, company_name, ordered, description, status) values(?,?,?,?,?);
* 2. 参数:需要,除了id之外的所有参数信息
* 3. 结果:boolean
*/
@Test
public void add() throws Exception{
// 页面提交的数据
String brandName = "香飘飘";
String companyName = "香飘飘";
int ordered = 1;
String description = "绕地球一圈";
int status = 1;
// 加载配置文件,并获取连接池对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/driud.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义sql
String sql = "insert into tb_brand(brand_name, company_name, ordered, description, status) values(?,?,?,?,?)";
// 获取PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setString(1,brandName);
pstmt.setString(2,companyName);
pstmt.setInt(3,ordered);
pstmt.setString(4,description);
pstmt.setInt(5,status);
// 执行插入语句
int count = pstmt.executeUpdate();
System.out.println(count > 0);
// 释放资源
pstmt.close();
conn.close();
}
After running the above code, query the brand table:
5.4 Modify data
/**
* 修改
* 1. SQL:
update tb_brand
set brand_name = ?, company_name = ?, ordered = ?, description = ?, status = ?
where id = ?
* 2. 参数:需要,所有数据
* 3. 结果:boolean
*/
@Test
public void update() throws Exception{
// 页面提交的数据
String brandName = "香飘飘";
String companyName = "香飘飘";
int ordered = 1000;
String description = "绕地球三圈";
int status = 1;
int id = 4;
// 加载配置文件,并获取连接池对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/driud.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义sql
String sql = "update tb_brand\n" +
"set brand_name = ?, company_name = ?, ordered = ?, description = ?, status = ?\n" +
"where id = ?";
// 获取PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setString(1,brandName);
pstmt.setString(2,companyName);
pstmt.setInt(3,ordered);
pstmt.setString(4,description);
pstmt.setInt(5,status);
pstmt.setInt(6,id);
// 执行更新语句
int count = pstmt.executeUpdate();
System.out.println(count > 0);
// 释放资源
pstmt.close();
conn.close();
}
After running the above code, query the brand table:
5.5 Deletion of data
/**
* 删除
* 1. SQL:delete from tb_brand where id = ?
* 2. 参数:需要,id
* 3. 结果:boolean
*/
@Test
public void deleteById() throws Exception{
// 页面提交的数据
int id = 4;
// 加载配置文件,并获取连接池对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/driud.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义sql
String sql = "delete from tb_brand where id = ?";
// 获取PreparedStatement对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setInt(1,id);
// 执行删除语句
int count = pstmt.executeUpdate();
System.out.println(count > 0);
// 释放资源
pstmt.close();
conn.close();
}
After running the above code, query the brand table: