JDBC学习笔记(黑马)

news2024/9/22 9:29:16

目录

一、JDBC快速入门

二、JDBC API详解

(一)DriverManager

(二)Connection

(三)Statement

(四)ResultSet

(五)PreparedStatement

三、数据库连接池

(一)数据库连接池简介

(二)数据库连接池实现

(三)Driud使用


  笔记跟课:黑马程序员

https://www.bilibili.com/video/BV1Qf4y1T7Hx?p=30&vd_source=0e0517ebadf244dd640ab0b61dd700c5

一、JDBC快速入门

1.创建工程,导入驱动 jar 包

2.注册驱动

Class.forName("com.mysql.jdbc.Driver");

 3.获取连接

Connection conn = DriverManager.getConnection(url, username, password);

4.定义SQL语句

String sql = "update…";

5.获取执行SQL对象

Statement stmt = conn.createStatement();

6.执行SQL

stmt.executeUpdate(sql);

7.处理返回结果

8.释放资源
【全部代码】:
public class JDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注册驱动
        //Class.forName("com.mysql.jdbc.Driver");

        //2.获取连接
        String url="jdbc:mysql://127.0.0.1:3306/test";
        String user="root";
        String password="✅✅✅";
        Connection conn=DriverManager.getConnection(url,user,password);

        //3.定义sql
        String sql = "update stu set Class = '软件133' where S_ID = '123456'";

        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();

        //5. 执行sql
        int count = stmt.executeUpdate(sql);//受影响的行数

        //6. 处理结果
        System.out.println(count);

        //7. 释放资源
        stmt.close();
        conn.close();
    }
}

二、JDBC API详解

(一)DriverManager

  • 注册驱动

    MySQL 5之后的驱动包,可以省略注册驱动( Class.forName )的步骤,会自动加载jar 包中 META-INF/services/java.sql.Driver 文件中的驱动类
  • 获取连接
    DriverManager.getConnection(url, user, password);

    1.参数url: jdbc:mysql://ip地址 ( 域名 ): 端口号 / 数据库名称 ? 参数键值对1&参数键值对2…
                 示例: jdbc:mysql://127.0.0.1:3306/db1
    2.如果连接的是本机mysql服务,且mysql服务默认端口是3306,则可以简写成jdbc:mysql:///db1

(二)Connection

  • 获取执行对象
    • 普通执行SQL对象:
      Statement createStatement()
    • 预编译SQL的执行SQL对象:防止SQL注入
      PreparedStatement prepareStatement(sql)
    • 执行存储过程的对象
      CallableStatement prepareCall(sql)
  • 事务管理
    • MySQL事务管理的操作:
      开启事务 : BEGIN; 或者 START TRANSACTION;
      提交事务 : COMMIT;
      回滚事务 : ROLLBACK;
      MySQL 默认是自动提交事务
    • Connection接 口中定义了 3 个对应的方法:
      开启事务:setAutoCommit(boolean autoCommit);
                       
      true为自动提交事务;false为手动提交事务,即为开启事务
      提交事务:commit()
      回滚事务:rollback()
Connection 全部代码
package com.itheima.jdbc_demo;

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

public class JDBCDemo_Connection {
    public static void main(String[] args) throws Exception {
        //1. 注册驱动
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1? useSSL=false";
        String username = "root";
        String password = "✅✅✅";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql1 = "update account set money = 3000 where id = 1";
        String sql2 = "update account set money = 3000 where id = 2";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        try {
            // ============开启事务==========
            conn.setAutoCommit(false);
            //5. 执行sql
            int count1 = stmt.executeUpdate(sql1);//受影响的行数
            //6. 处理结果
            System.out.println(count1);
            int i = 3 / 0;
            //5. 执行sql
            int count2 = stmt.executeUpdate(sql2);//受影响的行数
            //6. 处理结果
            System.out.println(count2);
            // ============提交事务==========
            //程序运行到此处,说明没有出现任何问题,则需求提交事务
            conn.commit();
        } catch (Exception e) {
            // ============回滚事务==========
            //程序在出现异常时会执行到这个地方,此时就需要回滚事务
            conn.rollback();
            e.printStackTrace();
        }
        //7. 释放资源
        stmt.close();
        conn.close();
    }
}

(三)Statement

  • 执行 sql 语句
    • 执行DML(数据操纵语言)、DDL(数据定义语言)语句
      int count = stmt.executeUpdate(sql);
      返回值:(1)DML语句影响的行数 (2)DDL语句执行成功也可能返回0
    • 执行DQL(数据查询语言)语句
      ResultSet rs = stmt.executeQuery(sql);

      返回值:ResultSet结果集对象

(四)ResultSet

  • 封装DQL查询语句的结果——ResultSet  stmt.executeQuery(sql)【返回ResultSet对象】
    • 获取查询结果
      1.
      boolean next():
      (1)将光标从当前位置向前移动一行(2)判断当前行是否为有效行
      ● ↪️返回值:true : 有效航,当前行有数据
                                   false : 无效行,当前行没有数据

      2.

      xxx getXxx(参数):获取数据
      ●  xxx : 数据类型;如: int getInt(参数) ;String getString(参数)
       参数:int类型的参数:列的编号,从1开始;String类型的参数: 列的名称
    •  使用步骤

      1.游标向下移动一行,并判断该行是否有数据:next()
      2.获取数据:getXxx(参数)
      //循环判断游标是否是最后一行末尾
      while (rs.next()){
          //获取数据
          rs.getXxx(参数);
      }

ResultSet全部代码

/**
 * JDBC API 详解:ResultSet
 */
public class JDBCDemo_ResultSet {

    /**
     * 执行DQL
     * @throws Exception
     */
    @Test
    public void testResultSet() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1";
        String username = "root";
        String password = "✅✅✅";
        Connection conn = DriverManager.getConnection(url, username, password);

        //3. 定义sql
        String sql = "select * from account";

        //4. 获取statement对象
        Statement stmt = conn.createStatement();

        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);

        //6. 处理结果, 遍历rs中的所有数据
        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            //6.2 获取数据  getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");

            System.out.println(id);
            System.out.println(name);
            System.out.println(money);

            System.out.println("--------------");

        }

        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }




    /**
     * 查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
     * 1. 定义实体类Account
     * 2. 查询数据,封装到Account对象中
     * 3. 将Account对象存入ArrayList集合中
     *
     *
     * @throws Exception
     */
    @Test
    public void testResultSet2() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "✅✅✅";
        Connection conn = DriverManager.getConnection(url, username, password);

        //3. 定义sql
        String sql = "select * from account";

        //4. 获取statement对象
        Statement stmt = conn.createStatement();

        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);

        // 创建集合
        List<Account> list = new ArrayList<>();

        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            Account account = new Account();

            //6.2 获取数据  getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");

            //赋值
            account.setId(id);
            account.setName(name);
            account.setMoney(money);

            // 存入集合
            list.add(account);
        }

        System.out.println(list);

        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }

}

(五)PreparedStatement

  • 预编译SQL语句并执行,预防SQL注入问题
    SQL注入:通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
    1.获取PreparedStatement对象
    // SQL语句中的参数值,使用?占位符替代
    String sql = "select * from user where username = ? and password = ?" ;
    // 通过Connection对象获取,并传入对应的sql语句
    PreparedStatement pstmt = conn . prepareStatement ( sql );

    2.设置参数值

    PreparedStatement对象:setXxx(参数1,参数2):给 ? 赋值
    ●   Xxx:数据类型 ; 如 setInt (参数1 ,参数 2)
    ●  参数:
               参数1 : ?的位置编号,从 1 开始
               参数2 : ?的值

    3.执行SQL

    executeUpdate(); 执行DDL语句和DML语句
    executeQuery(); 执行DQL语句
    ● ● ●  调用这两个方法时不需要传递 SQL 语句,因为获取 SQL 句执行对象时已经对 SQL 语句进行预编译了

PreparedStatement全部代码

/**
 * API详解:PreparedStatement
 */
public class JDBCDemo_PreparedStatement {

    @Test
    public void testPreparedStatement() throws  Exception {
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true";
        String username = "root";
        String password = "✅✅✅";
        Connection conn = DriverManager.getConnection(url, username, password);

        // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "' or '1' = '1";

        // 定义sql
        String sql = "select * from tb_user where username = ? and password = ?";

        // 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);

        // 设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);

        // 执行sql
        ResultSet rs = pstmt.executeQuery();

        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }

        //7. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}

注意:需要使用 useServerPrepStmts=true 才能开启预编译功能,否则只是解决了SQL注入问题,预编译性能更高。

三、数据库连接池

(一)数据库连接池简介

  • 数据库连接池是个容器,负责分配、管理数据库连接 (Connection)
  • 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一
  • 释放空闲时间超过最大空闲时间的数据库连接,避免因为没有释放数据库连接而引起的数据库连接遗漏
    ​​
        数据库使用了数据库连接池后,就能达到Connection 对象的复用,如下图

        连接池是在一开始就创建好了一些连接(Connection )对象存储起来。用户需要连接数据库时,不需要自己创建连接,而只需要从连接池中获取一个连接进行使用,使用完毕后再将连接对象归还给连接池;这样就可以起到资源重用,也节省了频繁创建连接销毁连接所花费的时间,从而提升了系统响应的速度。

(二)数据库连接池实现

标准接口:DataSource

  • 该接口提供了获取连接的功能:Connection getConnection()
  • 以后就不需要通过 DriverManager 对象获取 Connection 对象,而是通过连接池(DataSource )获取 Connection 对象。

  • 常见的数据库连接池
    • DBCP
    • C3P0
    • Druid
      我们现在使用更多的是Druid,它的性能比其他两个会好一些
  • Druid (德鲁伊)
    Druid 连接池是阿里巴巴开源的数据库连接池项目,功能强大,性能优秀,是Java 语言最好的数据库连接池之一
    ​​​​​​​

(三)Driud使用

  1. 导入jar包 druid-1.1.12.jar

     导入后选择 Add as Library

  2. 定义配置文件——druid.properties

    配置文件代码:
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
    username=root
    password=✅✅✅
    # 初始化连接数量
    initialSize=5
    # 最大连接数
    maxActive=10
    # 最大等待时间
    maxWait=3000
  3. 加载配置文件
  4. 获取数据库连接池对象
  5. 获取连接
Druid使用全部代码
/**
 * Druid数据库连接池演示
 */
class DruidDemo {
    public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.定义配置文件

        //3. 加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("JDBC(itheima)/src/druid.properties"));

        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

        //5. 获取数据库连接 Connection
        Connection connection = dataSource.getConnection();
        System.out.println(connection);


        //System.out.println(System.getProperty("user.dir"));
    }
}

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

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

相关文章

前端实现水印的两种方式(DOM和Canvas)

&#x1f431; 个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff1a;vue3从入门…

Python 海象运算符

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人网站&#xff1a;小嗷犬的技术小站 &#x1f34a;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xf…

图纸版本混乱?BOM表管理困难?看SolidWorks PLM如何高效助力产品数据管理

“随着集团的日益壮大&#xff0c;我们越来越重视信息化系统的建设工作&#xff0c;但在研发生产的过程中我们经常会遇到图纸版本混乱、数据查找不便的问题&#xff1b;特别是在产品设计好后&#xff0c;还需要花费很多时间手动整理BOM表&#xff0c;整理期间由于数据量太大&am…

2023年,对人工智能的思考与展望

近些年来&#xff0c;人工智能的话题一次次的冲上热榜&#xff0c;而在前段时间内&#xff0c;chatgpt以及midjourney又一次冲上了热搜&#xff0c;在海内外引起广泛的讨论&#xff0c;我个人在研究了近一个多月的技术文档和文献资料后&#xff0c;也对人工智能的未来有了很多的…

STC32G 单片机通用串行通信接口及其编程

STC32G 系列单片机有4个全双工通用串行通信接口&#xff0c;串口1与串口2既有异步通信功能、又有同步通信功能&#xff0c;串口1与串口2都可进行SPI通信&#xff0c;SPI是一个全双工高速同步串行&#xff1b;通信总线串口3、串口4只有异步通信功能。本文将重点讨论其异步通信&a…

hexo个人博客搭建+butterfly主题配置(雏形版本)

前提&#xff1a; 1. 有一个属于自己的GitHub账号 2. 安装好了git 3. 安装好了node 一、安装hexo 1. 建立一个文件夹 Blog&#xff08;可以自己取名字&#xff09;&#xff0c;进入文件夹标右键打开 Git Bush Here&#xff0c;安装Hexo&#xff1a; npm install -g hexo-…

中智股份冲刺上交所上市:半年收入约87亿元,计划募资37亿元

近日&#xff0c;中智经济技术合作股份有限公司&#xff08;下称“中智股份”&#xff09;预披露招股书&#xff0c;准备在上海证券交易所主板上市&#xff0c;中信证券为其保荐机构。 本次冲刺上市&#xff0c;中智经济计划募资37.42亿元&#xff0c;将用于中智人力资源研发运…

函数的连续性和间断点——“高等数学”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容是高等数学中的函数的连续性和间断点&#xff0c;好的&#xff0c;那现在就让我们进入函数的连续性和间断点的世界吧 一、函数的连续性 1.函数增量 2.连续的定义 3.单侧连续 二、例题&#xff08;函数的连续性&#xff09; …

JDK动态代理CGLIB动态代理

代理模式 是通过代理对象访问目标对象&#xff0c;这样可以在目标对象基础上增强额外的功能&#xff0c;如添加权限&#xff0c;访问控制和审计等功能。 房产中介代替业主卖房 静态代理 静态代理中代理类与被代理类都需要实现同一个接口&#xff0c;这就说明我们的一个静态代…

MFC|Toolbox内控件简单介绍

参考&#xff1a; MFC控件工具箱 &#xff08;https://blog.csdn.net/Hubz131/article/details/77684910&#xff09; 对应工具的超链接是本人搜到认为较易理解的单个控件介绍。 Pointer&#xff1a;就是普通的鼠标&#xff0c;默认状态Button&#xff1a;按钮&#xff0c;用…

stm32f091芯片的学习总结

摘自芯片手册&#xff08;外加自己的思考&#xff09; 发现网上使用这种芯片的人较少或者说解释这种芯片的电路具体怎么画的人较少&#xff0c;本来想直接借鉴的&#xff0c;发现没有找到&#xff0c;于是我自己来写一篇。 一、概述 该芯片提供标准通信接口(两个i2c&#xf…

基于STM32的FreeRTOS开发(2)----Cube工程的FreeRTOS配置

为什么使用Cube进行FreeRTOS配置 STM32Cube是STMicroelectronics提供的一种软件工具&#xff0c;用于配置和生成STM32微控制器的固件。它提供了一个图形化用户界面&#xff0c;可以轻松配置微控制器的各种功能和外设&#xff0c;并生成初始化代码。使用Cube可以大大简化微控制…

[GNN] 图神经网络入门

GNN和GCN的入门公式一、GNN的计算二、GCN的计算跟随B站课程【GNN图神经网络最牛教程】学不会up直接下跪&#xff01;图神经网络快速入门教程&#xff08;GNN/GCN&#xff09;的笔记 一、GNN的计算 对于一个图来说&#xff0c;要更新它自身的特征&#xff0c;也要更新它邻接节点…

前端websocket劫持漏洞(CSWSH)

0x00 什么是ws劫持 在Websocket的业务中&#xff0c;其中常见的漏洞是ws劫持&#xff0c;全称为跨站点CSWSH(Cross-Site WebSocket Hijacking)跨站WebSocket劫持漏洞。 WebSocket概念 WebSocket是通过HTTP启动的双向、全双工通信协议。它们通常用于流式传输数据和其他异步流量…

深度卷积神经网络、池化层、为什么使用卷积

目录1.深度卷积神经网络(a deep convolutional neural network)输入图像的维度是&#xff0c;如果&#xff0c;计算输出图像维度公式&#xff1a;。s表示步幅&#xff0c;p表示填充的层数。filters的通道数是和输入图像的通道数保持一致的。分析上图案例&#xff1a;第一层卷积…

MySQL基本查询案例练习

目录 一.案例1 需求 解决代码 二.案例2 需求 解决代码 一.案例1 创建一个学生表&#xff0c;插入以下数据 insert into student values(1,张明,男,89,78,90), (2,李静,男,77,73,60), …

golang map原理

简介本文主要通过探究在golang 中map的数据结构及源码实现来学习和了解map的特性&#xff0c;共包含map的模型探究、存取、扩容等内容。欢迎大家共同讨论。Map 的底层内存模型在 goland 的源码中表示 map 的底层 struct 是 hmap&#xff0c;其是 hashmap 的缩写type hmap struc…

“华为杯”研究生数学建模竞赛2005年-【华为杯】A题:交通网络的通行时间预测与最优路径决策(附获奖论文)

赛题描述 A: Highway Traveling time Estimate and Optimal Routing Ⅰ Highway traveling time estimate is crucial to travelers. Hence, detectors are mounted on some of the US highways. For instance, detectors are mounted on every two-way six-lane highways o…

树与二叉树深度剖析(一)

一. 树简介 1. 定义 (1) 树结构是一种非线性存储结构&#xff0c;存储的是具有“一对多”关系的数据元素的集合。 (2) 树&#xff08;Tree&#xff09;是n(n≥0)个节点&#xff08;Node&#xff09;的有限集合。在任意一颗非空树中&#xff0c;有且仅有一个特定的成为根(Root)…

【快速幂】876. 快速幂求逆元

876. 快速幂求逆元 文章目录题目描述输入格式&#xff1a;输出格式&#xff1a;数据范围输入样例输出样例方法&#xff1a;快速幂解题思路代码复杂度分析&#xff1a;题目描述 给定 n 组 ai,pia_i,p_iai​,pi​&#xff0c;其中 pip_ipi​ 是质数&#xff0c;求 aia_iai​ 模 …