JDBC是 Java Data Base Connectirity(java语言连接数据库)
JDBC的本质
JDBC是sum公司制定的一套接口(interface)在java.sql包下
都有实现者和调用者
SUM公司制定这一套接口的目的是
因为每一个数据的底层实现原理都不一样
MySQL有mysql的实现原理
Oracle有oracle的实现原理
每一个数据库都有自己的实现原理
JDBC开发前准备
从官网下载对应的驱动jar包,然后将其配置在环境变量classpath当中。
classpath = . ; jar包的路径
驱动是什么
所有的数控驱动都是以jar包的形式存在,jar包当中有很多.class文件,这些class文件就是对JDBC接口的实现
驱动不是sun公司提供的是各大数据库厂家负责提供的,下载驱动jar包需要去数据库官网下载
JDBC编程六步
第一步:注册驱动
作用就是告诉java程序即将要连接的是哪个数据库
第二步:获取连接
表示jvm的进程和数据库的进程直接的通道打开了,这属于进程之间的通信
第三步:获取数据库操作对象
专门执行sql语句的对象
第四步:执行sql语句
第五步:处理查询集
此步只有第四步有select查询语句才会执行
第六步:释放资源
先释放查询结果集,再释放操作对象,最后释放连接对象。
注册驱动
注册驱动一共有两种写法
第一种写法(不常用)
Driver driver = new com.mysql.jdbc.Driver();
第二种写法(常用)
Class.forName("com.mysql.jdbc.Driver");
这写法常用的原因是因为
这个写法的参数是一个字符串,字符串可以写到XXX.properties文件中
在JDBC中有专门执行DQL和DML语句的方法
-
专门执行DQL语句的方法:
-
Statement.executeQuery()
返回 ResultSet
专门执行DML语句的方法:
-
Statement.executeUpdate()
放回int
ResultSet方法
-
ResultSet.next():
- 让光标向下移动一行如果指向有的位置有数据返回true,否则放回false。 光标初始位置是0 ResultSet.setString():
- 不管数据中什么类型,都有String的形式取出。括号内可以填int类型的,按照表列的顺序1,2,3,4。(不太键状) JDBC中的所有下标从1开始不是0。括号里面也可以填写列名,表里面最顶上的名字(这种比较键状)。 String是可以换的,你可以换成int啊,float啊这些
SQL注入
导致SQL注入根本原因是:
用户输入的信息带有sql语句的关键字,并且这些关键字参与SQL语句的编译过程,导致SQL语句的原本意思改变了,进而达到SQL注入。
解决SQL注入:
只要用户提供的信息不参与sql语句的编译过程,问题就解决了。即使用户提供的信息含有sql语句的关键字,但是没有参与编译,也起不了作用。
要想用户信息不参与sql语句编译就只可以使用java.sql.preparedStatement类
preparedStatement继承Statement类
preparedStatement是属于于编译的数据库操作对象
preparedStatement的原理是对sql语句的子语句的框架进行编译,然后再给sql语句传值。
sql语句的框子。其中一个?表示一个占位符,一个?将来接受一个"值"
占位符不能使用单引号括起来例如 ‘?’
占位符第一个下标为1,第二个下标为2
MySQL有个特点
在输入select语句的时候它第一次会自动编译,之后第二次select语句更第一次一样的化就不会进行编译了,会直接执行。
Statement和preparedStatement对比
statement存在注入问题,preparedstatement解决了sql注入问题
statement编译一次执行一次 ,preparedstatement是编译一次可执行N次。preparedstatement效率高一些。
preparedstatement会在编译阶段做类型安全检查。
什么情况下用Statement呢
业务方面要求必须支持sql注入的时候。
statement支持sql注入,凡是业务方面需求进去sql语句拼接的,必须使用statement。
JDBC事务机制
JDBC中的事务是自动提交的
只要执行一条DML语句,则自动提交一次这是JDBC默认的事务行为。但是在实际的业务当中,通常都是多条DML语句共同联合才能完成的必须保证他们这些DML语句在一个事务中同时成功或者同时失败。
JDBC中只要执行一条DML语句就结束一次
-
Connection方法:
-
Connection.setAutoCommit(boolean类型);
开启或者关闭事务
Connection.preparedStatement(Strig 类型);
编译SQL语句
Connection.commit();
提交事务
Connection.rollback();
回滚事务
悲观锁
- 事务必须排队执行,数据锁住了,不允许并发。(行级锁:select后面添加 forupdate) 乐观锁
- 支持并发,事务也不需要排队,只不过需要一个版本号。