JDBC —— 数据库连接

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: JDBC —— 数据库连接


文章目录

JDBC介绍

JDBC全称为Java Database Connectivity,直译过来就是Java数据库连接。它由一组用Java语言编写的类和接口组成。各种不同类型的数据库都有相应的实现。我们要连接数据库,就要去相应的数据库官网下载驱动,驱动都是以jar包的形式存在,jar包当中有很多.class文件,这些class文件就是JDBC接口的实现。本文针对MySQL数据库的连接实现。

JDBC六部曲

  1. 注册驱动(作用:告诉Java程序,即将要连接的是哪个品牌数据库)。
  2. 获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后要关闭通道)
  3. 获取数据库操作对象(专门执行sql语句的对象)。
  4. 执行sql语句。
  5. 处理查询结果集(只有第五步进行的是select语句的时候,才会到这一步)。
  6. 释放资源(使用完资源后一定要关闭资源)。

数据库连接完整代码如下:

import java.sql.*;
public class JDBCTest06 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement state = null;
        Driver driver = null;
        ResultSet rs = null;
        try {
            /*
            注册驱动
            在此处,Driver类型的对象driver和后面的com.mysql.cj.jdbc.Driver()并不是一个,它们是不同包下的。
             */
            driver = new com.mysql.cj.jdbc.Driver();
            DriverManager.registerDriver(driver);
            /*
            第二步:获取连接
            这里的url是由以下部分组成的:
            协议:jdbc:mysql://
            数据库服务端ip地址:因为这里使用的是本机,所以写的是localhost
            数据库端口号:MySQL的专用端口号:3306
            数据库账号:root
            密码:111111
             */
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study2","root","111111");
            //获取数据库操作对象
            state = conn.createStatement();
            /*
            执行sql语句
            若执行DML语句(update,insert,delete),写法如下:
            state.executeUpdate("insert into user (id,name) value ("1", "张三")");
            下面演示的是执行DQL语句(select)
             */
            rs = state.executeQuery("select *from user");
            /*
            处理查询结果
            如果rs中还有没有访问的记录,next()方法则会返回true
            如果访问的字段是varChar类型,则使用getString(),若访问字段是int类型,则使用getInt(),若访问字段是bigint,则使用getDouble(),其余同理。
            注意这里getStrng()以及同类型方法的传参,可以传一个字段名,也可以传要查询字段的下标(从1开始)
            */
            while(rs.next()){
                System.out.println(rs.getString(1) + "   " + rs.getString(2));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //释放资源,要从小到大释放
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(state != null){
                try {
                    state.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

在注册驱动时,我们现在并不会这样写,因为com.mysql.cj.jdbc.Driver类的源码中有如下静态代码块:

SQL注入

我们在这里简单的利用数据库实现一个账号的登录。

public static boolean Login(String loginName, String passWord){
        Connection conn = null;
        Statement state = null;
        ResultSet st = null;
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost/study2","root","111111");
            //获取数据库操作对象
            state = conn.createStatement();
            //执行查询语句
            st = state.executeQuery("select *from login where loginName ='" + loginName + "'and  loginPwd = '" + passWord + "'");
            if(st.next()){
                return true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if (state != null) {
                try {
                    state.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                ;
            }
        }
        return false;
    }

在这里我们借助了SQL语句的拼接来实现了一个账号登录功能,其中loginName,和passWordd都是由用户来输入的。如果用户正常输入,例如:输入loginName为’‘111’‘,输入passWord为’‘12345678’',拼接之后的SQL语句如下:

select * form login where loginName = '111' and passWord = '12345678'

只要用户输入的名字和密码是正确的,就会有查询结果,登录成功。

如果用户在输入时输入了带有sql关键字的’非法信息’并且该非法信息串改了sql语句的原先的含义,导致未输入正确的信息也同样登录成功,例如:输入loginName为’‘111’',输入passWord为 ‘‘1' or ' 1' = '1’’,拼接之后的SQL语句如下:

select * from login where loginName = '111' and passWord = '1' or '1' = '1';

用户如果这样输入就改变的SQL语句的原意,导致在不知道账号密码的情况下仍然登录成功,这就是SQL注入

PerparedStatement

上面使用Statement对象执行sql语句会造成SQL注入问题,Statement的子类PreparedStatement对象可以预编译SQL语句,从而避免了这种问题。

使用PreparedStatement来实现一个简单的登入如下:

public static boolean login(String loginName, String passWord){
        ResultSet rs = null;
        Connection conn = null;
        //预编译的数据库操作对象
        PreparedStatement ps = null;
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //连接数据库
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study2","root","111111");
            //获取预编译的数据库操作对象
            ps = conn.prepareStatement("select * from login where loginName = ? and loginPwd = ?");
            //给占位符传值
            ps.setString(1,map.get("loginName"));
            ps.setString(2,map.get("passWord"));
            //执行sql语句
            rs = ps.executeQuery();
            //处理查询结果
            if(rs.next()){
                return true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            if(ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

在该方法中我们通过调用数据库连接对象的prepareStatement(sql)方法获取的是预编译的数据库操作对象,在获取预编译的数据库操作对象时需要传入SQL语句的框子,其中它用占位符?来代替sql语句要接收的值。然后我们再用setString(int parameterIndex, String x) 方法给占位符‘ ?’传值。

Statement 与 PreparedStatement比较

  1. Statement存在sql注入问题,PreparedStatement不存在sql注入问题。
  2. Statement每一次执行都需要对sql语句进行编译一次,效率较低,PreparedStatement只需要编译一次就可以执行N次,效率较高。
  3. PreparedStatement会在编译阶段做类型检查,但是Statement不会。
  4. PreparedStatement并不支持sql语句的拼接,Statement更加灵活。

JDBC的事务机制

  1. JDBC中事务是自动提交的。只要执行一个DML语句,则会自动提交一次。
  2. 若conn为数据库连接对象,调用以下方法可以进行相关事务操作。
//关闭自动提交
  conn.setAutoCommit(false);
  //回滚事务
  conn.rollback();
  //提交事务
  conn.commit();


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
Java 关系型数据库 数据库连接
JDBC:Java与数据库的“黄金搭档”,为何它如此重要?
JDBC:Java与数据库的“黄金搭档”,为何它如此重要?
53 8
|
4月前
|
Java 数据库连接 API
JDBC:Java数据库连接的“黑科技”大揭秘
JDBC:Java数据库连接的“黑科技”大揭秘
41 7
|
2月前
|
SQL Java 数据库
Springboot+spring-boot-starter-data-jdbc实现数据库的操作
本文介绍了如何使用Spring Boot的spring-boot-starter-data-jdbc依赖来操作数据库,包括添加依赖、配置数据库信息和编写基于JdbcTemplate的数据访问代码。
200 2
|
2月前
|
SQL druid Java
JDBC和数据库连接池-两个工具类-JDBCUtilsByDruid和BasicDAO
JDBC和数据库连接池-两个工具类-JDBCUtilsByDruid和BasicDAO
61 0
|
4月前
|
Java 数据库连接 网络安全
JDBC数据库编程(java实训报告)
这篇文章是关于JDBC数据库编程的实训报告,涵盖了实验要求、实验环境、实验内容和总结。文中详细介绍了如何使用Java JDBC技术连接数据库,并进行增删改查等基本操作。实验内容包括建立数据库连接、查询、添加、删除和修改数据,每个部分都提供了相应的Java代码示例和操作测试结果截图。作者在总结中分享了在实验过程中遇到的问题和解决方案,以及对Java与数据库连接操作的掌握情况。
JDBC数据库编程(java实训报告)
|
4月前
|
SQL Java 数据库连接
JDBC之旅:从陌生到熟悉的Java数据库连接之路
JDBC之旅:从陌生到熟悉的Java数据库连接之路
33 9
|
4月前
|
SQL Java 数据库连接
Java开发者必知:JDBC连接数据库的“三大法宝”
Java开发者必知:JDBC连接数据库的“三大法宝”
42 7
|
4月前
|
SQL druid Java
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
62 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
|
4月前
|
SQL Java 关系型数据库
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
172 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
|
4月前
|
SQL 安全 Java
JDBC:Java与数据库的“月老红线”,你真的了解它吗?
JDBC:Java与数据库的“月老红线”,你真的了解它吗?
25 1
下一篇
DataWorks