What is JDBC?
- JDBC is (java database connectivity), which is a standard rule interface for linking databases written by sun company in java language.
What can JDBC do for us?
- jdbc uses a unified set of java codes to operate all relational databases. The interface operation is as follows:
- Sun company provides a unified database driver interface. Major database vendors write their own implementation classes according to the interface provided by sun company and package them into jar packages. Such jar packages have become the database drivers of major manufacturers. When you need to use a certain database, you only need to import the jar package corresponding to the database to connect to the database normally. (The actual code executed is the implementation class in the driver jar package).
How is JDBC used?
Steps for usage:
1. Import the driver jar package
Manual import
- Copy mysql-connector-java-5.1.37-bin.jar to the libs directory of the project
- Right click -> Add As Library
maven dependency import
Register driver steps
1. Obtain the database connection object connection
2. Define SQL
3. Obtain the object statement of the
SQL statement 4. Execute SQL and receive the returned result
5. Process the result
7. Release resources
Java operation database case
public class JdbcTest {
public static void main(String[] args) throws ClassNotFoundException {
Connection connection = null;
Statement statement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
/*connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test2",
"root","root");*/
connection = DriverManager.getConnection("jdbc:mysql:///test2",
"root", "root");
statement = connection.createStatement();
String sql = "update account set balance = 1000; -- where id =1;";
int i = statement.executeUpdate(sql);
if(i<1){
System.out.println("执行失败!!!");
}else{
System.out.println(i);
System.out.println("执行成功!!!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(statement !=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection !=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
Commonly used objects in jdbc
DriverManager driver management object
What does the DriverManager management object do?
In fact, what DriverManager does is mainly composed of the following two parts.
1. Register the driver
Registering the driver actually tells the system which database driver jar package is being used.
There is a static function in DriverManager:
public static void registerDriver(Driver driver)
throws SQLException
But when I wrote the code, I found that Class.forName was used directly to load the driver
Class.forName("com.mysql.jdbc.Driver");
What is the relationship between the two?
In fact, the secret lies in the source code of com.mysql.jdbc.Driver. There are static methods in the source code. When the file is loaded with class.forName("xxx"), the static code block of com.mysql.jdbc.Driver is automatically executed, and the static code is The code of the registered driver in the block will be executed automatically, and part of the source code is as follows:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
Notes: After mysql-connector-java version 5.0, the statement Class.forName("xxx") can be omitted. Because the configuration file was added after 5.0, the content in the configuration file will be automatically read when the program is loaded, so the above steps can be omitted.
2. Get database connection
Get the code method:
static Connection getConnection(String url, String user, String password)
parameter
- url: Specify the connection path
Syntax: jdbc:mysql://ip address (domain name): port number/database name
Example: jdbc:mysql://localhost:3306/test1
Details: If the connection is the local mysql server, and The default port of mysql service is 3306, then the url can be abbreviated as: jdbc:mysql:///database name
user: user name
password: password
Connection database connection object
Features
- Get database connection:
Statement createStatement();
PrepareStatement prepareStatement(String sql);
- Management affairs
- Start the transaction: setAutoCommit(boolean autoCommit): The calling method is false to start the transaction.
- Commit the transaction commit();
- Roll back the transaction rollback();
Statement object to execute sql
An object used to execute static SQL statements and return the results they generate.
boolean execute(String sql) throws SQLException
The above sql can execute any sql;
int executeUpdate(String sql) throws SQLException
Under normal circumstances, the sql executes DML (insert, update, delete) statements, DDL (data definition language) (create, alter, drop) statement
return value, indicating the number of rows of impression, you can judge the DML statement by the number of rows affected Whether the execution is successful and the return value is >0, the execution is successful, otherwise, it fails.
ResultSet executeQuery(String sql) :执行DQL(select)语句
ResultSet: result set object
It is used to encapsulate the results of the query.
getXxx(): Get data.
Xxx: represents the data type such as int getInt(), String getString();
parameters:
- int: represents the column number, starting from 1, such as: getString();
String: represents the column name. Such as: getDouble("balance")
Case number one
public class Jdbc02Test {
public static void main(String[] args) {
List<Emp> all = findAll();
for (Emp emp :
all) {
System.out.println(emp);
}
}
public static List<Emp> findAll(){
Connection connection =null;
Statement statement = null;
ResultSet resultSet = null;
LinkedList<Emp> emps =null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql:///test2",
"root", "root");
statement = connection.createStatement();
String sql = "select * from account;";
resultSet = statement.executeQuery(sql);
/*while (resultSet.next()){
int anInt = resultSet.getInt(1);
String name = resultSet.getString("name");
double balance = resultSet.getDouble("balance");
System.out.println(anInt+"----->"+name+"----->"+balance);
}*/
emps = new LinkedList<>();
while (resultSet.next()){
Emp emp = new Emp();
emp.setId(resultSet.getInt(1));
emp.setName(resultSet.getString("name"));
emp.setBalance(resultSet.getDouble("balance"));
emps.add(emp);
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally {
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return emps;
}
}
search result:
Case two
Use the list form to print out the results of the query.
Entity class:
public class Emp {
private int id;
private String name;
private Double balance;
public Emp() {
}
public Emp(int id, String name, Double balance) {
this.id = id;
this.name = name;
this.balance = balance;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
", balance=" + balance +
'}';
}
}
Test category:
public class JdbcTest {
public static void main(String[] args) throws ClassNotFoundException {
Connection connection = null;
Statement statement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
/*connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test2",
"root","root");*/
connection = DriverManager.getConnection("jdbc:mysql:///test2",
"root", "root");
statement = connection.createStatement();
String sql = "update account set balance = 1000; -- where id =1;";
int i = statement.executeUpdate(sql);
if(i<1){
System.out.println("执行失败!!!");
}else{
System.out.println(i);
System.out.println("执行成功!!!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(statement !=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection !=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
PreparedStatement
SQL injection problem:
- When splicing SQL, some special keywords of SQL participate in the splicing of strings. Will cause security problems, such as sql injection in case two in JDBCUtils
- Enter the user casually, enter the password: a'or'a' ='a
- The sql executed in the actual database is as follows
select
*
from
account
where
username = 'woailuo'
and
password= 'wo'
or
'ailuo' = 'ailuo';
How to solve the SQL injection problem
Sun provides a PreparedStatement object to solve the problem of SQL injection.
Pre-compiled SQL
Parameter use? as a placeholder
Extract the JDBCUtils class
Case number one
Abstract loading resource files and releasing resource files into a tool class, and then implement database operations
resource
url=jdbc:mysql:///test2
username=root
password=root
driver=com.mysql.jdbc.Driver
Entity class
public class Emp {
private int id;
private String name;
private Double balance;
public Emp() {
}
public Emp(int id, String name, Double balance) {
this.id = id;
this.name = name;
this.balance = balance;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
", balance=" + balance +
'}';
}
}
Tools
public class JDBCUtils {
private static String url;
private static String username;
private static String password;
private static String driver;
//静态代码块,加载资源文件
static {
try {
Properties properties = new Properties();
//加载文件
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL resource = classLoader.getResource("jdbc.properties");
String path = resource.getPath();
System.out.println(path);
properties.load(new FileReader(path));
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
driver = properties.getProperty("driver");
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
Connection connection = null;
try {
connection = DriverManager.getConnection(url, username, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
return connection;
}
}
public static void close(Statement statement, Connection connection){
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(ResultSet resultSet, Statement statement, Connection connection){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
Test class
Connection connection =null;
Statement statement = null;
ResultSet resultSet = null;
LinkedList<Emp> emps =null;
try {
connection = JDBCUtils.getConnection();
String sql = "select * from account;";
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
emps = new LinkedList<>();
while (resultSet.next()){
Emp emp = new Emp();
emp.setId(resultSet.getInt(1));
emp.setName(resultSet.getString("name"));
emp.setBalance(resultSet.getDouble("balance"));
emps.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,statement,connection);
return emps;
}
Test Results
Case two
Demonstration code: The
tool classes and resource files are consistent with the case 1, and case 2 does not require entity classes, so the data table needs to be slightly modified.
Need to modify the database.
use test2;
alter TABLE account add PASSWORD VARCHAR(20);
ALTER TABLE account CHANGE PASSWORD password VARCHAR(20);
ALTER TABLE account CHANGE NAME username VARCHAR(20);
UPDATE account SET PASSWORD = 'zhangsan' WHERE `NAME`='zhangsan';
UPDATE account SET PASSWORD = 'lisi' WHERE `NAME`='lisi';
SELECT * FROM account;
desc account;
The database tables and table structure are as follows:
Test category:
public class jdbc03Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
boolean flag = login(username, password);
if(flag){
System.out.println("登录成功!!!");
}else {
System.out.println("登录失败!!!");
}
}
public static boolean login(String username, String password){
Connection connection =null;
Statement statement = null;
ResultSet resultSet = null;
boolean loginFlag = false;
try {
connection = JDBCUtils.getConnection();
String sql = "select * from account where username = '"+username+"' and password= '"+password+"';";
System.out.println(sql);
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
if(resultSet.next()){
loginFlag = true;
System.out.println(resultSet.getString(2));
return loginFlag;
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,statement,connection);
}
return loginFlag;
}
}
Demonstrate sql injection problem.
When you just enter the account number: woailuo Password: wo' or'ailuo' ='ailuo,
we found that the login was successful.
It can be seen that the SQL injection problem is still quite serious.
We already know that PreparedStatement can solve the SQL injection problem. The following case three will show how to use PreparedStatement objects.
Case three
The resource class and tool class remain the same as in Case 2, and the statement object is changed to preparestatement
public class JDBC04Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
boolean flag = login(username, password);
if(flag){
System.out.println("登录成功!!!");
}else {
System.out.println("登录失败!!!");
}
}
public static boolean login(String username,String password){
if(username == null || password==null){
return false;
}
Connection connection =null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
boolean loginFlag = false;
try {
connection = JDBCUtils.getConnection();
String sql = "select * from account where username = ? and password= ?;";
System.out.println(sql);
preparedStatement = connection.prepareStatement(sql);
//需要给问好赋值
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
resultSet = preparedStatement.executeQuery();
if(resultSet.next()){
loginFlag = true;
System.out.println(resultSet.getString(2));
return loginFlag;
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,preparedStatement,connection);
}
return loginFlag;
}
}
SQL injection failed, this problem is resolved.
jdbc transaction control
jdbc transaction control process
Transaction control can use the Connection object.
Open the transaction:
- setAutoCommit(boolean autoCommit): Call this method to set the parameter to false, that is, start the transaction before executing SQL:
Commit the transaction:
- commit(); Submit the transaction after all SQL execution in the same transaction is completed.
Roll back the transaction:
- rollback(); Roll back the transaction in catch
It can also implement transaction management
Case number one
In this case, the tool class and resource class are consistent with the extracted JDBCUtils class
Test class
public class JDBC05Test {
public static void main(String[] args) {
System.out.println("----------交易开始前----------");
List<Emp> all = findAll();
for (Emp emp :
all) {
System.out.println(emp);
}
transaction("zhangsan","lisi",500);
System.out.println("------交易完成后-------");
all=findAll();
for (Emp emp :
all) {
System.out.println(emp);
}
}
public static boolean transaction(String user1, String user2, double val ){
Connection connection =null;
PreparedStatement preparedStatement1 = null, preparedStatement2=null;
ResultSet resultSet = null;
try {
connection = JDBCUtils.getConnection();
connection.setAutoCommit(false);
String sql1 = " update account set balance = balance - ? where username = ?";
String sql2 = " update account set balance = balance + ? where username = ?";
preparedStatement1 = connection.prepareStatement(sql1);
preparedStatement2 = connection.prepareStatement(sql2);
preparedStatement1.setDouble(1,val);
preparedStatement1.setString(2,user1);
preparedStatement2.setDouble(1,val);
preparedStatement2.setString(2,user2);
int i = preparedStatement1.executeUpdate();
// int i2= 4/0;
int i1 = preparedStatement2.executeUpdate();
connection.commit();
} catch (Exception e) {
try {
if(connection !=null){
connection.rollback();
}
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
e.printStackTrace();
return false;
}finally {
JDBCUtils.close(resultSet,preparedStatement1,connection);
JDBCUtils.close(resultSet,preparedStatement2,connection);
}
return true;
}
public static List<Emp> findAll(){
Connection connection =null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
LinkedList<Emp> emps =null;
try {
connection = JDBCUtils.getConnection();
String sql = "select * from account;";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
emps = new LinkedList<>();
while (resultSet.next()){
Emp emp = new Emp();
emp.setId(resultSet.getInt(1));
emp.setUsername(resultSet.getString("username"));
emp.setBalance(resultSet.getDouble("balance"));
emp.setPassword("password");
emps.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,preparedStatement,connection);
return emps;
}
}
}
When there is no exception in the transaction, the entire transaction runs normally.
When there is an exception in the transaction, the transaction is rolled back directly.
public class JDBC05Test {
public static void main(String[] args) {
System.out.println("----------交易开始前----------");
List<Emp> all = findAll();
for (Emp emp :
all) {
System.out.println(emp);
}
transaction("zhangsan","lisi",500);
System.out.println("------交易完成后-------");
all=findAll();
for (Emp emp :
all) {
System.out.println(emp);
}
}
public static boolean transaction(String user1, String user2, double val ){
Connection connection =null;
PreparedStatement preparedStatement1 = null, preparedStatement2=null;
ResultSet resultSet = null;
try {
connection = JDBCUtils.getConnection();
connection.setAutoCommit(false);
String sql1 = " update account set balance = balance - ? where username = ?";
String sql2 = " update account set balance = balance + ? where username = ?";
preparedStatement1 = connection.prepareStatement(sql1);
preparedStatement2 = connection.prepareStatement(sql2);
preparedStatement1.setDouble(1,val);
preparedStatement1.setString(2,user1);
preparedStatement2.setDouble(1,val);
preparedStatement2.setString(2,user2);
int i = preparedStatement1.executeUpdate();
int i2= 4/0;
int i1 = preparedStatement2.executeUpdate();
connection.commit();
} catch (Exception e) {
try {
if(connection !=null){
connection.rollback();
}
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
e.printStackTrace();
return false;
}finally {
JDBCUtils.close(resultSet,preparedStatement1,connection);
JDBCUtils.close(resultSet,preparedStatement2,connection);
}
return true;
}
public static List<Emp> findAll(){
Connection connection =null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
LinkedList<Emp> emps =null;
try {
connection = JDBCUtils.getConnection();
String sql = "select * from account;";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
emps = new LinkedList<>();
while (resultSet.next()){
Emp emp = new Emp();
emp.setId(resultSet.getInt(1));
emp.setUsername(resultSet.getString("username"));
emp.setBalance(resultSet.getDouble("balance"));
emp.setPassword("password");
emps.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,preparedStatement,connection);
return emps;
}
}
}
So far, the basic knowledge of jdbc is reviewed here.