通过JDBC 访问数据

学习时间 7月11日

一、使用Java访问数据库

JAVA 主动 提出接口 ,各种数据库适应 这些接口

  • 接口就是 JDBC Java Database Connector
  • 各种数据库都会提供一套对应的驱动程序(JAR文件
  • 即不同的数据库都有自己对应的JAR文件

1、导入mysql对应的JAR包

  1. 创建lib文件夹
  2. 将jar文件放入
  3. 右键jar包,点击 add as library导入包

2、访问数据库的步骤

  1. 加载驱动:涉及到反射

    • Class.forName 需要捕获异常

      • 快速添加异常的快捷键Alt + 回车,选第二个
  2. 连接数据库:查找db文件

    • 配置urljdbc:mysql://127.0.0.1:3306/zy_sys?useUnicode=true&characterEncoding=UTF-8&useSSL=false

      ip地址,数据库名字,编码unicode,不使用加密

      • zy_sys对应的是数据库名称
    • 创建连接Connection connection = DriverManager.getConnection(url , user , password);

      • 也需要异常捕获
  3. SQL语句

    • 创建一个字符串存储 SQL语句
    • 建议先在DBMS中测试一次
  4. 预编译SQL语句(判断语法错误,获取执行的对象)

    • 固定语法PreparedStatement preparedStatement = connection.prepareStatement(sql);
  5. 执行操作

  6. 获取执行结果

    • 增删改调用方法executeUpdate()

      • 返回类型int 表示受影响的条数
      • 获取执行结果只需要输出这个返回值即可
    • 查找调用方法executeQuery():

      • 返回值类型是ResultSet(结果集:类似对象列表)

      • 用 while 循环 遍历结果集.

        用到ResultSet.next()方法——向下移动一行,返回布尔值。默认是在空行,next一行才是第一行。举个例子如下:

          while (resultSet.next()){// 使用对应的方法获得相应的数据类型String sno = resultSet.getString("sno");String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");// 按顺序输出结果即可System.out.println(sno + "\t" + sname + "  \t" + sage);}
        
  7. 关闭操作(关闭连接,关闭接口,关闭对象) 释放资源

    • 关闭顺序有大小之分,小的先关,大的后关

3、举个例子(增删改

package com.cykj.demo;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;public class Test {public static void main(String[] args) {try {// 1、加载驱动  ——涉及到反射知识点Class.forName("com.mysql.jdbc.Driver"); // Driver类 驱动String url = "jdbc:mysql://127.0.0.1:3306/zy_sys?useUnicode=true&characterEncoding=UTF-8&useSSL=false";// 2、连接数据库String user = "root";  // 账号String password = "root";   // 密码Connection connection = DriverManager.getConnection(url , user , password);     // 创建连接System.out.println("连接成功!");// 3、写SQL语句String sql = "INSERT INTO zy_student(sno,sname,ssex)  VALUES ('jx220501','老王',1)";// 4、预编译PreparedStatement preparedStatement = connection.prepareStatement(sql);// 5、执行操作int re = preparedStatement.executeUpdate();// sql的增删改都用executeUpdate() 返回类型int 表示受影响的条数// 6、获取执行结果System.out.println(re);// 7、关闭preparedStatement.close();  // 关闭编译connection.close();         // 关闭连接// 关闭顺序有大小之分,小的先关,大的后关} catch (ClassNotFoundException  e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}
}

4、 查找例子

package com.cykj.demo;import java.sql.*;public class Test2 {public static void main(String[] args) {try {// 1、加载驱动  ——涉及到反射知识点Class.forName("com.mysql.jdbc.Driver"); // Driver类 驱动// 2、连接数据库String url = "jdbc:mysql://127.0.0.1:3306/zy_sys?useUnicode=true&characterEncoding=UTF-8&useSSL=false";String user = "root";  // 账号String password = "root";   // 密码Connection connection = DriverManager.getConnection(url , user , password);     // 创建连接System.out.println("连接成功!");// 3、写SQL语句String sql = "SELECT sno,sname,sage FROM zy_student WHERE sno LIKE 'AF%';";// 4、预编译PreparedStatement preparedStatement = connection.prepareStatement(sql);// 5、执行操作ResultSet resultSet = preparedStatement.executeQuery();  // 查找数据库用的是executeQuery()// 6、获取执行结果while (resultSet.next()){// 使用对应的方法获得相应的数据类型String sno = resultSet.getString("sno");        String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");// 按顺序输出结果即可System.out.println(sno + "\t" + sname + "  \t" + sage);}// 7、关闭resultSet.close();preparedStatement.close();  // 关闭编译connection.close();         // 关闭连接// 关闭顺序有大小之分,小的先关,大的后关} catch (ClassNotFoundException  e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}
}===输出结果===
AF121101    小王      22
AF121102    小红      22
AF121103    王思思     23
AF121104    小灰      30
AF121105    小林      27
AF121106    小张      26
AF121107    小丽      32
AF121108    小花      29
AF121109    小马      26

JDBC优化

一、在预编译时拼接字符串

  • SQL语句的拼接,有什么缺点?

    • 写法麻烦
    • 不安全,留有SQL注入的风险
  • 如何解决呢?

    用问号?替代字符串中需要拼接的位置

    • 预编译时加入字符串,举个例子
    // 原字符串
    String sql = "SELECT * FROM tb_user WHERE userid = '" + useridText + "' OR username = '" + useridText + "'";
    
    • 修改后
                // 用问号替代拼接的字符串  意思类似挖坑
    String sql = "SELECT * FROM tb_user WHERE userid = ? OR username = ?";;
    ps = connection.prepareStatement(sql);  // 预编译
    // 利用setString()方法 插入字符串,计数从1开始
    ps.setString(1,useridText);
    ps.setString(2,useridText);
    
    • 简单理解:这种方法类似挖坑和填坑

      1. 先挖坑:用问号?替代也要拼接的字符串
      2. 再填坑,利用setString()方法 插入字符串,计数从1开始
    • 注意:setString会自动给这个字符串加入单引号,无需再添加

二、优化关闭操作

  • 在JDBC操作中,如果编译出现报错,后续的关闭操作就不再执行了。这样会导致数据库负担较大

    • 要如何解决该问题呢?

      • 利用异常关键字finally的特点:异常处理中finally是最后必须执行一次的,可以把关闭操作写在这里!
  • 具体操作如下

    1. 将需要关闭的对象,设置为全局变量

    2. 目标**:在finally语句块里关闭对象**

    3. 关闭时也要加入异常捕获,注意:每次关闭都要分别捕获异常

    4. 在关闭前,也要加入一个if判断,判断对象不等于null,才进行关闭操作。举个例子

      try{。。。
      } catch{。。。
      } finally {try {if (connection != null){   // 判断连接是否为空connection.close();      // 关闭连接}} catch (SQLException e) {  // 加入关闭操作的异常捕获e.printStackTrace();}try {if (ps != null) {ps.close();}} catch (SQLException e) {e.printStackTrace();}
      }
      

三、封装

经过观察发现,1、2、7三步的基本类似,可以偷懒共同的方法,可以封装起来,甚至写成一个类,即:

共同的代码———> 方法 ———> 类

1、2、7三步的代码 ———> 分别封装成方法 ———> 放在同一个类中(工具层)

  • 这种类存放在工具层,这个类就成为"工具包"

1、 工具类 Utils

  • 用于存放各种封装起来的方法,提供给其他模块调用

2、封装第一步和第二步 加载驱动建立连接

  • 封装1+2步

    public Connection getConnection (){try {// 1、加载驱动Class.forName("com.mysql.jdbc.Driver");String url = "jdbc:mysql://127.0.0.1:3306/goods_db?" +"useUnicode=true&" +"characterEncoding=UTF-8&useSSL=false";String user = "root";String password = "root";// 2、建立连接Connection connection = DriverManager.getConnection(url,user,password);return connection;  // 连接成功则返回连接} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}return null;        // 连接失败则返回空
    }
    
  • 但是存在一个问题,URL,用户名,密码都是不固定的,这时候就需要用到配置文件*.properties” 、 xmlyml

    • 如何使用配置文件?

3、properties配置文件的使用

  • 键值对格式 : key=value

    • 注意:等号的两边都不能有空格
  • 具体使用步骤

    1. 将配置文件 拷贝到 项目工程目录 下

    2. 读取配置文件的值

      • 要有对应的库 ——> 找到对应的或对象 ——> 方法

      • Java有对应的类 Properties,实现的思路如下:

        1. 读取文件 调用InputStream类 (IO流的内容 后续会接触到
        2. 实例化属性类 Properties
        3. 调用load(文件名)加载文件
        4. 取值 用getProperty(键名)来搜索对应的数据,返回值类型为String
      • 举个例子

        public static void main(String[] args) {try {// 用IO读取文件InputStream inputStream = new FileInputStream("db.properties");// 加载Properties pps = new Properties();pps.load(inputStream);// 获取字符串String driver = pps.getProperty("driver");System.out.println(driver);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}
        }
        
    3. 在工具类中,获取对应的驱动,url,用户名,密码存放在String

    4. 在执行连接数据库时,直接调用这些字符串进行登陆即可


  • 在实际应用场景中,只需要读取一次配置文件。那么,如何只读取一次配置文件?

    • 构造函数?实例化的时候只运行一次,但是多次实例化还会再次执行
    • 这里就需要用到静态代码块——
      • 语法:static {代码块}
      • 在类里的静态代码块,只会执行一次
      • 执行的时间是在构造函数之前,且需要实例化的时候才会运行

4、封装第七步:关闭操作

  • 举个例子

    public void closeJdbc(Connection con , PreparedStatement ps , ResultSet rs){try {if (rs != null){rs.close();}} catch (SQLException e) {e.printStackTrace();}try {if (con != null){    // 判断连接是否为空con.close();     // 关闭连接}} catch (SQLException e) {  // 加入关闭操作的异常捕获e.printStackTrace();}try {if (ps != null) {ps.close();}} catch (SQLException e) {e.printStackTrace();}
    }
    

5、调用思路

  • 思路如下:

    1. 先将工具类实例化为全局变量 (所有需要关闭的对象也要声明为全局变量)
    2. 调用工具类的方法 getConnection () 获取 连接 Connection
      • 对应的完成了第一步和第二步
    3. 继续完成 写SQL语句 预编译 执行和获取结果的步骤
    4. 在最后的finally的语句块中调用关闭的方法closeJdbc(),关闭掉对应的对象。
      • 由于关闭方法有多个对象,当不存在某个对象时,可以传入null

6、工具类的具体案例

  • 举个例子

    Connection connection = null;
    PreparedStatement ps = null;
    ResultSet resultSet = null;
    JdbcUtils jdbcUtils = new JdbcUtils();
    connection = jdbcUtils.getConnection();    // 调用方法获得连接
    try {String sql = "SELECT * FROM tb_user WHERE userid = ? OR username = ?";  // 预编译ps = connection.prepareStatement(sql);ps.setString(1, useridText);ps.setString(2, usernameText);resultSet = ps.executeQuery();if (resultSet.next()) {JOptionPane.showMessageDialog(null, "账号已重复!","注意", JOptionPane.WARNING_MESSAGE);return;} else {// 账号没有重复 可以继续执行操作 。。。}
    } catch (SQLException e) {e.printStackTrace();
    } finally {jdbcUtils.closeJdbc(connection, ps, resultSet);// 如果没有resultset,就传入null即可
    }
    

【Java学习笔记】 MYSQL03 学习使用JDBC访问数据 以及 JDBC的优化和封装相关推荐

  1. JDBC学习笔记02【ResultSet类详解、JDBC登录案例练习、PreparedStatement类详解】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  2. WinDbg学习笔记(二)--字符串访问断点

    标 题: [原创]WinDbg学习笔记(二)--字符串访问断点 作 者: gaorqing 时 间: 2009-07-25,21:39:04 链 接: http://bbs.pediy.com/sho ...

  3. 【Springboot学习笔记】SpringBoot+Mybatis+Thymeleaf+Layui数据表单从零开始实现按条件模糊分页查询的方法

    [Springboot学习笔记]SpringBoot+Mybatis+Thymeleaf+Layui数据表单从零开始实现按条件模糊分页查询的方法 目录 1.搭建环境 1.1直接从网上下载SpringB ...

  4. Kafka学习笔记(3)----Kafka的数据复制(Replica)与Failover

    1. CAP理论 1.1 Cosistency(一致性) 通过某个节点的写操作结果对后面通过其他节点的读操作可见. 如果更新数据后,并发访问的情况下可立即感知该更新,称为强一致性 如果允许之后部分或全 ...

  5. Kinect开发学习笔记之(七)骨骼数据的提取

    Kinect开发学习笔记之(七)骨骼数据的提取 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7x86 + VS2010 ...

  6. SilverLight学习笔记--进一步学习Isolated Storage独立存储一(理论篇)

    在"silverlight如何在客户端读取文件"以及"silverlight如何在客户端写入文件"两篇文章中我们初步接触了Isolated Storage概念. ...

  7. at24c16如何划分出多个读写区_AVR学习笔记九、基于AT24C16的数据存储实验

    Ema{@AVR 学习笔记九.基于 AT24C16 的数据存储实验 ------- 基于 LT_Mini_M16 9.1 用 I/O 口模拟 I2C 总线实现 AT24C16 的读写 9.1.1 .实 ...

  8. oracle 11g dul,学习笔记:Oracle dul数据挖掘 导出Oracle11G数据文件坏块中表中

    试验模拟导出Oracle 11G数据库中数据文件坏块中表中的数据 以前一直以为dul对应的版本只能恢复最高的数据库版本一致,今天测试发现dul 10可以恢复11g最新版的数据库. 模拟环境SQL> ...

  9. Python3学习笔记之-学习基础(第三篇)

    Python3学习笔记之-学习基础(第三篇) 文章目录 目录 Python3学习笔记之-学习基础(第三篇) 文章目录 一.循环 1.for循环 2.while循环 3.break,continue 二 ...

  10. 强化学习笔记-强化学习概述

    强化学习笔记-强化学习概述 机器学习分类 强化学习与监督学习的异同点 强化学习基本原理 强化学习解决的是什么样的问题 强化学习分类 请分别解释随机性策略和确定性策略 回报.值函数.行为值函数三个指标的 ...

最新文章

  1. DAY11-MYSQL之ORM框架SQLAlchemy
  2. 操作系统(二十二)用信号量机制实现进程互斥、同步、前驱关系
  3. struts2的处理流程
  4. opencv及相机相关6
  5. 理解lua中 . : self
  6. Python 装饰器理解
  7. Java 面试 80% 的人都会踩这些坑,你知道几种?
  8. blade php代码,Laravel 5框架学习之Blade 简介
  9. SpringMVC 的总结
  10. GitHub Universe 2020 强势登陆,GitCode直播已上线
  11. 6. 分类图显示和保存
  12. python︱Anaconda安装、简介(安装报错问题解决、Jupyter Notebook)
  13. oracle 11g安装自己理解
  14. mysql 如何避免间隙锁_mysql 间隙锁
  15. 网络安全-MySQL数据库
  16. Arm Compiler for Embedded 6 编译器工具链常用选项
  17. Leedcode 875. 爱吃香蕉的珂珂
  18. python字体类型arial_python-3.x - 为什么我的font.name属性不影响使用Python-pptx制作的ppt上的字体? 我总是得到arial字体 - 堆栈内存溢出...
  19. windows下 编写的Qt程序连接远程MySQL数据库
  20. git推送被拒绝可能的原因

热门文章

  1. kalibr fov畸变模型
  2. 怎样下载网页上的视屏到本地
  3. 使用LIME解释CNN
  4. 动环监控系统服务器维护,机房动环设备维护与检测的13个具体内容
  5. rtlinux linux实时补丁,(九)RTLinux补丁以及cyclictest
  6. python 正则表达式 compile_使用compile()函数编译正则表达式【Python技术文章】
  7. 2019中兴通讯软件开发岗c/c++方向(笔试+面试)总结
  8. 四色定理java_java – 四色定理的递归算法
  9. lucas–kanade_Lucas–Kanade光流算法
  10. 基于Arch GNU/Linux的简体中文live系统 archlive