JDBC基础

本文深入讲解JDBC技术,包括其核心API、使用方法及不同类型的SQL执行策略,如Statement、PreparedStatement和CallableStatement的区别,以及如何通过类路径加载资源文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDBC入门


        1.1 回顾
            之前操作mysql数据库:
                    1)使用mysql客户端工具
                    2)使用客户端连接mysql服务器
                    3)发送sql语句到mysql服务器,执行
        1.2 什么是JDBC?
            使用java程序发送sql语句到数据库服务器端执行,这叫用到了JDBC技术!!!!
            jdbc是Oracle-Sun公司设计的一套专门用于java程序操作数据库的接口。
        1.3 使用jdbc发送sql条件
            连接mysql数据库:
                    数据库主机
                    端口
                    数据库用户名
                    数据库密码
                    连接的数据库
原理图

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

        1.4 JDBC的核心API
            |-Driver接口: 数据库驱动程序的接口,所有具体数据库厂商需要的驱动程序需要实现次接口。
                Connection connect(String url, Properties info)  用于获取数据库连接

            |-Connection接口:与具体的数据库的连接对象。
                    Statement createStatement()    创建一个静态sql语句对象
                    PreparedStatement prepareStatement(String sql)  创建预编译的sql语句对象
                    CallableStatement prepareCall(String sql)   创建存储过程的sql语句对象

            |-Statement接口:用于执行静态 SQL 语句
                    int executeUpdate(String sql)  执行更新操作的sql语句                                                                         (create/alter/drop/insert/update/delete)
                    ResultSet executeQuery(String sql)  执行查询操作的sql语句
                                                    (select)

                |- PreparedStatement接口:用于执行预编译的 SQL 语句(是Statement的子接口)
                    int executeUpdate()  执行更新操作的sql语句
                    ResultSet executeQuery()  执行查询操作的sql语句

                        |- CallableStatement接口:用于执行 SQL 存储过程的接口(是PreparedStatement的子                                                        接口)
                                ResultSet executeQuery()  执行存储过程的sql语句

            |- ResultSet接口:结果集对象。 存储所有数据库查询的结果,用该对象进行数据遍历。
                    boolean next() : 把光标移动到下一行。如果下一行有数据,返回true,如果没有下一行数                                 据,返回false。
                    getXXX(列索引|列字段名称): 获取字段的数据

2 Statement对象执行SQL操作
        2.1 执行DDL操作
/**
 * 通过jdbc执行DDL语句
 * @author APPle
 *
 */
public class Demo1 {
    //数据库的连接的URL
    private static String url = "jdbc:mysql://localhost:3306/day17";
    //数据库用户名
    private static String user = "root";
    //数据库密码
    private static String password = "root";

    public static void main(String[] args){
        Connection conn = null;
        Statement stmt = null;
        try {
            //1.驱动驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            //2.从驱动程序管理类获取连接
            conn = DriverManager.getConnection(url, user, password);
            //3.通过Connection对象获取Statement对象
            stmt = conn.createStatement();
            //4.准备sql语句
            String sql = "CREATE TABLE student(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),gender VARCHAR(2))";
            //5.执行sql语句,返回结果
            int count = stmt.executeUpdate(sql);

            System.out.println("影响了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //6.关闭资源(先关闭statement,再关闭connection)
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }
}

        2.2 执行DML操作

/**
 * 通过jdbc执行DML语句(insert/update/delete)
 * @author APPle
 *
 */
public class Demo2 {
    //数据库的连接的URL
    private static String url = "jdbc:mysql://localhost:3306/day17";
    //数据库用户名
    private static String user = "root";
    //数据库密码
    private static String password = "root";
    /**
     * 执行插入操作
     */
    @Test
    public void test1(){
        Connection conn = null;
        Statement stmt = null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            conn = DriverManager.getConnection(url, user, password);
            //创建Statment对象
            stmt = conn.createStatement();
            //准备sql
            String sql = "INSERT INTO student(NAME,gender) VALUES('张三','男')";
            //执行sql,返回结果
            int count = stmt.executeUpdate(sql);
            System.out.println("影响了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //关闭资源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }

    /**
     * 执行更新操作
     */
    @Test
    public void test2(){
        Connection conn = null;
        Statement stmt = null;
        //声明外部变量
        String name = "陈六";
        int id=2;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            conn = DriverManager.getConnection(url, user, password);
            //创建Statment对象
            stmt = conn.createStatement();
            //准备sql
            String sql = "UPDATE student SET NAME='"+name+"' WHERE id="+id+""; //变量和String拼接sql
            //执行sql,返回结果
            int count = stmt.executeUpdate(sql);
            System.out.println("影响了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //关闭资源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }

    /**
     * 执行删除操作
     */
    @Test
    public void test3(){
        Connection conn = null;
        Statement stmt = null;
        //声明外部变量
        int id=2;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            conn = DriverManager.getConnection(url, user, password);
            //创建Statment对象
            stmt = conn.createStatement();
            //准备sql
            String sql = "DELETE FROM student WHERE id="+id+""; //变量和String拼接sql
            //执行sql,返回结果
            int count = stmt.executeUpdate(sql);
            System.out.println("影响了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //关闭资源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }
}

        2.3 执行DQL查询操作
/**
 * 使用jdbc执行DQL语句(select)
 * @author APPle
 *
 */
public class Demo3 {
    //数据库的连接的URL
    private static String url = "jdbc:mysql://localhost:3306/day17";
    //数据库用户名
    private static String user = "root";
    //数据库密码
    private static String password = "root";

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            conn = DriverManager.getConnection(url, user, password);
            //创建Statement对象
            stmt = conn.createStatement();
            //准备sql
            String sql = "SELECT * FROM student";

            rs = stmt.executeQuery(sql);

            //移动光标到下一行
            //rs.next();
            /**
             * 注意:
             *   1)如果光标在第一行之前,使用rs.getXX()获取列值,报错:Before start of result set
             *   2)如果光标在最后一行之后,使用rs.getXX()获取列值,报错:After end of result set
             */

            //获取列值
            /*if(rs.next()){
                //使用列索引

                int id = rs.getInt(1);
                String name = rs.getString(2);
                String gender = rs.getString(3);

                //使用列名称
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+name+"\t"+gender+"\t");
            }*/

            //迭代结果集
            while(rs.next()){
                //使用列索引
                /*
                int id = rs.getInt(1);
                String name = rs.getString(2);
                String gender = rs.getString(3);
                */
                //使用列名称
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+name+"\t"+gender+"\t");
            }


        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            if(rs!=null)
                try {
                    rs.close();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                    throw new RuntimeException(e1);
                }
            //关闭资源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }

    }
}

3 PreparedStatement对象执行SQL操作
/**
 * 使用PreparedStatement执行sql语句
 * @author APPle
 *
 */
public class Demo1 {

    /**
     * 插入操作
     */
    @Test
    public void test1(){
        Connection conn = null;
        PreparedStatement stmt = null;
        try{
            //获取连接
            conn = JdbcUtil.getConnection();
            String sql = "INSERT INTO student(NAME,gender) VALUES(?,?)"; //预编译sql:使用?号代替参数值。一个?号代表一个参数值
            //创建PreparedStatement对象,执行预编译的sql语句
            stmt = conn.prepareStatement(sql);
            //设置参数
            /**
             * 参数一: 参数位置。从1开始
             * 参数二: 参数实际值
             * 注意: 所有参数必须要赋值
             */
            stmt.setString(1, "rose");
            stmt.setString(2, "女");
            //发送参数,执行sql语句
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //关闭资源
            JdbcUtil.close(conn, stmt, null);
        }
    }

    /**
     * 修改操作
     */
    @Test
    public void test2(){
        Connection conn = null;
        PreparedStatement stmt = null;
        //声明变量
        String name = "jacky";
        int id = 8;
        try{
            //获取连接
            conn = JdbcUtil.getConnection();
            String sql = "UPDATE student SET NAME=? WHERE id=?"; //预编译sql:使用?号代替参数值。一个?号代表一个参数值
            //创建PreparedStatement对象,执行预编译的sql语句
            stmt = conn.prepareStatement(sql);
            //设置参数
            stmt.setString(1,name);
            stmt.setInt(2, id);
            //发送参数,执行sql语句
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //关闭资源
            JdbcUtil.close(conn, stmt, null);
        }
    }

    /**
     * 删除操作
     */
    @Test
    public void test3(){
        Connection conn = null;
        PreparedStatement stmt = null;
        //声明变量
        int id = 8;
        try{
            //获取连接
            conn = JdbcUtil.getConnection();
            String sql = "DELETE FROM student WHERE id=?"; //预编译sql:使用?号代替参数值。一个?号代表一个参数值
            //创建PreparedStatement对象,执行预编译的sql语句
            stmt = conn.prepareStatement(sql);
            //设置参数
            //任何类型都可以使用setObject进行赋值
            stmt.setObject(1, id);
            //发送参数,执行sql语句
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //关闭资源
            JdbcUtil.close(conn, stmt, null);
        }
    }

    /**
     * 查询操作
     */
    @Test
    public void test4(){
        Connection conn = null;
        PreparedStatement stmt = null;
        //声明变量
        String name = "张%";
        try{
            //获取连接
            conn = JdbcUtil.getConnection();
            String sql = "SELECT * FROM student WHERE NAME LIKE ?";
            //创建PreparedStatement,预编译sql语句
            stmt = conn.prepareStatement(sql);
            //设置参数
            stmt.setObject(1, name);
            //发送参数,执行sql,返回结果集
            ResultSet rs = stmt.executeQuery();
            //遍历结果集
            while(rs.next()){
                int id = rs.getInt("id");
                String nameStr = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+nameStr+"\t"+gender+"\t");
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //关闭资源
            JdbcUtil.close(conn, stmt, null);
        }
    }

}

        ==============Statement和PreparedStatement的区别==========================================
    一、语法结构不同
            1)Statment执行静态sql语句,且sql可以拼接。
            2)PreparedStatement可以先执行预编译的sql语句,在预编译sql语句中使用?进行参数占位,后面                    在进行参数赋值
    二、原理不同
            1)Statement不能进行sql缓存
            2)而PreparedStatement可以进行sql缓存,执行效率会比Statement快!!!

    三、安全性不同
            1)Statement存在sql注入的风险
            2)而PreparedStatement可以有效防止用户注入。

4 CallableStatement对象执行存储过程
        4.1 执行带输入参数的存储过程
/**
     * 执行带有输入参数存储过程
     */
    @Test
    public void test1(){
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try{
            //获取连接
            conn = JdbcUtil.getConnection();
            //创建CallableStatement对象
            String sql = "CALL pro_findById(?)";//预编译sql、可以带?号
            //执行预编译的sql
            stmt = conn.prepareCall(sql);
            //设置参数
            stmt.setInt(1, 4);
            //发送参数,执行sql,返回结果
            rs = stmt.executeQuery();// 注意: 执行存储过程必须使用exeuteQuery!!!!
            //遍历结果
            while(rs.next()){
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+name+"\t"+gender+"\t");
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //关闭资源
            JdbcUtil.close(conn, stmt, rs);
        }
    }

        4.2 执行带有输出参数的存储过程
/**
     * 执行带有输出参数存储过程
     */
    @Test
    public void test2(){
        Connection conn = null;
        CallableStatement stmt = null;
        try{
            //获取连接
            conn = JdbcUtil.getConnection();
            String sql = "CALL pro_findById2(?,?)"; // 第一个参数时输入参数,第二个参数是输出参数
            //创建CallableStatement对象
            stmt = conn.prepareCall(sql);
            //设置输入参数
            stmt.setObject(1, 4);
            //注册一个输出参数
            /**
             * 参数一: 参数位置
             * 参数二: 表示存储过程中的OUT参数的数据库类型
             */
            stmt.registerOutParameter(2, java.sql.Types.VARCHAR);

            //发送参数,执行存储过程
            stmt.executeQuery();

            /**
             * 如何获取存储过程的返回值:OUT参数值。使用getXXX方法
             */
            String name = stmt.getString(2);//和预编译语句中的参数位置保持一致!!!!
            System.out.println("结果:"+name);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //关闭资源
            JdbcUtil.close(conn, stmt, null);
        }
    }

5 使用类路径加载资源文件

/**
             * 使用类路径的方式加载db.properties文件
             */
            //1.得到字节码对象
            Class clazz = JdbcUtil.class;
            //2.通过方法加载文件,使用类路径方式
            // / : 表示类路径的根目录(放class字节码文件目录)
                  // java项目: bin目录下
                  // web项目: WEB-INF/classes目录下
            InputStream in = clazz.getResourceAsStream("/db.properties"); // 从类路径的根目录下开始找
            //InputStream in = clazz.getResourceAsStream("db.properties"); // 文件和当前类处于同一个目录
            prop.load(in);

         Class.getResourceAsStream("/db.properties");  
         Class.getResourceAsStream("db.properties");  

        这里的 斜杠 / 表示当前项目的类路径的根目录。
            当前项目是java项目,/ 在项目的bin目录下
            当前项目是web项目,/在项目的WEB-INF/classes目录下

            注意: 无论是java项目还是web项目,在开发时如果把资源文件放在src下,那么src下的文件都会拷贝到类路径的根目录下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值