JDBC 入门:从基础到实战

news2025/2/21 18:37:12

一、JDBC 概述

JDBC,即 Java DataBase Connectivity,是 Java 用于连接数据库的技术,旨在通过 Java 代码操作数据库。它是一套接口规范,其实现类由各数据库生产商提供。掌握 JDBC 接口和方法,就能操作不同数据库。而驱动则是数据传输的桥梁,使用 MySQL 数据库需导入 mysql - connector - java - 5.1.13 - bin.jar 等相应驱动 jar 包。

二、JDBC 快速入门步骤

  1. 创建数据库和表结构:以创建 jdbcdemo 数据库及 t_user 表为例,插入一些测试数据。
CREATE DATABASE jdbcdemo;
USE jdbcdemo;
CREATE TABLE t_user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(30),
    password VARCHAR(30),
    email VARCHAR(30)
);
INSERT INTO t_user VALUES (NULL, 'aaa', '123', 'aaa@163.com');
INSERT INTO t_user VALUES (NULL, 'bbb', '456', 'bb@163.com');
INSERT INTO t_user VALUES (NULL, 'ccc', '789', 'ccc@163.com');
  1. 加载驱动:使用 DriverManager 类加载驱动,推荐 Class.forName("com.mysql.jdbc.Driver"); 方式,相比 DriverManager.registerDriver(new Driver()),此方式避免过度依赖特定实现类,也不会使驱动 jar 包加载两次。

  1. 获取连接:通过 DriverManager.getConnection(String url, String user, String password) 方法获取连接。url 格式如 jdbc:mysql://localhost:3306/day07,其中 jdbc 是主协议,mysql 是子协议,localhost 是主机,3306 是默认端口号,day07 是数据库名。若访问本地数据库,localhost:3306 可省略,即 jdbc:mysql:///day07。另外两个参数分别是用户名和密码。
 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
 // 获取到连接,localhost:3306可以省略不写的,访问本地mysql服务器

  1. 执行 SQL 语句
    • 编写 SQL 语句:根据需求编写查询、插入、更新或删除等 SQL 语句。
    • 获取执行 SQL 语句的对象:通过 Connection 对象获取 Statement 接口对象,如 Statement createStatement()。若要防止 SQL 注入漏洞,可使用 PreparedStatement prepareStatement(String sql) 获取 PreparedStatement 对象。
    • 执行查询语句:若执行查询,使用 Statement 的 executeQuery(String sql) 方法,结果封装在 ResultSet 接口中。
    • 执行增删改语句:使用 Statement 的 executeUpdate(String sql) 方法执行增删改操作。
// 执行SQL语句
            // 编写SQL语句
            String sql = "select * from t_user";
            // 有能执行SQL语句的对象 Statement对象
            stmt = conn.createStatement();//不能防止sql注入
            //conn.prepareStatement()//可以防止sql注入问题
  1. 处理结果集(针对查询)ResultSet 代表结果集,以表格形式封装数据,内部有游标,默认指向第一行数据之前。通过调用 next() 方法向下移动游标,根据字段类型调用不同方法获取值,如 getInt()getString() 等,也可使用 getObject() 并自行强转。获取数据方法可通过下标(从 1 开始)或字段名称取值,后者更常用。
 rs = stmt.executeQuery(sql);
            // 遍历rs结果集
            while(rs.next()){
                // 获取到数据就OK
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String password = rs.getString("password");
                String email = rs.getString("email");
                // 做打印
                System.out.println(id+"-"+username+"-"+password+"-"+email);
  1. 释放资源:连接等对象使用完后必须释放,通常在 finally 代码块中进行,确保一定会执行。以释放 Connection 为例:
if (conn!= null) {
    try {
        conn.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    conn = null;
}

三、JDBC 相关接口和 API

  1. DriverManager 类:管理 JDBC 驱动的实现类,作用是加载驱动和获取连接。
  2. Connection 接口:代表数据库连接,很重要且资源稀有,用完需释放。可获取执行 SQL 语句的对象(Statement 或 PreparedStatement),还能管理事务(如 setAutoCommit(boolean autoCommit) 开启事务、commit() 提交事务、rollback() 回滚事务)。
  3. Statement 接口:能执行 SQL 语句,包括查询(executeQuery(String sql))和增删改(executeUpdate(String sql)),还支持批处理(addBatch(String sql) 添加 SQL 语句到批处理、clearBatch() 清除批处理、executeBatch() 执行批处理)。
  4. PreparedStatement 接口Statement 的子接口,能执行 SQL 语句,有预编译功能,可解决 SQL 注入漏洞。通过 Connection 的 prepareStatement(String sql) 方法获取,使用 setXxxx() 系列方法向占位符 ? 传入值,再执行相应的 executeQuery() 或 executeUpdate() 方法。

四、SQL 注入漏洞及解决

  1. 漏洞产生:在拼接 SQL 语句时,若用户输入特殊字符,可能改变 SQL 语句逻辑。例如,当用户名输入 aaa'or'1=1,密码任意时,原本的查询语句 select * from t_user where username = '"+username+"' and password = '"+password+"' 会变为 select * from t_user where username = 'aaa'or'1=1' and password ='sfsdfsds,使查询条件恒成立,导致非法登录。
  2. 解决方法:使用 PreparedStatement 接口,将 SQL 语句中的参数部分用 ? 占位符代替,先将 SQL 语句发送到 MySQL 服务器编译,之后传入的值都作为 ? 的参数处理,从而避免 SQL 注入。

五、JDBC 工具类编写及控制台登陆案例

  1. 编写配置文件:在 src 目录创建 db.properties 文件,以 key = value 形式配置数据库相关信息。
driverclass=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbcdemo
username=root
password=root
  1. 封装工具类:将 JDBC 常用操作封装成工具类,方便复用。在控制台登陆案例中,结合工具类和 PreparedStatement 可有效防止 SQL 注入,实现安全的用户登陆验证。
package cn.qcby.utils;

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

/**
 * JDBC的工具类 1.0版本
 * JDBC的工具类 2.0版本(智能一些),编写properties属性文件,程序就可以读取属性文件
 *      1. 驱动类
 *      2. 数据库地址
 *      3. 用户名
 *      4. 密码
 */
public class JdbcUtils {

    private static final String driverclass;
    private static final String url;
    private static final String username;
    private static final String password;

    static{
        // 加载属性文件
        Properties pro = new Properties(); //创建Properties对象
        //通过反射获取文件里的数据并转成流的方式输出
        InputStream inputStream = JdbcUtils.class.getResourceAsStream("/db.properties");
        //调用Properties中的load方法进行加载
        try {
            // 加载属性文件
            pro.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 给常量赋值
        driverclass = pro.getProperty("driverclass");
        url = pro.getProperty("url");
        username = pro.getProperty("username");
        password = pro.getProperty("password");
    }

    /**
     * 加载驱动
     */
    public static void loadDriver(){
        try {
            // 通过反射加载驱动类
            Class.forName(driverclass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 加载完驱动,获取到连接,返回连接对象
     * @return
     */
    public static Connection getConnection(){
        // 加载驱动
        loadDriver();
        // 获取到连接对象,返回
        Connection conn = null;
        try {
            // 获取到连接
            conn = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭资源
     * @param conn
     * @param stmt
     * @param rs
     */
//两种对close方法的重载,一种是有结果集的,也就是查询走的关闭资源路径,一种是没有结果集走的关闭资源
    public static void close(Connection conn, Statement stmt, ResultSet rs){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭资源
     * @param conn
     * @param stmt
     */
    public static void close(Connection conn, Statement stmt){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }



}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2301144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux探秘坊-------5.git

1.git介绍 1.版本控制器 为了能够更⽅便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你了解到⼀个⽂件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统&am…

VsCode美化 Json

1.扩展中输入:pretty json 2. (CtrlA)选择Json文本 示例:{ "name" : "runoob" , "alexa" :10000, "site" : null , "sites" :[ "Google" , "Runoob" , "T…

ssm121基于ssm的开放式教学评价管理系统+vue(源码+包运行+LW+技术指导)

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问…

《深度学习》——ResNet网络

文章目录 ResNet网络ResNet网络实例导入所需库下载训练数据和测试数据设置每个批次的样本个数判断是否使用GPU定义残差模块定义ResNet网络模型导入GPU定义训练函数定义测试函数创建损失函数和优化器训练测试数据结果 ResNet网络 ResNet(Residual Network&#xff0…

【Windows软件 - HeidiSQL】导出数据库

HeidSQL导出数据库 软件信息 具体操作 示例文件 选项分析 选项(1) 结果(1) -- -------------------------------------------------------- -- 主机: 127.0.0.1 -- 服务器版本: …

【达梦数据库】dblink连接[SqlServer/Mysql]报错处理

目录 背景问题1:无法测试以ODBC数据源方式访问的外部链接!问题分析&原因解决方法 问题2:DBLINK连接丢失问题分析&原因解决方法 问题3:DBIINK远程服务器获取对象[xxx]失败,错误洋情[[FreeTDS][SQL Server]Could not find stored proce…

java断点调试(debug)

在开发中,新手程序员在查找错误时, 这时老程序员就会温馨提示,可以用断点调试,一步一步的看源码执行的过程,从而发现错误所在。 重要提示: 断点调试过程是运行状态,是以对象的运行类型来执行的 断点调试介绍 断点调试是…

最新智能优化算法:牛优化( Ox Optimizer,OX)算法求解经典23个函数测试集,MATLAB代码

一、牛优化算法 牛优化( OX Optimizer,OX)算法由 AhmadK.AlHwaitat 与 andHussamN.Fakhouri于2024年提出,该算法的设计灵感来源于公牛的行为特性。公牛以其巨大的力量而闻名,能够承载沉重的负担并进行远距离运输。这种…

Redis7——基础篇(四)

前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二)Redis(三) 接上期内容&…

Git备忘录(三)

设置用户信息: git config --global user.name “itcast” git config --global user.email “ helloitcast.cn” 查看配置信息 git config --global user.name git config --global user.email $ git init $ git remote add origin gitgitee.com:XXX/avas.git $ git pull or…

MySQL 之INDEX 索引(Index Index of MySQL)

MySQL 之INDEX 索引 1.4 INDEX 索引 1.4.1 索引介绍 索引:是排序的快速查找的特殊数据结构,定义作为查找条件的字段上,又称为键 key,索引通过存储引擎实现。 优点 大大加快数据的检索速度; 创建唯一性索引,保证数…

Linux基础24-C语言之分支结构Ⅰ【入门级】

分支结构 问题抛出 我们在程序设计中往往会遇到如下问题,比如下面的函数计算: 也就是我们必须要通过一个条件的结果来选择下一步的操作,算法上属于一个分支结构,处于严重实现分支结构主要使用if语句。 条件判断 根据某个条件成…

LeetCode47

LeetCode47 目录 题目描述示例思路分析代码段代码逐行讲解复杂度分析总结的知识点整合总结 题目描述 给定一个可包含重复数字的整数数组 nums,按任意顺序返回所有不重复的全排列。 示例 示例 1 输入: nums [1, 1, 2]输出: [[1, 1, 2],[1, 2, 1],[2, 1, 1] ]…

【Unity动画】导入动画资源到项目中,Animator播放角色动画片段,角色会跟随着动画播放移动。

导入动画资源到项目中,Animator播放角色动画片段,角色会跟随着动画播放移动,但我只想要角色在原地播放动画。比如:播放一个角色Run动画,希望角色在原地奔跑,而不是产生了移动距离。 问题排查: 1.是否勾选…

图解循环神经网络(RNN)

目录 1.循环神经网络介绍 2.网络结构 3.结构分类 4.模型工作原理 5.模型工作示例 6.总结 1.循环神经网络介绍 RNN(Recurrent Neural Network,循环神经网络)是一种专门用于处理序列数据的神经网络结构。与传统的神经网络不同&#xff0c…

【数据结构】(9) 优先级队列(堆)

一、优先级队列 优先级队列不同于队列,队列是先进先出,优先级队列是优先级最高的先出。一般有两种操作:返回最高优先级对象,添加一个新对象。 二、堆 2.1、什么是堆 堆也是一种数据结构,是一棵完全二叉树&#xff0c…

4、IP查找工具-Angry IP Scanner

在前序文章中,提到了多种IP查找方法,可能回存在不同场景需要使用不同的查找命令,有些不容易记忆,本文将介绍一个比较优秀的IP查找工具,可以应用在连接树莓派或查找IP的其他场景中。供大家参考。 Angry IP Scanner下载…

【Linux】命令操作、打jar包、项目部署

阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 一:Xshell下载 1:镜像设置 二:阿里云设置镜像Ubuntu 三&#xf…

瑞萨RA-T系列芯片ADCGPT功能模块的配合使用

在马达或电源工程中,往往需要采集多路AD信号,且这些信号的优先级和采样时机不相同。本篇介绍在使用RA-T系列芯片建立马达或电源工程时,如何根据需求来设置主要功能模块ADC&GPT,包括采样通道打包和分组,GPT触发启动…

Unity Shader学习6:多盏平行光+点光源 ( 逐像素 ) 前向渲染 (Built-In)

0 、分析 在前向渲染中,对于逐像素光源来说,①ForwardBase中只计算一个平行光,其他的光都是在FowardAdd中计算的,所以为了能够渲染出其他的光照,需要在第二个Pass中再来一遍光照计算。 而有所区别的操作是&#xff0…