JDBC笔记

1.jdbc入门原理:

面向接口编程,就是面向抽象编程。

由于 每个数据库厂家是=底层原理不同,所以如果没有这个接口,程序员需要对每个数据库都写一套程序。
所以sun公司定义了一个接口,用于连接数据库与Java。

关系图如下:
接口类似一个库文件,各个数据库厂家写java程序实现自己的数据库。也就是为jdbc接口写实现类。这些实现类要去官网下载,一个jar包。这些实现类也叫驱动。
程序员也是面向这个接口编程,直接调用。
请添加图片描述

2.jdbc连接六步

  1. 注册驱动(告诉java要处理的是什么厂家的数据库)
  2. 获取连接(表示jvm的进程和数据库进程直接的通道打开了,这属于进程之间的通信,重量级的使用完一定要关闭)
  3. 获取数据库操作对象(专门执行sql语句)
  4. 执行sql语句(DQL,DML……)
  5. 处理查询结果集(只有第四步执行的是查询语句,才有这一步)
  6. 释放资源(使用完资源以后一定要关闭资源,java和数据库属于进程间的通信,开启以后一定要关闭)

3.第一步——注册驱动

第一种方法(原理方法,但是不常用):

直接使用一个方法

//驱动程序管理器.注册驱动程序(驱动接口)
DriverManager.registerDriver(new com.mysql.jdbc.Driver);

这里,括号里面的Driver是一个代表驱动的接口程序,然后各个公司来实现它。
他在java.sql.Driver
然后我们传的是数据库厂家做的实现类
也就是com.mysql,jdbc,Driver 与接口同名的实现类

第一步结束,也就是告诉java我们连接的是哪个数据库。

第二种方法(常用,因为里面有一个静态代码块执行上面那个语句,类加载,静态代码块就执行了)

//既然只要类加载就可以,那就用反射把类加载了
Class.forName("com.mysql.jdbc.Driver");

为什么这种方式常用?因为参数是字符串,字符串可以写在xxx.properties文件中。

4.第二部——获取连接

怎么获取连接呢?是通过DriverManager下的一个方法getConnection(url,use,password)
这是个静态方法,直接用就可以,返回的是一个Connect对象,说明连接成功建立

其中,url:统一资源定位符(网络中某个资源的绝对路径)
包括:协议+ip+端口+数据库名(协议是通信标准,ip代表主机是哪个,端口代表软件是哪个,然后再指定这个软件的哪个资源(数据库名字))

user是用户名,password是密码

如下

String url = "jdbc:mysql://127.0.0.1:3306/abc";
String user = "root";
String password  = "333";
Connect conn = DriveerManager.getConnection(url,user.password);

5.第三步——获取数据库操作对象

就是Statement,专门用于执行sql语句,它由刚才建立的连接,的一个方法创建

Statement stmt = conn.createStatement();

6.第四步——执行sql语句

先把sql写成字符串,再执行

//增删改,返回数量
//直接用操作对象的这个方法执行,返回的int数据是指几条语句受到影响
String sql = "insert into abc(xx,xxx,xx) values(xxx,xx,xx)";
int count = stmt.exeuteUpdate(sql);		//这个是对于增删改的语句
//查询语句,返回结果集
String sql = "select empno,ename,sal from emp";
ResultSet rs = stmt.executeQuery(sql);  	//一般rs的定义在try外部

由于select的结果需要显示,并不是操作了就完事了,所以需要在处理一下

7.第五步——处理查询结果集

rs是一个游标,一开始指着第0行,我们通过next往下走,通过getString()或者getInt()或者getDouble()获取本行第几列的元素
在这里插入图片描述

boolean flag = rs.next();	//这里是向下走一行
String empno = rs.getString(1);	//获取本行第一列
//或者
String empno = rs.getString(“name”);	//获取本行name那一列(这里注意,列名称不是表的列名称,是查询结果的列名称)
int id = rs.getInt("id")		//取数字

打印表的话,就是用个while循环

8.第六步——释放资源

先关小的,再关大的

rs.close
stmt.close();
conn.close();

分开try,catch SQLExeception。前面那些也都要放在try里,这个释放要卸载finally里,无论怎么样都要释放
一般rs的定义在try外部,不然finally里作用域关不了,同样连接和操作对象也是这样。

9.SQL注入

1.注入问题现象及原因

现象:随便输一个用户名,然后密码输一个

'xxxx' or '1' = '1'

就能直接破解进入数据库

原因:用户输入的信息中,含有sql语句的关键字,并且这些关键字参与sql语句的编译过程

因为我们的sql语句在字符串里

String sql = "selet * from tbale where user = " + user + "and password = " + password;

我们像这样把语句拼接起来,然后对比where是否正确,但是我们如果用上述的注入,就会变成

String sql = "selet * from tbale where user = " + user + "and password =  'xxxx' or '1' = '1';

这样就是一个或条件,无论前面的密码有没有,都会返回true

2.注入问题解决——PerparedStatement

只要用户提供的信息不参与sql语句的编译过程,问题就解决了
即使用户提供的信息中含有sql关键字,不参与编译就不起作用
要想不参与,就要用java.sql.PerparedStatement

PerparedStatement是预编译的数据库操作对象,原理是预先对sql语句框架进行编译,然后再给sql传值

//先写sql语句,再获取这个语句对应的数据库操作对象
//对于参数,用?这个占位符占位即可
String sql = "selet * from tbale where user = ? and password =  ?";

//传给数据库操作对象,这里perpare没有d,因为是动作,p也不大写,因为是方法不是类。
PerparedStatement ps = conn.perpareStatement(sql);

//然后传参数,第一个问号对应着下标1(jdbc都是从1开始)
ps.setString(1,name);
ps.setString(2,password);

//然后再获取查寻结果集,这里要记住不能再传了,因为再传还要再编译
rs = ps.executeQuery();

与普通的操作的不同点

  1. statement:先获取操作对象statement--------->再写sql语句,参数用加号拼接--------->再把sql语句传入查询结果集
  2. PerparedStatement:先写sql语句,有参数的部分用?作为占位符--------->传入预编译数据库操作对象进行预编译--------->再传参数,通过下标一个一个传--------->最后进行处理查询结果集,这里不需要传入sql语句,sql已经在操作对象中了

PerparedStatement更快,因为他相同功能语句样子都一样, mysql中相同的语句只用编译一次,所以编译一次可以执行n次。但是statement每次因为都要拼接,所以每次都要编译、

PerparedStatement输入参数的时候,也就是ps.setString(1,name);这一步会进行类型的安全检查,所以更安全。

综上:PerparedStatement没有sql注入、性能更好、更安全。

(有注入的需求,就必须用statement了:也就是需要进行拼接,比如升序降序,我们要传dsc和asc,进行sql拼接,而papare的只能传字符串的还有其他的类型,不能拼接编译)

10.jdbc事务

  • jdbc中事务是自动提交的,也就是一条dml就自动提交一条
  • 实际业务开发中,为墨门更需要多条一起执行
//关闭自动提交
conn.setAutoCommit(false);

//手动提交,代表事务结束
conn.commit();

//捕捉到一次,手动回滚,事务没完成,那么就回滚到事务开始时候的状态
conn.rollback

11.工具类

  • 工具类的构造方法都是私有的,因为都是静态方法不用实例化

把注册驱动方法放在工具类的静态代码块里,使用工具类时候自动执行,并且只会执行一次。

建立连接的封装到一个静态方法里。

把关闭的都封装的一个静态方法。

12.悲观锁和乐观锁

行级锁(悲观锁):

  • 在查询的时候,在后边加一个for update,就是上锁,这个表里所有符合job = dd 的记录,其他事务都不能修改了
  • 自己操作完了会开锁,别人才能改他
select xx,xx,xx from emp where job = 'dddd' for update

乐观锁:几个事务可以一起操作,但是每一条记录都会有一个版本号,每次事务都会检查版本号,如果拿到数据的时候的版本号和提交数据的时候的版本号发生了变化,说明有其他的事务在这期间修改了,那么就回滚放弃这次提交。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、概述: JDBC从物理结构上说就是Java语言访问数据库的一套接口集合。从本质上来说就是调用者(程序员)和实现者(数据库厂商)之间的协议。JDBC的实现由数据库厂商以驱动程序的形式提供。JDBC API 使得开发人员可以使用纯Java的方式来连接数据库,并进行操作。 ODBC:基于C语言的数据库访问接口。 JDBC也就是Java版的ODBC。 JDBC的特性:高度的一致性、简单性(常用的接口只有4、5个)。 1.在JDBC包括了两个包:java.sql和javax.sql。 ① java.sql 基本功能。这个包的类和接口主要针对基本的数据库编程服务,如生成连接、执行语句以及准备语句和运行批处理查询等。同时也有一些高级的处理,比如批处理更新、事务隔离和可滚动结果集等。 ② javax.sql 扩展功能。它主要为数据库方面的高级操作提供了接口和类。如为连接管理、分布式事务和旧有的连接提供了更好的抽象,它引入了容器管理的连接池、分布式事务和行集等。 注:除了标出的Class,其它均为接口。 API 说明 java.sql.Connection 与特定数据库的连接(会话)。能够通过getMetaData方法获得数据库提供的信息、所支持的SQL语法、存储过程和此连接的功能等信息。代表了数据库java.sql.Driver 每个驱动程序类必需实现的接口,同时,每个数据库驱动程序都应该提供一个实现Driver接口的类。 java.sql.DriverManager (Class) 管理一组JDBC驱动程序的基本服务。作为初始化的一部分,此接口会尝试加载在”jdbc.drivers”系统属性引用的驱动程序。只是一个辅助类,是工具。 java.sql.Statement 用于执行静态SQL语句并返回其生成结果的对象。 java.sql.PreparedStatement 继承Statement接口,表示预编译的SQL语句的对象,SQL语句被预编译并且存储在PreparedStatement对象。然后可以使用此对象高效地多次执行该语句。 java.sql.CallableStatement 用来访问数据库的存储过程。它提供了一些方法来指定语句所使用的输入/输出参数。 java.sql.ResultSet 指的是查询返回的数据库结果集。 java.sql.ResultSetMetaData 可用于获取关于ResultSet对象列的类型和属性信息的对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值