JAVA全栈开发 day19_JDBC

一、JDBC

1.JDBC概述

1.1什么是jdbc

Java DataBase Connectivity是一种用于执行SQL语句的Java API,它由一组用Java语言编写的类和接口组成。通过这些类和接口,JDBC把SQL语句发送给不同类型的数据库进行处理并接收处理结果。

1.2jdbc的作用

提供java 操作不同数据库的技术

1.3JDBC两大类

对Java开发人员而言是API,对数据库提供商而言是接口。

面向开发人员:作为API,JDBC为程序开发提供标准的接口。

面向数据库厂商:作为接口,让数据库厂商按标准方法来实现数据库连接与操作(数据库驱动程序)。

在这里插入图片描述

1.4JDBC工作过程

在这里插入图片描述

2.Jdbc数据库连接

  1. 下载Jar

下载jarhttps://blog.csdn.net/qq_35368140/article/details/131246017

  1. 引入Jar (包括jdbc 驱动程序 )

引入jarhttps://blog.csdn.net/qq_43599841/article/details/127368168%5D

  1. JDBC 使用步骤

    ​ 1. 加载驱动 (只会运行一次:static)

    ​ 2. 获得链接对象 Connection

    ​ 3. 获得执行对象 Statement

    ​ 4. 执行sql并获得结果集(ResultSet)

    ​ 5. 处理结果集

    6.释放资源

    public static void main(String[] args) throws SQLException {//1.注册驱动 告诉jdbc我们使用哪一个数据库厂商的驱动//驱动管理器专门注册驱动(需要传递一个驱动对象)DriverManager.registerDriver(new com.mysql.jdbc.Driver());//2. 建立驱动连接//url:链接数据库的地址  jdbc:mysql://localhost:3306/数据库的名字//user:用户名//password:密码//面向接口编程Connection connection = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/j352", "root", "");//3.创建向数据库发送sql的statement对象Statement st = connection.createStatement();//4.发送sql后获得一个封装了查询结果的ResultSet对象ResultSet rs = st.executeQuery("select * from student limit 1");//5.解析ResultSet对象获得结果if(rs.next()) {System.out.println("id:"+rs.getObject("Id"));System.out.println("name:"+rs.getObject("StudentName"));System.out.println("age:"+rs.getObject("age"));}//释放资源rs.close();st.close();connection.close();}
    

二、Api详解

1 注册驱动

DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用

原因有2个:

>导致驱动被注册2次。

>强烈依赖数据库的驱动jar

解决办法:

注册驱动的第二种方式

Class.forName(“com.mysql.jdbc.Driver”);

2 获取链接

static Connection getConnection(String url, String user, String password)试图建立到给定数据库 URL 的连接。参数说明:url 需要连接数据库的位置(网址) user用户名 password 密码例如:getConnection("jdbc:mysql://localhost:3306/数据库名称", "root", "");URL:SUN公司与数据库厂商之间的一种协议。jdbc:mysql://localhost:3306/数据库名称协议 子协议 IP : 端口号 数据库
常用数据库URL地址的写法: 
Oracle写法:jdbc:oracle:thin:@localhost:1521:sid 
SqlServer jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=sid 
MySql jdbc:mysql://localhost:3306/sid 
Mysql的url地址的简写形式: jdbc:mysql:///sid 
常用属性:useUnicode=true&characterEncoding=UTF-8

接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。

Statement createStatement(); //创建操作sql语句的对象

3 API详解:java.sql.Statement接口: 操作sql语句,并返回相应结果

String sql = “某SQL语句”;

获取Statement语句执行平台:Statement stmt = con.createStatement();

常用方法:

int executeUpdate(String sql); --执行insert update delete语句.

ResultSet executeQuery(String sql); --执行select语句.

boolean execute(String sql); --仅当执行select并且有结果时才返回true,执行其他的语句返回false.

 //1.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取链接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","root");//3.获取代表向数据库发送sql的statement对象Statement st = conn.createStatement();String sql="insert into student(name,age) values('奥利给','20')";//4.发送sql//返回影响的行数 大于0代表执行成功int result = st.executeUpdate(sql);if(result>0) {System.out.println("插入成功");}//5.释放资源st.close();conn.close();

4 API详解:处理结果集(注:执行insert、update、delete无需处理)

ResultSet实际上就是一张二维的表格,我们可以调用其boolean next()方法指向某行记录,当第一次调用next()方法

时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法(与索引从0开始不同个,列从1

开始)来获取指定列的数据:

rs.next();//指向第下一行

rs.getObject(1);//获取第一行第一列的数据

在这里插入图片描述

常用方法:

n Object getObject(int index) / Object getObject(String name) 获得任意对象

n String getString(int index)/ String getString(String name) 获得字符串

n int getInt(int index)/int getInt(String name) 获得整形

n double getDouble(int index)/ double getDouble(String name) 获得双精度浮点型

在这里插入图片描述

5 释放资源

与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。

rs.close();  //结果集stmt.close(); //statement对象con.close(); //连接对象

6 关闭异常处理

public static void main(String[] args) throws Exception {//1.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取链接Connection conn =null;Statement st=null;ResultSet rs=null;try {//2.获取链接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","root");//3.获取代表向数据库发送sql的statement对象st = conn.createStatement();String sql="select id,name,age from student";//4.发送sqlrs = st.executeQuery(sql);//定义集合封装Student数据List<Student> list=new ArrayList<Student>();while(rs.next()) {//查询出来的结果封装到对象中Student s=new Student();s.setId(rs.getInt("id"));s.setAge(rs.getInt("age"));s.setName(rs.getString("name"));list.add(s);}System.out.println(list);}finally {//5.释放资源//关闭资源之前一定要判断if(rs!=null) {try {rs.close();}catch (Exception e) {e.printStackTrace();}//让jvm回收没有被关闭的rs对象rs=null;}if(st!=null) {try {st.close();}catch (Exception e) {e.printStackTrace();}st=null;}if(conn!=null) {try {conn.close();}catch (Exception e) {e.printStackTrace();}conn=null;}}}}

三、封装JDBC

  1. 提交公共方法(获取连接,释放资源)
  2. 将这两方法,提到一个类中
  3. 将数据库连接url, 用户名,密码,放到文件中,把它变成可以配置的

步骤1,步骤2:

public class JdbcUtils {static {//1.注册驱动  告诉jdbc我们使用哪一个数据库厂商的驱动try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}// 项目一旦交付// 公司(乙)  做项目(产品)  =》   给别人做项目(甲)//                                部署(运维)-》 配置文件public static Connection GetConnection() throws ClassNotFoundException, SQLException {//2.通过驱动管理器获取一个链接Connection connection = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/j352", "root", "");return  connection;}public static void release(Connection conn, Statement sm , ResultSet rs){if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}rs =null; //让jvm来回收它}if(sm!=null){try {sm.close();} catch (SQLException e) {e.printStackTrace();}sm =null; //让jvm来回收它}if(conn!=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}conn =null; //让jvm来回收它}}
}

步骤3: 将数据库连接url, 用户名,密码,放到文件中,把它变成可以配置的

Properties

在这里插入图片描述

使用properties后的代码

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/j352
username=root
password=
public class JdbcUtils {private static Properties properties = new Properties();static {//1.注册驱动  告诉jdbc我们使用哪一个数据库厂商的驱动try {//1.1 读取文件中的信息FileInputStream in = null;try {in = new FileInputStream("src\\jdbc.properties");} catch (FileNotFoundException e) {throw new RuntimeException(e);}// 1.2  Properties对象中有一个load方法properties.load(in);  //将文件相关的信息加载到properties 对象中Class.forName(properties.getProperty("driverClassName"));} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}// 项目一旦交付// 公司(乙)  做项目(产品)  =》   给别人做项目(甲)//                                部署(运维)-》 配置文件public static Connection GetConnection() throws ClassNotFoundException, SQLException, IOException {// 读取文件中的数据 jdbc.properties ,进行使用//String getProperty(String key)//2.通过驱动管理器获取一个链接Connection connection = (Connection) DriverManager.getConnection(properties.getProperty("url"),properties.getProperty("username"), properties.getProperty("password"));return  connection;}public static void release(Connection conn, Statement sm , ResultSet rs){if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}rs =null; //让jvm来回收它}if(sm!=null){try {sm.close();} catch (SQLException e) {e.printStackTrace();}sm =null; //让jvm来回收它}if(conn!=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}conn =null; //让jvm来回收它}}
}

四、SQL注入

登录

如果执行的sql语句,是用字符串进行拼接, 就容易出sql 注入

在这里插入图片描述

如何防止sql注入

  1. 输入时,不让它输入特殊字符 ,正则(只输入字母或数字 )

  2. 执行sql时不用sql拼接,而使用参数化查询

    public int login(String username, String pwd) {int result = 0;Connection conn = null; //创建连接
    //        Statement statement = null;PreparedStatement pst = null;ResultSet resultSet = null;try {conn = JdbcUtils.GetConnection();// 查询String sql = "select * from user where username=? and pwd=? ";pst = conn.prepareStatement(sql);pst.setString(1,username);pst.setString(2,pwd);System.out.println(sql);resultSet = pst.executeQuery(sql);if (resultSet.next()) {result = 1;}}  catch (ClassNotFoundException e) {result = 2;e.printStackTrace();
    //                throw new RuntimeException(e);} catch (SQLException e) {result = 3;e.printStackTrace();} catch (IOException e) {result = 4;e.printStackTrace();}finally {JdbcUtils.release(conn,pst,resultSet);}return  result;}

五、Jdbc控制事务

1.java中事务的控制

conn.setAutoCommit(false) == start transaction;

conn.commit() == commit;

conn.rollback(); == rollback;

public class TransactionDemo {public static void main(String[] args) {// 1. 获取连接Connection connection =  null;PreparedStatement statement = null;ResultSet resultSet = null;try{connection = JdbcUtils.GetConnection();//2. 事务开启connection.setAutoCommit(false);String sql = "update user set age = 18 where username='admin'";statement = connection.prepareStatement(sql);statement.executeUpdate(); //执行sql//            int x= 1/ 0 ;String sql2 = "update user set age = 28 where username='doubleyong'";statement = connection.prepareStatement(sql2);statement.executeUpdate(); //执行sql// 3。提交事务connection.commit();}catch (Exception e){//关闭事务try {connection.rollback();
//                connection.commit();} catch (SQLException ex) {throw new RuntimeException(ex);}e.printStackTrace();}finally {JdbcUtils.release(connection,statement,resultSet);}}
}

2.事务的回滚点

回滚到指定位置

savepoint = conn.setSavepoint();

 public static void main(String[] args) {// 1. 获取连接Connection connection =  null;PreparedStatement statement = null;ResultSet resultSet = null;Savepoint savepoint=null;try{connection = JdbcUtils.GetConnection();//2. 事务开启connection.setAutoCommit(false);String sql = "update user set age = 66 where username='admin'";statement = connection.prepareStatement(sql);statement.executeUpdate(); //执行sql//设置一个事务的回滚点savepoint = connection.setSavepoint();int x= 1/ 0 ;String sql2 = "update user set age = 77 where username='doubleyong'";statement = connection.prepareStatement(sql2);statement.executeUpdate(); //执行sql// 3。提交事务connection.commit();}catch (Exception e){//关闭事务try {connection.rollback(savepoint); //回滚到指定事物点connection.commit(); //回滚后,如何 还是有sql执行,必须 加上commit } catch (SQLException ex) {throw new RuntimeException(ex);}e.printStackTrace();}finally {JdbcUtils.release(connection,statement,resultSet);}}

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

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

相关文章

非常抱歉的通知

非常感谢有这么多的同志向我提问一些问题&#xff0c;也非常感谢很多的同志可以看我的学习文章&#xff0c;这次大概有四五个月没有上csdn&#xff0c;看到了许多同志的疑问和慰问&#xff0c;我也很感动&#xff0c;但是由于我自己以及其他的原因&#xff0c;我现在打算以考编…

【目标检测从零开始】torch搭建yolov3模型

用torch从0简单实现一个的yolov3模型&#xff0c;主要分为Backbone、Neck、Head三部分 目录 Backbone&#xff1a;DarkNet53结构简介代码实现Step1&#xff1a;导入相关库Step2&#xff1a;搭建基本的Conv-BN-LeakyReLUStep3&#xff1a;组成残差连接块Step4&#xff1a;搭建Da…

思维模型 色彩心理效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知色彩影响情绪。 1 色彩心理效应的应用 1.1 色彩心理效应在营销中的应用 1 可口可乐公司的“红色”营销 可口可乐公司是全球最著名的饮料品牌之一&#xff0c;其标志性的红色包装已经成为了…

Constraining Async Clock Domain Crossing

Constraining Async Clock Domain Crossing 我们在normal STA中只会去check 同步clock之间的timing,但是design中往往会存在很多CDC paths,这些paths需要被正确约束才能保证design function正确,那么怎么去约束这些CDC paths呢? 以下面的design为例,如下图所示 这里clk…

Spring Kafka常用配置详解

目录 前言producer配置consumer 配置listener 配置 前言 在 Spring Kafka 中&#xff0c;主要的配置分为三大块&#xff0c;分别是producer、consumer、listener&#xff0c;下面我们就按模块介绍各个模块的常用配置 producer配置 在 Spring Kafka 中&#xff0c;spring.kaf…

小红书蒲公英平台开通后,有哪些注意的地方,以及如何进行报价?

今天来给大家聊聊当小红书账号过1000粉后&#xff0c;开通蒲公英需要注意的事项。 蒲公英平台是小红书APP中的一个专为内容创作者设计的平台。它为品牌和创作者提供了一个完整的服务流程&#xff0c;包括内容的创作、推广、互动以及转换等多个方面。 2.蒲公英平台的主要功能 &…

【C语言】vfprintf函数

vfprintf 是 C 语言中的一个函数&#xff0c;它是 fprintf 函数的变体&#xff0c;用于格式化输出到文件中。vfprintf 函数接受一个格式化字符串和一个指向可变参数列表的指针&#xff0c;这个列表通常是通过 va_list 类型来传递的。vfprintf 函数的主要用途是在需要处理不定数…

NGINX安装升级

nginx介绍 Nginx的版本分为开发版、稳定版和过期版&#xff0c;nginx以功能丰富著称&#xff0c;它即可以作为http服务器&#xff0c;也可以作为反向代理服务器或者邮件服务器&#xff0c;也可以作为反向代理服务器或者邮件服务器&#xff0c;能够快速的响应静态网页的请求&am…

vue+django 开发环境跨域前后端联调配置

vue环境是127.0.0.1:8080&#xff0c;django环境是127.0.0.1:8000 要解决url相对路径和Axios跨域权限问题。 注意&#xff1a;程序发起了一个 POST 请求&#xff0c;但请求的 URL 没有以斜杠结尾。Django 默认设置是无法执行重定向到带斜杠 URL的。例如&#xff1a;url http:/…

远传智能水表一般应用于哪些场景?

远传智能水表是一种在水表领域应用广泛的创新技术&#xff0c;它利用物联网和无线通信技术使水表具备了远程监测和数据传输的能力。这种智能水表的应用场景多种多样&#xff0c;可适用于各个领域和环境。那么&#xff0c;远传智能水表一般应用于哪些场景呢&#xff1f; 首先&am…

ElasticSearch之Refresh API

使用本方法&#xff0c;显式的执行refresh操作。 默认情况下&#xff0c;ElasticSearch启动后台任务&#xff0c;周期性执行refresh操作&#xff0c;周期使用参数index.refresh_interval控制。 本方法触发的refresh为同步操作&#xff0c;运行完毕之后才会返回任务的执行结果。…

CPU密集型和IO密集型任务

1. CPU密集型任务 1.1 定义 CPU密集型任务是指在任务执行过程中&#xff0c;主要由计算操作占用大部分时间&#xff0c;而不是等待外部资源的任务类型。 1.2 特点 计算密集性&#xff1a; 需要大量的数学运算、逻辑判断和数据处理。高CPU利用率&#xff1a; 任务执行期间&a…

9.关于Java的程序设计-基于Springboot的家政平台管理系统设计与实现

摘要 随着社会的进步和生活水平的提高&#xff0c;家政服务作为一种重要的生活服务方式逐渐受到人们的关注。本研究基于Spring Boot框架&#xff0c;设计并实现了一种家政平台管理系统&#xff0c;旨在提供一个便捷高效的家政服务管理解决方案。系统涵盖了用户注册登录、家政服…

mybatis数据输出-map类型输出

1、建库建表 create table emp (empNo varchar(10) null,empName varchar(100) null,sal int null,deptno varchar(10) null ); 2、pom.xml <dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis<…

氧化性低密度脂蛋白抗体原料——博迈伦生物

氧化性低密度脂蛋白抗体原料——博迈伦生物 引言 氧化性低密度脂蛋白&#xff08;oxLDL&#xff09;是动脉粥样硬化等心血管疾病的关键因素之一。抗体作为诊断和研究工具&#xff0c;在oxLDL的检测和相关疾病的研究中发挥着重要作用。本文将深入探讨氧化性低密度脂蛋白抗体原料…

Elasticsearch 8.9 flush刷新缓存中的数据到磁盘源码

一、相关API的handler1、接收HTTP请求的hander2、每一个数据节点(node)执行分片刷新的action是TransportShardFlushAction 二、对indexShard执行刷新请求1、首先获取读锁&#xff0c;再获取刷新锁&#xff0c;如果获取不到根据参数决定是否直接返回还是等待2、在刷新之后transl…

芯知识 | 如何选择合适的单片机语音芯片?

随着科技的飞速发展&#xff0c;单片机语音芯片已经广泛应用于各个领域。然而&#xff0c;在众多的芯片产品中&#xff0c;如何选择合适的单片机语音芯片成为了一个重要的问题。本文将为您提供一些建议&#xff0c;助您找到最适合您需求的单片机语音芯片。 一、明确需求 在选…

Android Audio实战——音频链路分析(二十五)

在 Android 系统的开发过程当中,音频异常问题通常有如下几类:无声、调节不了声音、爆音、声音卡顿和声音效果异常(忽大忽小,低音缺失等)等。尤其声音效果这部分问题通常从日志上信息量较少,相对难定位根因。想要分析此类问题,便需要对声音传输链路有一定的了解,能够在链…

AI发展下服务器的选择非常重要

在AI发展下&#xff0c;服务器的选择非常重要。以下是一些选择服务器时需要考虑的因素&#xff1a; 1. 计算能力&#xff1a;AI需要大量的计算资源来进行训练和推理。因此&#xff0c;选择具有强大计算能力的服务器是至关重要的。 2. 内存容量&#xff1a;AI需要大量的内存来…

cryptojs加密和java解密:AES算法

试了一下午终于跑通了&#xff0c;一开始尝试RC4算法生成的密文在java中解密不出来&#xff0c;放弃了&#xff0c;改用AES。 js代码 import aes from crypto-js/aes; import base from crypto-js/enc-base64;function encrypt(plaintext: string) {const iv base.parse(ZGY…