jdbc
Posted wdadwa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdbc相关的知识,希望对你有一定的参考价值。
JDBC概述
-
JDBC全称java DataBase Connectivity,java数据操作。
-
JDBC就是java语言操作关系型数据库的一套API。
-
JDBC的目的是用同一套java代表,操作不同的关系型数据库。
-
JDBC本质是Sun公司定义的一套操作所有关系型数据库的规则,即接口。
各个数据库厂商去实现这套接口,提供数据库驱动jar包,我们可以使用这套接口JDBC编程,真正执行的代码是驱动jar包中的实现类
这样写的好处:java代表不需要针对不同的数据库分别开发jdbc,可以随时替换底层数据库而代码不需要改变。
使用方法
以MYSQL为例,先导入mysql-connercot-java这个jar包到项目中。
-
注册驱动
Class.forName("com.mysql.jdbc.Driver");//mysql5.0之后的写法 Class.forName("com.mysql.cj.jdbc.Driver");//mysql8.0之后的写法
-
获取连接
String url = "jdbc:mysql://127.0.0.1:3306/wdadwa?&useSSL=false&serverTimezone=UTC"; String username="root"; String password="123456"; Connection conn = DriverManager.getConnection(url, username, password); //url会细讲
-
定义SQL语句
String sql="select * from student";
-
获取执行SQL的对象
Statement stmt = conn.createStatement();
-
执行SQL
ResultSet resultSet = stmt.executeQuery(sql);
-
处理返回结果
-
释放资源
stmt.close(); conn.close();
API详解
DriverManger
作用:
- 注册驱动
- 获取数据库连接
两个重要的方法
DriverManager.registerDriver(new Driver());//注册驱动
Connection conn = DriverManager.getConnection(url, username, password);//建立连接对象
第一个注册驱动在Mysql5.0之后就不需要写了,Class.forName(""com.mysql.jdbc.Driver"")在底层也是通过这个方式注册的驱动.
DriverManger建立连接对象三个参数详解:
-
第一个参数:
语法:
jdbc:mysql://ip地址(域名):端口号/数据库名名?参数键值对1&参数键值对2...
举例:
jdbc:mysql://127.0.0.1:3306/db1
如果连接的是本机mysql,默认端口3306,url可以简写为:
jdbc:mysql////数据库名?参数键值对1&参数键值对2...
参数键值对有:
useSSL=false
禁用安全连接方式,解决警告提示.useServerPrepStmts=true
打开SQL预编译功能
-
第二个参数:用户名
-
第三个参数:密码
Connection
作用:
- 获取执行SQL的对象
- 管理事务``
利用Connection获取执行SQL的对象分为:
-
普通执行SQL对象
Statement stmt = conn.createStatement();
-
预编译SQL的执行对象(防止SQL注入)
PreparedStatement preparedStatement = conn.prepareStatement(sql);
-
执行存储过程的对象(存储过程不常用)
CallableStatement callableStatement = conn.prepareCall();
利用Connection进行事务管理
//开启事务
setAutoCommit(boolean autoCommit);//true自动提交事务,false手动提交事务
conn.commit();//提交事务
conn.setAutoCommit(false);//关闭事务的自动提交
conn.rollback();//回滚事务
一般在java中使用try catch包围起来,当出现异常就回滚事务。
Statement
作用:执行SQL语句。
Statement提供了三种方法来执行SQL
-
executeQuery
用来执行DQL语句String sql="select * from student where name=\'"+name+"\'and password=\'"+pwd+"\'"; //即通过 \'"字符串"\'这种形式把字符串包围起来 ResultSet resultSet = stmt.executeQuery(sql);
-
executeUpdate
用来执行DDL,DML语句String sql="update student set age=10 where age=21"; int i = stmt.executeUpdate(sql); //执行DDL语句返回的可能是0,执行DML语句返回的是被影响的行数
-
execute
可以执行任意sql查询boolean execute = stmt.execute(sql); //如果查询结果时ResultSet,这个方法就会返回true,如果不是ResultSet,比如insert或者update,就会返回false。
ResultSet
作用:封装了DQL查询语句的结果集合。
使用ResultSet中方法获取查询结果:
boolean next();
//将光标从当前位置向下移动一行,并判断当前行是否为有效行(移动后)
//返回值true,有效行
//返回值false,无效行
//默认从数据行的上一行作为起始位置
xxx getXXX(参数);//获取数据
//xxx代表数据类型,如int getInt(参数),String getString(参数)
//参数:有两种重载形式
//int:根据列的编号获取元素,从1开始
//String:根据列的名字获取元素
//举例:
ResultSet res = stmt.executeQuery(sql);
res.getInt(1);//获取id
res.getInt("id");//获取id
while(res.next())
int anInt = res.getInt(4);
System.out.println(anInt);
res.close();//写完后记得释放资源
PreparedStatement
PreparedStatement是Statement的子类。
作用:与变量SQL并执行,预防SQL注入问题。
SQL注入:通过操作输入来修改事先定义好的SQL语句,用来达到执行代码对服务器进行攻击的方法。
SQL注入产生的原因:字符串拼接产生的问题
String name="wdadwa";
String pwd="\' or \'1\'=\'1";
String sql="select * from tb_user where username=\'"+name+"\' and password=\'"+pwd+"\' ";
System.out.println(sql);//select * from tb_user where username=\'wdadwa\' and password=\'\' or \'1\'=\'1\'
//这样的SQL语句会导致查询返回结果为整张表,因为1=1是个恒等式,这个SQL等同于select * from tb_user
PreparedStatement使用
-
获取PreparedStatement对象
String sql="select * from student where name=? and age=?";//用占位符?代替变量 PreparedStatement pstmt=conn.prepareStatement(sql);
-
设置参数值
//PreparedStatement对象:setXxx(参数1,参数2):给?赋值 //Xxx:数据类型,比如setInt(参数1,参数2); //参数1:?占位符的编号,从1开始 //参数2:?的值 pstmt.setString(1,"张三"); pstmt.setInt(2,10);
-
执行SQL
ResultSet resultSet1 = pstmt.execute();//执行SQL语句 ResultSet resultSet2= pstmt.executeQuery();//executeQuery执行DQL语句 ResultSet resultSet3 = pstmt.executeUpdate();//executeUpdate用来执行DDL,DML语句
底层原理:将
"\' or \'1\'=\'1"
中的单引号作为文本使用转义字符反斜杠转义了,从而区分了sql语句的单引号和文本的单引号实际传入的是
select * from tb_user where username=\'wdadwa\' and password=\'\\\' or \\\'1\\\'=\\\'1\'
PreparedStatement预编译:
- 在获取PreparedStatement对象时,将SQL语句发送给MYSQL服务器进行检查,编译(这些步骤很耗时)
- 执行时就不需要再进行这些步骤了
- 如果sql模板一样,只需进行一次检查和编译即可。
预编译功能需要在建立连接对象的时候传入参数useServerPreStmts=true
数据库连接池
数据库连接池简介:
-
数据库连接池是个容器,负责分配,管理数据库连接
-
允许应用程序重复使用一个现有的数据库连接,而不是重新再建一个。
-
释放空闲时间超过最大空闲时间的数据库连接,避免因为没有释放数据库连接导致的数据库连接遗漏
好处:
- 资源重用
- 提高系统响应效率
- 避免数据库连接遗漏
数据库连接池实现
-
标准接口:
DataSource
官方提供的数据库连接池标准接口,由第三方组织实现此接口。
功能:获取连接
Connection getConnection()
-
常见的数据库连接池:
- DBCP
- C3P0
- Druid
-
Druid:
Druid连接池是阿里巴巴开源的数据库连接池项目,是java语言最好的数据库连接池之一。
使用方法:
-
导入jar包
-
定义配置文件
druip.properties
模板:
#驱动类名,固定模板 driverClassName=com.mysql.cj.jdbc.Driver #url url=jdbc:mysql://localhost:3306/test?useUnicode=true& #字符编码 等配置 characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai #数据库的账号密码 username=root password=123456 #初始化连接数 initialSize=10 #最大连接数 maxActive=100 #最大等待时间(毫秒 maxWait=3000
-
加载配置文件
Properties prop=new Properties(); prop.load(new FileInputStream("src/druid.properties"));//配置文件路径
-
获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
-
获取连接
Connection connection = dataSource.getConnection();
其他功能和jdbc一样不多讲述
JDBC笔记--- JDBC概述
1、JDBC是什么?
Java DataBase Connectivity(Java语言连接数据库)
2、JDBC的本质是什么?
JDBC是SUN公司制定的一套接口(实质)
java.sql.*; (这个软件包下有很多接口)
接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。
思考:为什么SUN制定一套JDBC接口呢?
因为每一个数据库的底层实现原理都不一样。
Oracle数据库有自己的原理。
MySQL数据库也有自己的原理。
MS SqlServer数据库也有自己的原理。
....
每一个数据库产品都有自己独特的实现原理。
3、JDBC开发前的准备工作,先从官网下载对应的驱动jar包,然后将其配置到环境变量classpath当中。
以上的配置是针对于文本编辑器的方式,开发IDEA有自己的配置方式;
4、JDBC编程六步(重点)
第一步:注册驱动(作用:告诉Java程序,即将要连接的是哪个品牌的数据库)
第二步:获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后一定要关闭通道。)
第三步:获取数据库操作对象(专门执行sql语句的对象)
第四步:执行SQL语句(DQL DML....)
第五步:处理查询结果集(只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集)
第六步:释放资源(使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)
5.辅助理解图示:
以上是关于jdbc的主要内容,如果未能解决你的问题,请参考以下文章