《Java基础入门 极速版》

ch12 JDBC


1. JDBC简介

JDBC概念

JDBC本质

JDBC好处:

图1 JDBC----一套标准接口

2. JDBC快速入门

0. 创建工程,导入驱动jar包

mysql-connector-java-5.1.48.jar

// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接 ,
Connection conn = DriverManager.getConnection(url, username, password);
// 3.定义SQL语询
String sql =“update..." ;
// 4.获取执行SQL对象
Statement stmt = conn.createStatement();
// 5.执行SQL
stmt.executeUpdate(sq);
// 6.处理返回结果
// 7.释放资源

【例题1】JDBC快速入门(七步操作数据库)

package cn.zzh.ch12;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.DriverManager;

public class JDBCDemo {
    public static void main(String[] args) throws Exception {
        //1.注册驱动
        // Class.forName("com.mysql.jdbc.Driver");
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.获取连接对象
        String url = "jdbc:mysql://101.42.158.247:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "******";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3.定义SQL
        String sql = "update 账户表 set 金额 = 2000 where id = 2";
        //4.获取执行sqL的对象Statement
        Statement stmt = conn.createStatement();
        //5.执行sqL
        int count = stmt.executeUpdate(sql);//受影响的行数
        //6.处理结果
        System.out.println(count);
        //7.释放资源
        stmt.close();
        conn.close();
    }
}
图2 数据库访问
create table 账户表( id int, 账户名 varchar(10), 金额 int);
insert 账户表 values (1,'杜老师',10),(2,'李同学',20);
select * from 账户表;
update 账户表 set 金额 = 2000 where id = 2;
图3 JDBC快速入门----数据库结果

3. JDBC API详解

(1) DriverManager(驱动管理类)

DriverManager作用:

1.注册驱动

Class.forName("com.mysql.jdbc.Driver");

2.获取数据库连接

static Connection getConnection(String url, String user, String password)

【例题2】DriverManager举例

package cn.zzh.ch12;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class JDBCDemo_1DriverManager {
    public static void main(String[] args) throws Exception {
        //1.注册驱动 可以省略 下一句
        // Class.forName("com.mysql.jdbc.Driver");
        // Class.forName("com.mysql.cj.jdbc.Driver");

        //2.获取连接:如果连接的是本机mysqL并且端口是默认的3306可以简化书泻
        //String url = "jdbc:mysql:///db1";
        String url = "jdbc:mysql://101.42.158.247:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "*******";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3.定义SQL
        String sql = "update 账户表 set 金额 = 30 where id = 2";
        //4.获取执行sqL的对象Statement
        Statement stmt = conn.createStatement();
        //5.执行sql
        int count = stmt.executeUpdate(sql);//受影响的行数
        //6.处理结果
        System.out.println(count);
        //7.释放资源
        stmt.close();
        conn.close();
    }
}
图5 DriverManager执行举例

(2) Connection(数据库连接对象)

Connection作用:

1.获取执行SQL的对象

2.事务管理

MySQL事务管理

JDBC事务管理: Connection接口中定义了3个对应的方法

【例题3】Connection举例

package cn.zzh.ch12;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class JDBCDemo_2Connection {
    public static void main(String[] args) throws Exception {
        //1.注册驱动
        // Class.forName("com.mysql.jdbc.Driver");   //mysql 5.x 驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //2.获取连接对象
        String url = "jdbc:mysql://IP地址:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "密码";
        Connection conn = DriverManager.getConnection(url, username, password);

        //3.定义SQL
        String sql1 = "update 账户表 set 金额 = 3001 where id = 1";
        String sql2 = "update 账户表 set 金额 = 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 = 2/0;

            //5.执行sql
            int count2 = stmt.executeUpdate(sql2);//受影响的行数
            //6.处理结果
            System.out.println(count2);
            //提交事务
            conn.commit();
        } catch (Exception throwables) {
            //回滚事务
            conn.rollback();
            throwables.printStackTrace();
        }

        //7.释放资源
        stmt.close();
        conn.close();
    }
}
图6 Connection举例

(3) Statement语句对象

Statement作用:

1.执行SQL语句

int executeUpdate(sql): 执行DML、DDL语句
➢返回值: (1) DML语句影响的行数  (2) DDL语句执行后,执行成功也可能返回0
ResultSet executeQuery(sql): 执行DQL语句
➢返回值: ResultSet 结果集对象

【例题4】Statement举例:DML和DDL

package cn.zzh.ch12;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import org.junit.Test;

/**
 * JDBC API 详解:Statement
 */
public class JDBCDemo_3Statement {
    /**
     * 执行DML语句
     * @throws Exception
     */
    @Test
    public void testDML() throws  Exception {
       //1. 注册驱动
       //Class.forName("com.mysql.jdbc.Driver");
       //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql://101.42.158.247:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "*******";
        Connection conn = DriverManager.getConnection(url, username, password);

        //3. 定义sql
        String sql = "update 账户表 set 金额 = 3033 where id = 1";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //5. 执行sql
        int count = stmt.executeUpdate(sql);//执行完DML语句,受影响的行数

       //6. 处理结果
        System.out.println(count);
        if(count > 0){
            System.out.println("修改成功~");
        }else{
            System.out.println("修改失败~");
        }

       //7. 释放资源
       stmt.close();
       conn.close();
   }

    /**
     * 执行DDL语句
     * @throws Exception
     */
    @Test
    public void testDDL() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql://101.42.158.247:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "*********";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        //String sql = "create database db2";
        String sql = "drop database db2";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //5. 执行sql
        int count = stmt.executeUpdate(sql);//执行完DDL语句,可能是0
        //6. 处理结果
        System.out.println(count);
        if(count > 0){
            System.out.println("修改成功~");
        }else{
            System.out.println("修改失败~");
        }
        //7. 释放资源
        stmt.close();
        conn.close();
    }
}
图7 DML执行成功
图8 DDL执行失败
图9 DDL执行成功

(4) Statement结果集

【例题5】ResultSet测试和ResultSet案例

ResultSet案例:查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中

package cn.zzh.ch12.pojo;

public class Account {

    private int id;
    private String 账户名;
    private double 金额;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String get账户名() {
        return 账户名;
    }

    public void set账户名(String 账户名) {
        this.账户名 = 账户名;
    }

    public double get金额() {
        return 金额;
    }

    public void set金额(double 金额) {
        this.金额 = 金额;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", 账户名='" + 账户名 + '\'' +
                ", 金额=" + 金额 +
                '}';
    }
}
package cn.zzh.ch12;

import cn.zzh.ch12.pojo.Account;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * JDBC API 详解:ResultSet
 */
public class JDBCDemo_4ResultSet {

    /**
     * 执行DQL
     * @throws Exception
     */
    @Test
    public void testResultSet() throws  Exception {
       //1. 注册驱动
       //Class.forName("com.mysql.jdbc.Driver");
       //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql://IP地址:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "密码";
       Connection conn = DriverManager.getConnection(url, username, password);

       //3. 定义sql
        String sql = "select * from 账户表";

        //4. 获取statement对象
        Statement stmt = conn.createStatement();

        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);

        //6. 处理结果, 遍历rs中的所有数据
        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            //6.2 获取数据  getXxx()
            int id = rs.getInt(1);
            String name = rs.getString(2);
            double money = rs.getDouble(3);

            System.out.println(id);
            System.out.println(name);
            System.out.println(money);
            System.out.println("--------------");
        }

        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        System.out.println();
        rs = stmt.executeQuery(sql);
        while (rs.next()){
            //6.2 获取数据  getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("账户名");
            double money = rs.getDouble("金额");

            System.out.println(id);
            System.out.println(name);
            System.out.println(money);
            System.out.println("--------------");
        }

        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }


    /**
     * 查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
     * 1. 定义实体类Account
     * 2. 查询数据,封装到Account对象中
     * 3. 将Account对象存入ArrayList集合中
     *
     * @throws Exception
     */
    @Test
    public void testResultSet2() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql://IP地址:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "密码";
        Connection conn = DriverManager.getConnection(url, username, password);

        //3. 定义sql
        String sql = "select * from 账户表";

        //4. 获取statement对象
        Statement stmt = conn.createStatement();

        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);

        // 创建集合
        List<Account> list = new ArrayList<>();

        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            Account account = new Account();

            //6.2 获取数据  getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("账户名");
            double money = rs.getDouble("金额");

            //赋值
            account.setId(id);
            account.setName(name);
            account.setMoney(money);

            // 存入集合
            list.add(account);
        }

        System.out.println(list);

        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }

}
图10 ResultSet测试1
图12 ResultSet测试2

(5) PreparedStatement

-- 删除tb user表
DROP TABLE IF EXISTS tb_user;
-- 创建tb user表
CREATE TABLE tb_user (
id int,
username VARCHAR(20),
password VARCHAR(32)
) ;
-- 添加数据
INSERT INTO tb_user VALUES(1, 'zhangsan' , '123'), (2, 'lisi', '234');
SELECT * from tb_user;

【例题6】SQL注入

package cn.zzh.ch12;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * 用户登录 SQL 注入
 */
public class JDBCDemo_5UserLogin {

    @Test
    public void testLogin() throws  Exception {
       //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql://IP地址:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "密码";
       Connection conn = DriverManager.getConnection(url, username, password);

       // 接收用户输入 用户名和密码
        String name = "zhangsan";
        //String pwd = "123";
        String pwd = "fhsjkfhdsk";

        String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";

        // 获取stmt对象
        Statement stmt = conn.createStatement();

        // 执行sql
        ResultSet rs = stmt.executeQuery(sql);

        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }

        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }


    /**
     * 演示SQL注入
     * @throws Exception
     */
    @Test
    public void testLogin_Inject() throws  Exception {
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql://IP地址:3306/ch12_du?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";
        String username = "root";
        String password = "密码";
        Connection conn = DriverManager.getConnection(url, username, password);

        // 接收用户输入 用户名和密码
        String name = "hfkjsfhskj";
        String pwd = "' or '1' = '1";

        String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
        System.out.println(sql);
        // 获取stmt对象
        Statement stmt = conn.createStatement();
        // 执行sql
        ResultSet rs = stmt.executeQuery(sql);

        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }

        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}
图12 登录成功
图13 登录失败
图14 SQL注入

12.4 数据库连接池

图19 1

【例题6】语句

package cn.zzh.ch03;


    }
}

返回