Java Jdbc的详解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Java Jdbc的详解

一、Jdbc原理示意图

二、Jdbc的概述

三、JDBC的快速入门

代码如下,具体讲解在注释中已经说明

public class Jdbc01 {
    public static void main(String[] args) throws SQLException {
        //前置工作:在项目下创建一个文件夹比如libs
        //将mysql.jar拷贝到该目录下,点击add to project ..加入到项目
        //1.注册驱动
        Driver driver = new Driver();//创建Driver对象
        //2.得到连接
        //解读
        //1.jdbc:mysql:// 规定好的协议,通过jdbc的方式连接mysql
        //2.localhost 主机,可以是ip地址
        //3.3306 表示sql监听的端口
        //4.db_ly 连接到mysql dbms的哪个数据库
        //5.mysql的连接本质就是socket连接
        String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
        //将用户名和密码放入到Properties对象
        Properties properties = new Properties();
        //说明 user 和 password 是规定好的,后面的值根据实际情况写
        properties.setProperty("user", "root");//用户
        properties.setProperty("password", "123456");//密码
        Connection connect = driver.connect(url, properties);
        //3.执行sql
//        String sql = "insert into actor values(null,'刘德华','男','1970-01-01','110')" +
//                ",(null,'周星驰','男','1980-01-03','123456789')";
        String sql = "update actor set name='王宝强' where id = 3";
//        String sql = "delete from actor where id =1";
        //statement:用于执行静态的sql语句并返回其生成的结果对象
        Statement statement = connect.createStatement();
        //如果是dml语句,返回的就是影响行数
        int rows = statement.executeUpdate(sql);
        System.out.println(rows);
        System.out.println(rows > 0 ? "成功" : "失败");
        //4.关闭连接资源
        statement.close();
        connect.close();
    }
}

输出结果如下

成功

四、Java操作数据库需要获得Connection连接,获取Connection连接的五种方式如下

public class JdbcConn {
    //方式1
    @Test
    public void connect01() throws SQLException {
        //1.注册驱动
        Driver driver = new Driver();//创建Driver对象
        String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
        //将用户名和密码放入到Properties对象
        Properties properties = new Properties();
        //说明 user 和 password 是规定好的,后面的值根据实际情况写
        properties.setProperty("user", "root");//用户
        properties.setProperty("password", "123456");//密码
        Connection connect = driver.connect(url, properties);
        System.out.println(connect);
    }
    //方式2
    @Test
    public void connect02() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException {
        //使用反射获取Driver类,动态加载,更加的灵活,减少依赖性
        Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
        Driver driver = (Driver) aClass.newInstance();
        String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
        //将用户名和密码放入到Properties对象
        Properties properties = new Properties();
        //说明 user 和 password 是规定好的,后面的值根据实际情况写
        properties.setProperty("user", "root");//用户
        properties.setProperty("password", "123456");//密码
        Connection connect = driver.connect(url, properties);
        System.out.println(connect);
    }
    //方法3 使用DriverManager 替代driver 进行统一管理
    @Test
    public void connect03() throws IllegalAccessException, InstantiationException, ClassNotFoundException, SQLException {
        Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
        Driver driver = (Driver) aClass.newInstance();
        //创建url和user的password
        String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
        String user = "root";
        String password = "123456";
        //注册driver驱动
        DriverManager.registerDriver(driver);
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println("第三种方式:" + connection);
    }
    //方式4:使用Class.forName() 自动完成注册驱动,简化代码
    //这种方式获取连接是使用的最多的,推荐使用
    @Test
    public void connect04() throws ClassNotFoundException, SQLException {
        //使用反射加载了Driver类
        //在加载Driver类时,完成注册
        /*
            源码:1.静态代码块,在类加载时,会执行一次
                 2. DriverManager.registerDriver(new Driver());
                 3.因此注册driver的工作已经完成
            static {
                try {
                    DriverManager.registerDriver(new Driver());
                } catch (SQLException var1) {
                    throw new RuntimeException("Can't register driver!");
                }
            }
         */
        Class.forName("com.mysql.cj.jdbc.Driver");
        //创建url和user的password
        String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
        String user = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println("第四种方式:" + connection);
    }
    //方式5:在方式4的基础上改进,增加配置文件,让连接mysql更加灵活
    @Test
    public void connect05() throws IOException, ClassNotFoundException, SQLException {
        //通过Properties,获取相关配置文件的信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        //获取相关的值
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println("第五种方式:" + connection);
    }
}

输出结果

com.mysql.cj.jdbc.ConnectionImpl@1a38c59b
com.mysql.cj.jdbc.ConnectionImpl@1a38c59b
第三种方式:com.mysql.cj.jdbc.ConnectionImpl@7f77e91b
第四种方式:com.mysql.cj.jdbc.ConnectionImpl@1a38c59b
第五种方式:com.mysql.cj.jdbc.ConnectionImpl@1a38c59b

四、ResultSet的详解

对应的代码如下

@SuppressWarnings({"all"})
public class ResultSet_ {
    public static void main(String[] args) throws Exception {
        //通过Properties配置相关信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        //获取相关的值
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");
        //1.注册驱动
        Class.forName(driver);
        //建立与给定数据库的url连接
        //2.建立连接
        Connection connection = DriverManager.getConnection(url, user, password);
        //3.得到Statement
        Statement statement = connection.createStatement();
        //4.组织sql
        String sql = "SELECT id,name,sex,borndate,phone FROM ACTOR";
        //执行给定的SQL语句,该语句返回单个 ResultSet对象。
        /*
        +----+--------+-----+---------------------+-----------+
        | id | NAME   | sex | borndate            | phone     |
        +----+--------+-----+---------------------+-----------+
        |  1 | 刘德华 | 男  | 1970-01-01 00:00:00 | 110       |
        |  2 | 王宝强 | 男  | 1980-01-03 00:00:00 | 123456789 |
        +----+--------+-----+---------------------+-----------+
         */
        /*
            resultSet对象的结构,debug进行阅读
            查询到的数据,底层使用byte[] 数组存的,比如id =1  存放的1对应的ASCII码49
         */
        ResultSet resultSet = statement.executeQuery(sql);
        //5.使用while取出数据
        while (resultSet.next()) {//让光标向后移动,如果没有更多行,则返回false
           // int id = resultSet.getInt(1);//获取该行的第一列数据
            int id = resultSet.getInt("id");//通过列名来获取值,推荐使用
            String name = resultSet.getString(2);//获取该行第二列
            String sex = resultSet.getString(3);//获取该行第三列
            Date date = resultSet.getDate(4);//获取该行第四列
            String phone = resultSet.getString(5);//获取该行第五列
            System.out.println(id + "\t" + name + "\t" + sex + "\t" + date + "\t" + phone);
        }
        //6.关闭连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

输出结果

1 刘德华 男 1970-01-01  110
2 王宝强 男 1980-01-03  123456789

resultSet对象的结构如下

Statement的介绍

使用Statement会存在SQL注入的风险,所以开发中一般使用PreparedStatement。

SQL注入演示:

CREATE TABLE ADMIN(
NAME VARCHAR(32) NOT NULL UNIQUE,
pwd VARCHAR(32) NOT NULL DEFAULT ''
);
INSERT INTO ADMIN VALUES('jack','123456');
SELECT * FROM ADMIN WHERE NAME='jack' AND pwd = '12456';
-- name 输入 1'or 
-- pwd 输入or '1'='1
-- 条件'1'='1' 永远成立 能查到数据库中的数据,JAVA程序在拼接的时候就发生了SQL注入
SELECT * FROM ADMIN 
WHERE NAME='1'or' AND pwd = 'or '1'='1';

下面演示使用Statement会发生SQL注入的风险

public class Statement_ {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        //让用户输入管理员名和密码
        System.out.println("请输入管理员的名字:");//next():当接收到空格或者 '就是表示结束
        String admin_name = scanner.nextLine();//如果希望看到SQL注入效果,这里需要nextLine() 这个回车才表示结束
        System.out.println("请输入管理员的密码:");
        String admin_pwd = scanner.nextLine();
        //通过Properties配置相关信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        //获取相关的值
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");
        //1.注册驱动
        Class.forName(driver);
        //建立与给定数据库的url连接
        //2.建立连接
        Connection connection = DriverManager.getConnection(url, user, password);
        //3.得到Statement
        Statement statement = connection.createStatement();
        //4.组织sql
        String sql = "SELECT NAME,pwd FROM ADMIN WHERE NAME='" + admin_name + "' AND pwd= '" + admin_pwd + "'";
        ResultSet resultSet = statement.executeQuery(sql);
        if (resultSet.next()) {//如果查询到一条记录,则说明该管理存在
            System.out.println("恭喜登录成功!");
        } else {
            System.out.println("登录失败!");
        }
        //关闭连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

输出结果如下

请输入管理员的名字:
1'or
请输入管理员的密码:
or '1'='1
恭喜登录成功!

五、PrepareStatement的介绍与使用

PrepareStatement的好处

1、下面是演示代码,解决了SQL注入的问题

public class PrepareStatement_ {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        //让用户输入管理员名和密码
        System.out.println("请输入管理员的名字:");//next():当接收到空格或者 '就是表示结束
        String admin_name = scanner.nextLine();//如果希望看到SQL注入效果,这里需要nextLine() 这个回车才表示结束
        System.out.println("请输入管理员的密码:");
        String admin_pwd = scanner.nextLine();
        //通过Properties配置相关信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        //获取相关的值
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");
        //1.注册驱动
        Class.forName(driver);
        //建立与给定数据库的url连接
        //2.建立连接
        Connection connection = DriverManager.getConnection(url, user, password);
        //3.组织sql语句,sql语句的? 就相当于占位符
        String sql = "SELECT name,pwd FROM ADMIN WHERE name=? AND pwd=?";
        //4.得到preparedStatement
        //preparedStatement对象是实现了PreparedStatement接口的实现类对象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //给?赋值
        preparedStatement.setString(1, admin_name);
        preparedStatement.setString(2, admin_pwd);
        //执行select语句,使用executeQuery()
        //如果执行的是dml(update,insert,delete) 使用executeUpdate()
        //这里执行executeQuery,不要写sql
        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) {//如果查询到一条记录,则说明该管理存在
            System.out.println("登录成功!");
        } else {
            System.out.println("登录失败!");
        }
        //关闭连接
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}

输出结果

请输入管理员的名字:
1 'or 
请输入管理员的密码:
or '1'='1
登录失败!

2、使用PrepareStatement进行DML操作

public class PrepareStatement_DML {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        //让用户输入管理员名和密码
        System.out.println("请输入要删除的管理员的名字:");//next():当接收到空格或者 '就是表示结束
        String admin_name = scanner.nextLine();//如果希望看到SQL注入效果,这里需要nextLine() 这个回车才表示结束
//        System.out.println("请输入管理员的密码:");
//        String admin_pwd = scanner.nextLine();
        //通过Properties配置相关信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        //获取相关的值
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String driver = properties.getProperty("driver");
        //1.注册驱动
        Class.forName(driver);
        //建立与给定数据库的url连接
        //2.建立连接
        Connection connection = DriverManager.getConnection(url, user, password);
        //3.组织sql语句,sql语句的? 就相当于占位符
        //添加记录
//        String sql = "insert into admin values(?,?)";
        //修改记录
//        String sql = "update admin set name=? where pwd=?";
        //删除记录
        String sql = "delete from admin where name=?";
        //4.得到preparedStatement
        //preparedStatement对象是实现了PreparedStatement接口的实现类对象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //给?赋值
        preparedStatement.setString(1, admin_name);
//        preparedStatement.setString(2, admin_pwd);
        //如果执行的是dml(update,insert,delete) 使用executeUpdate()
        int rows = preparedStatement.executeUpdate();
        System.out.println(rows > 0 ? "执行成功" : "执行失败");
        //关闭连接
        preparedStatement.close();
        connection.close();
    }
}

输出结果

请输入要删除的管理员的名字:
smith
执行成功


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6天前
|
SQL Java 数据库连接
java使用jdbc操作数据库
java使用jdbc操作数据库
|
6天前
|
SQL Java 关系型数据库
javaweb实训第四天上午——JDBC入门(2)
3.1.3 拿到连接(贾琏) 注册驱动成功之后,接着拿到链接;(贾琏是一个人名字) 贾:加载驱动; 链:建立连接;
54 0
|
6天前
|
SQL Java 数据库连接
Java一分钟之-JDBC:Java数据库连接基础
【5月更文挑战第14天】JDBC是Java与关系数据库交互的API,常见问题包括资源管理、SQL注入和性能优化。易错点涉及驱动加载、空指针异常和事务管理。避免这些问题的方法有使用try-with-resources自动关闭资源、预编译PreparedStatement以防止SQL注入,以及正确管理事务。示例代码展示了基本的JDBC连接和查询。在实际开发中,推荐使用ORM框架如Hibernate或JPA来简化数据库操作。
15 1
|
6天前
|
SQL Java 关系型数据库
零基础轻松入门Java数据库连接(JDBC)
零基础轻松入门Java数据库连接(JDBC)
13 0
|
6天前
|
SQL Java 数据库连接
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
12 0
|
6天前
|
Java 关系型数据库 MySQL
【JDBC编程】基于MySql的Java应用程序中访问数据库与交互数据的技术
【JDBC编程】基于MySql的Java应用程序中访问数据库与交互数据的技术
|
6天前
|
SQL Java 数据库连接
Java从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
ava从入门到精通:2.3.1数据库编程——学习JDBC技术,掌握Java与数据库的交互
|
6天前
|
SQL Java 数据库连接
使用JDBC进行数据库操作:Java Web开发的数据库连接
【4月更文挑战第3天】Java Web开发中,JDBC是与数据库交互的关键,提供统一访问关系型数据库的规范。核心组件包括DriverManager、Connection、Statement和ResultSet。使用流程涉及加载驱动、建立连接、创建Statement、执行SQL及处理结果,最后关闭资源。最佳实践包括使用try-with-resources、PreparedStatement、事务管理等。在Web开发中,JDBC用于用户认证、数据持久化、检索和事务管理。虽然有ORM工具,但掌握JDBC基础仍然重要。
|
6天前
|
SQL Java 数据库连接
Java的JDBC编程
Java的JDBC编程
|
6天前
|
SQL Java 关系型数据库
Java学习—JDBC
Java学习—JDBC