JDBC(一)——statement对象、PreparedStatement对象

1. 数据库驱动

驱动:声卡,显卡、数据库
在这里插入图片描述

我们的程序会通过 数据库 驱动,和数据库打交道!

2. JDBC

Java数据库连接(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。
这些规范的实现由具体的厂商去做
对于开发人员来说,我们只需要掌握 JDBC 接口的操作即可
在这里插入图片描述

3. 第一个JDBC程序

(1)SQLyog中创建测试数据库

CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci; 
USE jdbcStudy; 
CREATE TABLE users( 
id INT PRIMARY KEY, 
NAME VARCHAR(40), 
PASSWORD VARCHAR(40), 
email VARCHAR(60), 
birthday DATE 
);

INSERT INTO users(id,NAME,PASSWORD,email,birthday) 
VALUES(1,'zhansan','123456','[email protected]','1980-12-04'), 
(2,'lisi','123456','[email protected]','1981-12-04'), 
(3,'wangwu','123456','[email protected]','1979-12-04');

在这里插入图片描述
(2)IDEA中创建项目
①创建一个普通项目
②导入数据库驱动
在这里插入图片描述
③编写测试代码

package com.kuang.lesson01;

import java.sql.*;

// 我的第一个JDBC程序
public class JdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1. 加载驱动
        // DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        Class.forName("com.mysql.jdbc.Driver"); // 固定写法,加载驱动

        //2. 用户信息和url
        // useUnicode=true&characterEncoding=utf8&useSSL=true
        String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username = "root";
        String password = "123456";
        //3. 连接成功,数据库对象  Connection 代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //4. 执行SQL的对象 Statement 执行sql的对象
        Statement statement = connection.createStatement();

        //5. 执行SQL的对象 去 执行SQL,可能存在结果,查看返回结果
        String sql = "SELECT * FROM users";

        ResultSet resultSet = statement.executeQuery(sql); //返回的结果集,结果集中封装了我们全部的查询出来的结果

        while (resultSet.next()){
            System.out.println("id=" + resultSet.getObject("id"));
            System.out.println("name=" + resultSet.getObject("NAME"));
            System.out.println("pwd=" + resultSet.getObject("PASSWORD"));
            System.out.println("email=" + resultSet.getObject("email"));
            System.out.println("birth=" + resultSet.getObject("birthday"));
            System.out.println("==================================");
        }

        //6、释放连接
        resultSet.close();
        statement.close();
        connection.close();

    }
}

  • 运行结果
    在这里插入图片描述

  • 步骤总结
    ①加载驱动
    ②连接数据库 DriverManager
    ③获得执行sql的对象 Statement
    ④获得返回的结果集
    ⑤释放连接

  • DriverManager

// DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 
Class.forName("com.mysql.jdbc.Driver"); // 固定写法,加载驱动 
Connection connection = DriverManager.getConnection(url, username, password); // connection 代表数据库 
// 数据库设置自动提交 
// 事务提交 
// 事务滚回 
connection.rollback(); 
connection.commit(); 
connection.setAutoCommit();
  • URL
String url = "jdbc:mysql://localhost:3306/jdbcstudy?
 useUnicode=true&characterEncoding=utf8&useSSL=true"; // mysql -- 3306 
// 协议 :
//主机地址:端口号/数据库名?参数1&参数2&参数3 
// oralce -- 1521 //jdbc:oracle:thin:@localhost:1521:sid
  • Statement 执行SQL 的对象 PrepareStatement 执行SQL 的对象
String sql = "SELECT * FROM users"; // 编写SQL 

statement.executeQuery(); //查询操作返回 ResultSet 
statement.execute(); // 执行任何SQL 
statement.executeUpdate(); // 更新、插入、删除。都是用这个,返回一个受影响的行数 
  • ResultSet 查询的结果集:封装了所有的查询结果
    获得指定的数据类型
resultSet.getObject(); // 在不知道列类型的情况下使用 
// 如果知道列的类型就使用指定的类型 
resultSet.getString();
resultSet.getInt(); 
resultSet.getFloat(); 
resultSet.getDate(); 
resultSet.getObject(); 
.... 

遍历,指针

resultSet.beforeFirst(); // 移动到最前面
resultSet.afterLast(); // 移动到最后面
resultSet.next(); //移动到下一个数据 
resultSet.previous(); //移动到前一行 
resultSet.absolute(row); //移动到指定行 
  • 释放资源
//6、释放连接 
resultSet.close(); 
statement.close(); 
connection.close(); // 耗资源,用完关掉! 

4. statement对象

4.1 简述

  • Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
  • Statement对象的executeUpdate方法,用于向数据库发送增、删、改的语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。
  • Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。

4.2 CRUD操作

  • CRUD是指在做计算处理时的增加(Create)读取(Read)更新(Update)删除(Delete) 几个单词的首字母简写。CRUD主要被用在描述软件系统中数据库的基本操作功能。

(1)CRUD操作-create
使用executeUpdate(String sql)方法完成数据添加操作,示例操作:

Statement st = conn.createStatement(); 
String sql = "insert into user(….) values(…..) "; 
int num = st.executeUpdate(sql); 
if(num>0){ System.out.println("插入成功!!!");
 } 

(2)CRUD操作-read
使用executeQuery(String sql)方法完成数据查询操作,示例操作:

Statement st = conn.createStatement(); 
String sql = "select * from user where id=1"; 
ResultSet rs = st.executeQuery(sql); 
while(rs.next()){ 
//根据获取列的数据类型,分别调用rs的相应方法映射到java对象中 
} 

(3)CRUD操作-update
使用executeUpdate(String sql)方法完成数据修改操作,示例操作:

Statement st = conn.createStatement(); 
String sql = "update user set name='' where name=''"; 
int num = st.executeUpdate(sql); 
if(num>0){ 
System.out.println(“修改成功!!!"); 
}

(4)CRUD操作-delete
使用executeUpdate(String sql)方法完成数据删除操作,示例操作:

Statement st = conn.createStatement(); 
String sql = "delete from user where id=1"; 
int num = st.executeUpdate(sql); 
if(num>0){ 
System.out.println(“删除成功!!!"); 
} 

4.3 代码实现

(1)在 src 下建立资源文件 db.properties
在这里插入图片描述
(2)提取工具类

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {

    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    static {
        try{
            InputStream in =  JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);

            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            //1.驱动只用加载一次
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }


    //释放连接资源
    public static void release(Connection conn, Statement st, ResultSet rs){
        if (rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

(3)编写增删改的方法, executeUpdate

  • TestInsert(增)
import com.kuang.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestInsert {
    public static void main(String[] args) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

            try {
                conn = JdbcUtils.getConnection(); //获取数据库连接
                st = conn.createStatement(); //获得SQL的执行对象

                String sql = "INSERT INTO users(id,`NAME`,`PASSWORD`,`email`,`birthday`)" +
                        "VALUES(4,'dalao','123456','[email protected]','2020-01-01')";

                int i = st.executeUpdate(sql);
                if (i>0){
                    System.out.println("插入成功!");
                }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }

    }
}

在这里插入图片描述

  • TestDelete(删)
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDelete {
    public static void main(String[] args) {

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection(); //获取数据库连接
            st = conn.createStatement(); //获得SQL的执行对象

            String sql = "DELETE FROM users WHERE id = 2";

            int i = st.executeUpdate(sql);
            if (i>0){
                System.out.println("删除成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }

    }
}

在这里插入图片描述

  • TestUpdate(改)
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestUpdate {
    public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection(); //获取数据库连接
            st = conn.createStatement(); //获得SQL的执行对象

            String sql = "UPDATE users SET `NAME`='xiaohua',`email`='[email protected]' WHERE id=1";

            int i = st.executeUpdate(sql);
            if (i>0){
                System.out.println("更新成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }

    }
}

在这里插入图片描述
(3)查询 executeQuery

  • TestSelect(查)
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestSelect {
    public static void main(String[] args) {
        Connection conn =null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();

            //SQL
            String sql = "select * from users where id = 1";

            rs = st.executeQuery(sql); //查询完毕会返回一个结果集
            while (rs.next()){
                System.out.println(rs.getString("NAME"));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

在这里插入图片描述
在这里插入图片描述
(4)SQL 注入的问题
sql 存在漏洞,会被攻击导致数据泄露SQL会被拼接 or

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

public class SQL注入 {
    public static void main(String[] args) {

        // login("kuangshen","123456");
        login(" 'or '1=1"," 'or'1=1"); // 技巧
    }

    // 登录业务
    public static void login(String username,String password){

        Connection conn =null;
        Statement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();

            // SELECT * FROM users WHERE `Name` = 'kuangshen' AND `password` = '123456';

            // SELECT * FROM users WHERE `Name` = '' or '1=1' AND `password` = '' or '1=1';
            String sql = "select * from users where `NAME`='"+username+"' AND `password` ='"+password+"'";

            rs = st.executeQuery(sql); //查询完毕会返回一个结果集
            while (rs.next()){
                System.out.println(rs.getString("NAME"));
                System.out.println(rs.getString("password"));
                System.out.println("============================");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

在这里插入图片描述

5. PreparedStatement对象

PreparedStatement 可以防止SQL注入,效率更好!
(1)新增

import java.sql.Connection;
import java.util.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestInsert {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils.getConnection();
            // 区别
            // 使用? 占位符代替参数
            String sql = "insert into users(id,`NAME`,`PASSWORD`,`email`,`birthday`) values(?,?,?,?,?)";

            st = conn.prepareStatement(sql); //预编译SQL,先写sql,然后不执行

            // 手动给参数赋值
            st.setInt(1,4); //id
            st.setString(2,"xiaopang");
            st.setString(3,"1232112");
            st.setString(4,"[email protected]");
            // 注意点: sql.Date   数据库   java.sql.Date()
            //          util.Date  Java     new Date().getTime() 获得时间戳
            st.setDate(5,new java.sql.Date(new Date().getTime()));

            //执行
            int i = st.executeUpdate();
            if (i>0){
                System.out.println("插入成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,null);
        }
    }
}

在这里插入图片描述
(2)删除

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestDelete {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils.getConnection();
            // 区别
            // 使用? 占位符代替参数
            String sql = "delete from users where id=?";

            st = conn.prepareStatement(sql); //预编译SQL,先写sql,然后不执行

            // 手动给参数赋值
            st.setInt(1,4);

            //执行
            int i = st.executeUpdate();
            if (i>0){
                System.out.println("删除成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,null);
        }
    }
}

在这里插入图片描述
(3)更新

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestUpdate {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = JdbcUtils.getConnection();
            // 区别
            // 使用? 占位符代替参数
            String sql = "update users set `NAME`=?  where id=?;";

            st = conn.prepareStatement(sql); //预编译SQL,先写sql,然后不执行

            // 手动给参数赋值
           st.setString(1,"xiaohuang");
           st.setInt(2,1);

            //执行
            int i = st.executeUpdate();
            if (i>0){
                System.out.println("更新成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,null);
        }

    }
}

在这里插入图片描述
(4)查询

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestSelect {
    public static void main(String[] args) {

        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();

            String sql = "select * from users where id = ?"; // 编写SQL

            st = conn.prepareStatement(sql); // 预编译

            st.setInt(1,2); //传递参数

            rs = st.executeQuery(); //执行

            if (rs.next()){
                System.out.println(rs.getString("NAME"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

在这里插入图片描述
(5)防止SQL注入

import java.sql.*;
public class SQL注入 {
    public static void main(String[] args) {
        // login("lisi","123456");
        login("'' or 1=1","123456"); //
    }

    // 登录业务
    public static void login(String username,String password){

        Connection conn =null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            // PreparedStatement 防止SQL注入的本质,把传递进来的参数当做字符
            // 假设其中存在转义字符,比如说 ' 会被直接转义
            String sql = "select * from users where `NAME`=? and `PASSWORD`=?"; // Mybatis

            st = conn.prepareStatement(sql);
            st.setString(1,username);
            st.setString(2,password);
            
            rs = st.executeQuery(); //查询完毕会返回一个结果集
            while (rs.next()){
                System.out.println(rs.getString("NAME"));
                System.out.println(rs.getString("password"));
                System.out.println("============================");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

如下所示 查询不到数据在这里插入图片描述

发布了62 篇原创文章 · 获赞 2 · 访问量 2736

猜你喜欢

转载自blog.csdn.net/nzzynl95_/article/details/104090262