The database implements the data persistence , But we have to process the data in the program , that java How to access the database, read and write data in the code ?
That's what we need sun A set of database standards set by the company , This set of standards is JDBC(Java Database Connectivity). But it's just the norm , Don't make concrete realization . So the database manufacturer again according to JDBC standard , Realize your own drive Driver. Such as :mysql drive com.mysql.cj.jdbc.Driver,Oracle The driver oracle.jdbc.OracleDriver. With this solution ,java You can access the data in the database .
public interface Connection extends Wrapper, AutoCloseable {}
public interface Statement extends Wrapper, AutoCloseable {}
public interface PreparedStatement extends Statement {}
public interface CallableStatement extends PreparedStatement {}
public interface ResultSet extends Wrapper, AutoCloseable {}Java Interface oriented development is advocated in , The most classic interface design is JDBC Database interface .
If you have any questions, you can watch the video :
https://www.bilibili.com/vide...
Connection link 、Statement sentence 、PreparedStatement Preprocessing statement 、CallableStatement stored procedure 、ResultSet Result set .
There are three ways to call :
Statement sentence 、PreparedStatement Preprocessing statement 、CallableStatement stored procedure , The second is recommended PreparedStatement, prevent SQL Inject , It is also precompiled with high performance .
Use steps
- Import jar package ( Rich tool classes )
- Get the connection to the database ( user name 、 password )
- Execute by program SQL
- Process the results through the program
idea Create a project and import jar package
- establish stage2 Java engineering
- establish lib Catalog , Copy driven objbc6-11.1.0.7.0 To lib Under the table of contents
- The project references this external jar package
Introductory cases
package cn.tedu.jdbc;
import java.sql.*;
// test jdbc
// demand : Inquire about cgb2104 In the database students All the data in the table
public class Test1 {
public static void main(String[] args) throws Exception {
//1, Registration drive
Class.forName("com.mysql.jdbc.Driver");
//2, Get the connection to the database
//String url= "jdbc:mysql://localhost:3306/cgb2104?characterEncoding=utf8";// Specify which database to connect to
String url= "jdbc:mysql:///cgb2104?characterEncoding=utf8";// Specify which database to connect to
String user= "root" ; // User name used
String pwd= "root" ; // Password used
Connection conn = DriverManager.getConnection(url, user, pwd);
//3, Get the transmitter , perform SQL
Statement st = conn.createStatement();
//4, perform SQL
ResultSet rs = st.executeQuery("select * from students");
//5, Parse the result set
while( rs.next() ){//next() Determine whether there is data in the result set
for (int i = 1; i <= 5 ; i++) {
// Get the value of each column and print
System.out.println( rs.getString(i) );
}
}
//6, Release resources
rs.close(); // Close result set
st.close();// Turn off the transmitter
conn.close();// Close the connection
}
}SQL Inject
/* Prepare yourself user2 surface (id/name/password), Prepare the data
CREATE TABLE `user2` (
`id` int(11) PRIMARY KEY auto_increment,
`name` varchar(10) default NULL,
`password` varchar(10) default NULL
) ;
*/
// demand : utilize jdbc, Search by user name and password cgb2104 In the database user surface
//SQL Injection attack problem
private static void login() {
try{
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql:///cgb2104?characterEncoding=utf8";
Connection conn = DriverManager.getConnection(url, "root", "root");
Statement st = conn.createStatement();
// String sql ="select * from user2 where name='jack' and password='123456'";// It's dead
String user = new Scanner(System.in).nextLine();// User input jack'#
String pwd = new Scanner(System.in).nextLine();
//SQL Injection attack problem : Essentially because SQL A special symbol appears in the statement #, Changed the SQL semantics
String sql ="select * from user2 where name='"+user+"' and password='"+pwd+"'";
ResultSet rs = st.executeQuery(sql);// Executing the query SQL, Return result set
if(rs.next()){
System.out.println(" Login successful ~");
}else{
System.out.println(" Login failed ~");
}
st.close();
conn.close();
}catch(Exception e){
e.printStackTrace();// There are abnormal , Print exception information directly
//System.out.println(" Execution failure ...");// go online
}
}SQL Injected solutions
// solve SQL The scheme of injection attack
private static void login2() {
try{
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql:///cgb2104?characterEncoding=utf8";
Connection conn = DriverManager.getConnection(url, "root", "root");
// Statement st = conn.createStatement(); no way , unsafe , Will be SQL attack
String user = new Scanner(System.in).nextLine();// User input jack'#
String pwd = new Scanner(System.in).nextLine();
//? It's called placeholder ,SQL The skeleton of the
String sql ="select * from user2 where name=? and password=?";
// The first SQL The skeleton is sent to the database for execution
PreparedStatement ps = conn.prepareStatement(sql);
// to SQL Inside ? Set parameters
ps.setString(1,user);// Give the first one. ? The setting value is user
ps.setString(2,pwd);// For the second ? The setting value is pwd
ResultSet rs = ps.executeQuery();// Perform the spliced SQL, Return result set
if(rs.next()){
System.out.println(" Login successful ~");
}else{
System.out.println(" Login failed ~");
}
ps.close();
conn.close();
}catch(Exception e){
e.printStackTrace();// There are abnormal , Print exception information directly
//System.out.println(" Execution failure ...");// go online
}
}JDBC common problem
Class.forName Is this sentence useful ?
Class.forName You can specify class Class path to dynamically create object instances , can JDBC This sentence does not return an object , What's the use of writing this sentence ? have a look java.sql.Driver.class The source code will find the truth , It turns out that it uses static code blocks to create objects .
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}Wrote and created , What about not writing ? How can it be executed without writing ?
Java Provides SPI Mechanism , Users can configure classes by themselves ,JDBC High version drivers have introduced this support . If the user uses Class.forName The method specifies its own driver , If you don't write this sentence , be Java Go automatically META-INF/services/java.sql.Driver Found startup class in file .
Driver version
Different versions mysql Different versions of drivers are required
Mysql5.0x mysql-connector-java-5.1.32.jar
Mysql8.0x mysql-connector-java-8.0.21.jar
- Driver Turned into : com.mysql.cj.jdbc.Driver, There are more in the middle cj
- url The time zone parameter must be : serverTimezone=Asia/Shanghai
Chinese garbled
url Add parameters :characterEncoding=utf8 Prevent Chinese miscoding
String url ="jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";SQL Inject
String condition = " Chen Qiang ";
String condition = " Chen Qiang ' or 1=1 or '";
String condition = " Chen Qiang ' or true or '";
String sql = "select * from teachers where tname='" + condition+"'";utilize sql in ' Single prime is the end of a string ,or As long as one condition holds, there is no need to judge the others , And malice causes sql Query invalid , Should have shown only one piece of data , The results all show .
Formed after injection SQL:
SELECT * FROM teachers WHERE tname=' Chen Qiang ' OR 1=1 OR ''Let's imagine if it's a financial statement , Ben, you can only read your own information , As a result, you read everyone's information . As a result, the new employee is paid more than you , You say no .
PreparedStatement sentence
SQL Injection solutions :
Statement Change the object to PreparedStatement object
sql = "select * from teachers where tname=?"; # Parameters use question marks
PreparedStatement stat = cn.prepareStatement(sql); # Change the object
stat.setString(1, condition); # Corresponding parameter type , Which question marks
ResultSet rs = stat.executeQuery(); # Get rid of sql Parameters PS After the results of the :
SELECT * FROM teachers WHERE tname=' Chen Qiang \' or 1=1 or \''Using escape character , Shielded SQL Malicious characters in . Not only did it solve sql Injection problem , Make the system safe ,PreparedStatement There is also a great advantage , It is a precompiled statement , Its main part mysql Cache after precompiling , Next time this part doesn't need to be parsed , Just spell the conditions into , In this way, the execution efficiency is much higher than statement Compile every time sql sentence .
Common mistakes
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
The reason for the error :
1)jar No import , No, builder path
2)Class.forName("com.mysql.jdbc.Driver"); Misspelled string
Unknown database mydb;
The reason for the error :
Misspelled database name
Access denied for user ‘root123’@‘localhost’ (using password: YES)
The reason for the error :
Wrong database user name or password
Table ‘py-school-db.mydb’ doesn’t exist
The reason for the error :
Table does not exist , Or maybe the name of the table is wrong









