JDBC知识点全面总结2:JDBC实战编写CRUD

news2024/10/3 8:17:06

二.JDBC知识点全面总结1:JDBC实战编写CRUD

1.JDBC重要接口?

2.Driver和DriverMangement的关系?

3.JAVA与数据库连接

4.JAVA中使用statement来执行sql语句时,拼接字符串的sql注入问题?

5.使用preparedstatement进行增删改查

6.自定义通用查询方法

未更新

二.JDBC知识点全面总结1:JDBC实战编写CRUD

1.JDBC重要接口?

①装载驱动接口

  • Driver接口:对接MySQL提供的Driver具体实现类
  • DriverManager类:封装Driver实例。

②连接

  • Connetion接口:获取和MySQL服务器的连接
  • 获取connection实例的方式:
    driver.connect();
    DriverManger.getConnection();

③执行SQL语句

  • Statement类(执行静态SQL语句并接受返回结果)
    Statement类:SQL语句无参数
    PreparedStatement类继承Statement类:SQL语句有参数(防止sql注入)
  • 执行方法
    execute()运行无返回值
    executeQuery()运行select语句有返回集
    executeUpdate()运行Insert/delete/Update语句返回影响的行数

2.Driver和DriverManger的关系?

①对比

  • Driver是所有JDBC驱动类实现的接口
  • DriverMangement封装Driver

②使用

  • Driver创建驱动实例后直接获取连接
    driver.connect()
  • DriverMangement初始化(注册)Driver后直接获取连接
    DriverMangement.getConnetion

③实战使用

  • Class.forName()加载类而且执行静态代码快。数据库驱动(Driver)中有静态代码块即注册驱动到DriverMangement
  • 故实战可以使用DriverMangement,在加载驱动类后直接获取连接。

3.JAVA与数据库连接

①获取连接注意事项

  • properties的编写,注意直接连接的具体数据库
  • class.forName在加载驱动类时执行类中静态代码,已经从DriverMangement中注册(初始化)

②获取连接代码

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:13306/mytest?useUnicode=true&characterEncoding=utf8&useSSL=false
user=root
password=abc123
package com.likejin;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Properties;

public class MyTest2 {
    public static void main(String[] args) throws Exception {
        InputStream resourceAsStream = MyTest2.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);

        String driverClass = properties.getProperty("driverClass");
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");

        Class.forName(driverClass);
        Connection connection = DriverManager.getConnection(url, user, password);
        
    }
}

4.JAVA中使用statement来执行sql语句时,拼接字符串的sql注入问题?

①statement

  • 是通过获取连接之后利用其来执行sql语句
  • 原理:字符串拼接(由于数据必须通过’'来包含)

②sql注入问题

  • 实例场景:判断学生在数据库中是否有。
  • 代码
package com.likejin;

import com.likejin.util.Utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class MyTest3 {
    public static void main(String[] args) throws Exception {
        Connection conn = Utils.getconn();
        Statement statement = conn.createStatement();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入ID");
        String id =scanner.nextLine();
        System.out.println("请输入年龄");
        String age = scanner.nextLine();
        String sql = "select * from student where id = '"+ id + "' and age = '" +age+"'";
        System.out.println(sql);
        ResultSet resultSet = statement.executeQuery(sql);
        if(resultSet.next()){
            System.out.println("您找的学生在这个班级");
        }else{
            System.out.println("您找的学生不在这个班级");
        }
    }
}

  • 数据表
    在这里插入图片描述
  • 正常情况下
    在这里插入图片描述
    在这里插入图片描述
  • sql注入问题加上单引号
    在这里插入图片描述
  • sql注入 不加单引号
    在这里插入图片描述

5.使用preparedstatement进行增删改查

①preparedstatement的方法

  • setObject 来填充占位符
  • execute() 来执行增删改,返回boolean类型是否成功
  • executeQuery()来执行查,返回ResultSet结果集

②ResultSet的方法

  • next() 判断下一个是否存在,存在指正下移,返回true,不存在指正不动,返回false
  • getObject(i) 参数为行数据的第几列,返回的是某一行数据的某一列的具体数值
  • getMetaData()获取到ResultSetMetaData类型,该类型有方法:
    getColumnCount()返回具体列数
    getColumnName(i)返回某一列的名称

②注意事项

  • 注意数据库中列从第一列开始,而JAVA数据一般从0开始,故计算时注意+1。
  • 注意sql注入时参数也是从第一个开始的。
  • 注意封装类时需要设置属性为public,否则无法利用反射初始化值。
  • 注意如果要编写未知数据的查找(封装为该类的list),需要知道数据的类型:
    可以用泛型方法来传入封装的数据类型
    Class <T> clazz
    T t

②代码

package com.likejin.util;

import com.likejin.MyTest2;
import com.likejin.Student;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class Utils {
    public static Connection getconn() throws Exception {
        InputStream resourceAsStream = MyTest2.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);

        String driverClass = properties.getProperty("driverClass");
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");

        Class.forName(driverClass);
        Connection connection = DriverManager.getConnection(url, user, password);
        return connection;
    }

    //针对学生表的通用更新操作
    public static boolean updateData(String sql, Object... args) throws Exception {
        Connection conn = getconn();
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        for (int i = 0; i < args.length; i++) {
            preparedStatement.setObject(i + 1, args[i]);
        }
        boolean execute = preparedStatement.execute();
        preparedStatement.close();
        conn.close();
        return execute;
    }

    //针对学生表的通用查询操作(已知列数,已知对象,已知列名)
    public static List selectData(String sql, Object... args) throws Exception {
        Connection conn = getconn();
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        for (int i = 0; i < args.length; i++) {
            preparedStatement.setObject(i + 1, args[i]);
        }

        ResultSet resultSet = preparedStatement.executeQuery();
        ArrayList<Student> students = new ArrayList<>();
        int i = 0;
        while (resultSet.next()) {
            Student student = new Student();
            student.setId(resultSet.getInt(1));
            student.setAge(resultSet.getInt(2));
            student.setGrade(resultSet.getInt(3));
            i = i + 1;
            students.add(student);
        }
        return students;
    }

    //针对任何表的查询操作
    public static <T> List<T> selectData(Class<T> clazz,String sql, Object... args) throws Exception {
        Connection conn = getconn();
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        for (int i = 0; i < args.length; i++) {
            preparedStatement.setObject(i + 1, args[i]);
        }
        ArrayList<T> ts = new ArrayList<>();
        ResultSet resultSet = preparedStatement.executeQuery();
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();
        while(resultSet.next()){
            T t = clazz.newInstance();
            for(int i = 0;i<columnCount;i++){
                Field dd = clazz.getDeclaredField(metaData.getColumnName(i+1));
                dd.set(t,resultSet.getObject(i+1));
            }
            ts.add(t);
        }
        return ts;
    }
}

6.自定义通用查询方法

①缺点

  • 运行时类和类类型不同,无法在方法中就强转为需要的类类型。
    stuent.getClass() 或者Student.class都和 Student不同
  • 故如果想获得类类型,就需要运用泛型。
  • 举例说明
    如果想在传入方法中获取该类的类型如何获取?
    利用泛型 T t或者 Class<T> clazz都可获取类型为T
    利用Object o 获取不到类类型,最多获取运行时类的实例,故需要在获取方法的返回值后手动进行强转。
  • 对象获取到类类型的数据是什么?为什么不能强转?
    即最多获取到类类型字符串
    String typeName = o1.getClass().getTypeName();由于编译的限制,无法去利用字符串强转对象。

②代码

    //针对任何表的查询操作
    public static List selectData5(Object o,String sql, Object... args) throws Exception {
        //获取连接(拿到配置文件中的内容+注册driver+DriverMangement获取连接)
        InputStream resourceAsStream = Utils.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        final String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");

        Class.forName(properties.getProperty("driverClass"));
        Connection connection = DriverManager.getConnection(url, user, password);
        //连接的sql注入获取结果集
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for(int i = 0;i<args.length;i++){
            preparedStatement.setObject(i+1,args[i]);
        }
        ResultSet resultSet = preparedStatement.executeQuery();
        //处理结果集利用反射获取结果的列表
        ResultSetMetaData metaData = resultSet.getMetaData();
        ArrayList arrayList = new ArrayList();
        int columnCount = metaData.getColumnCount();
        while(resultSet.next()){
            Object o1 = o.getClass().newInstance();
            for(int i =0;i<columnCount;i++){
                String columnName = metaData.getColumnName(i + 1);
                Field field = o1.getClass().getField(columnName);
                field.set(o1, resultSet.getObject(i+1));
            }
            //无法转换为目标对象的类
            //因为o.getClass获取的是运行时类的类型,而不是实际类类型
            //故实际使用时需要转换类型输出
            arrayList.add(o1);
        }
        return arrayList;
    }

    public static void main(String[] args) throws Exception {
        String sql = "select * from student where id<?" ;
        List students1 =null;
        List list = selectData5(new Student(), sql, 10);
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println((Student)iterator.next());
        }
    }

未更新

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

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

相关文章

【Microsoft】与 Bing AI 进行 ⌈狂飙⌋

&#x1f38a; 今天是3月8号&#xff0c;❤️农历二月十七&#xff0c;&#x1f495;祝广大女同胞们&#x1f469;女神节快乐&#x1f389;&#xff01;——以创作之名致敬女性开发者文章目录序言Ⅰ、Bing AI初体验Ⅱ、代码生成Ⅲ、生成图像Ⅳ、使用次数Ⅴ、总结序言 ​ 近期&…

数据结构与算法之《顺序表》

目录 1.什么是顺序表 顺序表的优势和缺点 顺序表预备知识 顺序表的代码实现 顺序表头部插入 顺序表的销毁 顺序表的头删 顺序表的尾删 顺序表的尾插 顺序表的任意位置插入 顺序表的查找 顺序表的打印 1.什么是顺序表 这篇文章我们来讲一下基础数据结构的顺序表&…

Input子系统(一)启动篇

代码路径 基于AndroidS&#xff08;12.0&#xff09;代码 system/core/libutils/Threads.cppframeworks/base/services- java/com/android/server/SystemServer.java- core- java/com/android/server/input/InputManagerService.java- jni/com_android_server_input_InputMan…

三步 让你的 vscode 自动编译ts文件

三步让你的 vscode 自动编译ts文件 TypeScript环境安装与如何在vscode实现自动编译ts文件? 文章目录三步让你的 vscode 自动编译ts文件前提条件环境安装自动编译运行监视任务时报错&#xff1f;前提条件 安装 node 环境 环境安装 tsc 作用&#xff1a;负责将ts 代码 转为 浏…

感知器算法

感知器算法原理说明 感知器是一种二分类的线性分类算法&#xff0c;其原理基于神经元的工作原理。感知器将输入数据通过加权求和的方式映射到一个输出&#xff0c;然后根据输出的结果进行分类。 具体来说&#xff0c;给定一个训练集 D(x1,y1),(x2,y2),...,(xn,yn)D{(x_1,y_1)…

研报精选230308

目录 【行业230308东吴证券】电力设备行业深度报告&#xff1a;氢能深度&#xff1a;绿氢&#xff0c;第四次能源革命的载体【个股230308安信证券_沪光股份】优秀的民营汽车线束供应商&#xff0c;行业国产化替代空间广阔【行业230308中原证券】食品饮料行业2月月报&#xff1a…

银行数字化转型导师坚鹏:数字化转型为什么需要致良知与知行合一

在银行数字化转型过程中&#xff0c;特别需要致良知与知行合一哲学思想的指导。 知中有行&#xff0c;行中有知&#xff1b;行极而知&#xff0c;知极而行&#xff1b;知行无端&#xff0c;知行无始。知与行是一件事&#xff0c;做事与培养本体&#xff08;修心&#xff09;也是…

手动集成Tencent SDK遇到的坑!!!

手动集成的原因 由于腾讯未把Tencent SDK上传到Github中&#xff0c;所以我们不能通过Cocoapods的方式集成&#xff0c;只能通过官方下载其SDK手动集成。 Tencent SDK手动集成步骤 1.访问腾讯开放平台SDK下载界面&#xff0c;找到并下载iOS_SDK_V3.5.1。&#xff08;目前最新…

数组(四)-- LC[167] 两数之和-有序数组

1 两数之和 1.1 题目描述 题目链接&#xff1a;https://leetcode.cn/problems/two-sum/description/ 1.2 求解思路 1. 暴力枚举 最容易想到的方法是枚举数组中的每一个数 x&#xff0c;寻找数组中是否存在 target - x 参考代码 class Solution(object):def twoSum(self, n…

Nginx学习(3)—— 反向代理、负载均衡、动静分离、URLRewrite、防盗链

文章目录网关、代理与反向代理Nginx的反向代理配置基于反向代理的负载均衡的配置负载均衡策略负载均衡权重相关配置&#xff08;weight&#xff09;动静分离Nginx配置动静分离URL-rewrite伪静态配置负载均衡URL-rewrite防盗链网关、代理与反向代理 什么是反向代理&#xff1a;…

在linux上部署Java项目

在Linux部署Java环境 要是想要部署java web程序,首先要配置环境 jdk tomcat mysql 安装jdk 推荐的方法是使用yum直接安装openjdk(开源的,与官方的jdk功能差不多),目前使用的最多的就是jdk8系列 yum list | grep jdk 在源上搜索所有关于jdk的文件 devel表示development的意思…

3.8多线程

案例一-线程安全的单例模式(面试)是一种设计模式,设计模式针对写代码时的一些常见场景给出一些经典解决方案单例模式的两种典型实现饿汉模式懒汉模式饿汉的单例模式:比较着急去进行创建实例懒汉的单例模式,是不太着急创建实例,,只是在用的时候,才真正创建这个是类对象,也就是.c…

【C++修炼之路】26.C++11(语法糖)

每一个不曾起舞的日子都是对生命的辜负 C11C11(语法糖)本节目标一.C11简介二.统一的列表初始化2.1 {}初始化2.2 std::initializer_list三.声明3.1 auto3.2 decltype3.3 nullptr四.总结C11(语法糖) 本节目标 C11简介 列表初始化 变量类型推导 一.C11简介 在2003年C标准委员…

信息收集-

url&#xff1a; https://en.wikipedia.org:443/wiki/hypertext_Transfer_Protocol?id123#HTTP/1.1_response_messages https&#xff1a;协议 en.wikipedia.org&#xff1a;域名 443&#xff1a;端口 wiki/hypertext_Transfer_Protocol&#xff1a;文件路径 id123&…

Unity 混合操作(Blending)

渲染图形时&#xff0c;在执行所有着色器并应用所有纹理后&#xff0c;像素将写入到屏幕。这些像素与已有像素的组合方式由 Blend 命令控制。用于生成透明对象。《Unity Shader入门精要》大致解释&#xff1a;片元通过了模板测试和深度测试之后&#xff0c;会进行混合步骤。如果…

三、SpringMVC的拦截器

1. SpringMVC的拦截器 针对请求和响应进行的额外的处理.在请求和响应的过程中添加预处理,后处理和最终处理. 2. 拦截器的应用场景 1、日志记录&#xff1a;记录请求信息的日志 2、权限检查&#xff0c;如登录检查 3、性能检测&#xff1a;检测方法的执行时间 3. 拦截器执行的…

调用一个函数时发生了什么?

欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e;&#x1f49e; 前言&#xff1a; 用C语言写代码&#xff0c;如果一个工程相对复杂时&#xff0c;我们往往会采取封装函数的方式。在主函数中调用函数 这一看似简单的过程&#xff0c;实际上有很多不宜观察的细节&#xff0…

计算机组成原理|第三章(笔记)

目录第三章 系统总线3.1 总线的基本概念3.2 总线的分类3.2.1 片内总线3.2.2 系统总线3.2.3 通信总线3.3 总线特性及性能指标3.3.1 总线的特性3.3.2 总线性能指标3.4 总线结构3.4.1 单总线结构3.4.2 多总线结构3.4.3 总线结构举例3.5 总线控制3.5.1 总线判优控制3.5.2 总线通信控…

ALG和STUN

目录 ALG 应用层网关讲解 Client1使用FTP主动模式建立FTP Client1使用FTP被动模式建立FTP STUN讲解 ALG 应用层网关讲解 用来替换应用层信息 Client1使用FTP主动模式建立FTP 主动模式&#xff1a;服务器收到客户端发来的请求FTP的地址和端口 服务器使用20端口直接向客户端建…

webpack dll 提升构建速度

DLL&#xff0c;动态链接库&#xff08;Dynamic Link Library 或者 Dynamic-link Library&#xff09;&#xff0c;由微软公司提出。目的是为了节约应用程序所需的磁盘和内存空间。 在一个传统的非共享库中&#xff0c;如果两个程序调用同一个子程序&#xff0c;就会出现两份那…