day23_jdbc详解

JDBC

JDBC概述

什么jdbc

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

jdbc的作用

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

JDBC两大类

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

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

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

在这里插入图片描述

JDBC工作过程

在这里插入图片描述

Jdbc数据库连接

1.下载Jar
官网连接
(注意与自的mysql版本匹配哦)随便选择一个下载
在这里插入图片描述

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

  1. JDBC 使用步骤

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

    ​ 2. 获得链接对象 Connection

    ​ 3. 获得执行对象 Statement

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

    ​ 5. 处理结果集

    1. 释放资源
    public static void main(String[] args) throws SQLException {//1.注册驱动 告诉jdbc我们使用哪一个数据库厂商的驱动//驱动管理器专门注册驱动(需要传递一个驱动对象)// DriverManager.registerDriver(new com.mysql.jdbc.Driver());Class.forName("com.mysql.jdbc.Driver");//2. 建立驱动连接//url:链接数据库的地址  jdbc:mysql://localhost:3306/数据库的名字//user:用户名//password:密码//面向接口编程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();
    }
    

2.Api详解

2.1 注册驱动

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

原因有2个:

>导致驱动被注册2次。

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

解决办法:

注册驱动的第二种方式

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

2.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语句的对象

2.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();

2.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) 获得双精度浮点型

在这里插入图片描述

2.5 释放资源

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

rs.close(); //结果集

stmt.close(); //statement对象

con.close(); //连接对象

2.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. 将这两方法,提到一个类中 JdbcUtils

  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=xxx
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控制事务

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);}}
}

事务的回滚点

回滚到指定位置

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);}}

= 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.hqwc.cn/news/267339.html

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

相关文章

Blender学习--制作带骨骼动画的机器人

1. 首先创建一个机器人模型 时间关系&#xff0c;这部分步骤有时间补充 2. 然后为机器人创建一副骨架 时间关系&#xff0c;这部分步骤有时间补充 3.骨骼绑定 切换到物体模式&#xff0c;选中机器人头部&#xff0c;Shift选中骨骼&#xff0c;切换到姿态模式&#xff0c;&am…

【Linux】进程周边002之进程状态

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.什么是状态&#xff1f; …

零拷贝的方式以及理解

零拷贝的方式以及理解 DMAmmapsendfilesendfile DMA scatter / Gatherdirect I/O 上一篇: 什么是零拷贝 DMA 正常的IO流程中&#xff0c;不管是物理设备之间的数据拷贝&#xff08;比如&#xff1a;磁盘到内存&#xff09;&#xff0c;还是内存之间的数据拷贝&#xff08;比…

rv1126-rv1109-以太网功能-eth-(调试篇)

先参考:以太网常见问题处理方法排查手册.pdf 调试指令: 1.首先dts修改 参考:Rockchip_Developer_Guide_Linux_GMAC_Mode_Configuration_CN.pdf 2.芯片地址尝试匹配 0~3地址都试下 &mdio { phy: phy0 { compatible "ethernet-phy-ieee802.3-c22"; reg <0…

C++之STL算法(1)

STL容器算法主要由、、组成&#xff1b;   algorithm主要有遍历、比较、交换、查找、拷贝、修改等&#xff1b; 1.遍历容器for_each for_each()函数用于完成容器遍历&#xff0c;函数参数如下&#xff1a; for_each(_InIt _First, _InIt _Last, _Fn _Func) 形参&#xff1a…

中伟视界:煤矿行业借力人工智能,防控灾害风险迈出新步伐 《“十四五”矿山安全生产规划》(应急(2022)64号),煤矿重大灾害风险防控系统

随着煤矿行业的发展&#xff0c;煤矿重大灾害风险防控成为了行业关注的重点之一。为了更好地预防和应对灾害风险&#xff0c;煤矿行业开始引入人工智能分析算法和检测场景&#xff0c;以提高灾害风险的识别和预警能力。 在煤矿的重大灾害风险防控中&#xff0c;AI算法发挥着重要…

MachMap:End-to-End Vectorized Solution for Compact HD-Map Construction

参考代码&#xff1a;None 动机与出发点 地平线的MapTR展现出了构建高精地图的能力&#xff0c;但是它的机制确实是有点复杂了。为了兼容不同车道线的朝向&#xff0c;环形车道线的起终点等情况&#xff0c;针对性设计了permute-equal的匹配逻辑&#xff0c;这样的逻辑真的是太…

VMWARE虚拟机无法正常复制粘贴

解决办法&#xff1a; 只要你拿25块钱给我&#xff0c;我立刻协助你完成这个任务&#xff0c;而且帮助你做到可以复制粘贴文件哈哈哈&#xff0c;搞不好不要钱&#xff0c;微信付款 我仔细看了&#xff0c;全网没有一个全面的解决方法&#xff0c;我这个是最全面的

以csv为源 flink 创建paimon 临时表相关 join 操作

目录 概述配置关键配置测试启动 kyuubi执行配置中的命令 bug解决bug01bug02 结束 概述 目标&#xff1a;生产中有需要外部源数据做paimon的数据源&#xff0c;生成临时表&#xff0c;以使用与现有正式表做相关统计及 join 操作。 环境&#xff1a;各组件版本如下 kyuubi 1.8…

【Kubernetes】存储类StorageClass

存储类StorageClass 一、StorageClass介绍二、安装nfs provisioner&#xff0c;用于配合存储类动态生成pv2.1、创建运行nfs-provisioner需要的sa账号2.2、对sa授权2.3、安装nfs-provisioner程序 三、创建storageclass&#xff0c;动态供给pv四、创建pvc&#xff0c;通过storage…

智能优化算法应用:基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于阴阳对算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.阴阳对算法4.实验参数设定5.算法结果6.参考文…

近期Chrome浏览器 不知哪个版本升级后原先http强制跳转到https,导致服务端302强制跳转到http也没反应

关于Chrome更新http强制跳转到https解决方法 近期Chrome浏览器 不知哪个版本升级后原先http强制跳转到https&#xff0c;导致服务端302强制跳转到http也没反应一、F12检查加载的Response Headers中有没有Non-Authoritative-Reason二、找了资料后得到解决方案&#xff1a;三、找…