目录
三、就到这里了,后面再写关于数据库连接池的总结,请多关注、点赞、收藏!!!
一、JDBC
1.1 jdbc下载
jar包百度网盘下载:
链接:https://pan.baidu.com/s/1i1QY6MdRbExHVZ_UwJp1ag?pwd=1234
提取码:1234
下载好复制一份,在模块里创建一个目录,将jar包复制到目录里,在右键添加到库,添加成功后就可以用来
1.2 JDBC概述
JDBC:( Java DataBase Connectivity ) Java 数据库连接
定义:一套操作所有关系型数据库的规则,即接口
各个数据库厂商去实现这套接口,提供数据库驱动jar包
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
1.3 执行流程
第一步:编写Java代码
第二步:Java代码将SQL发送到MySQL服务端
第三步:MySQL服务端接收到SQL语句并执行该SQL语句
第四步:将SQL语句执行的结果返回给Java代码
1.31 代码实现
//1. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 获取连接
String url = "jdbc:mysql://你的IP:3306/db1?useSSL=false&serverTimezone=UTC";
String username = "root";
String password = "********";
Connection conn = DriverManager.getConnection(url, username, password);
//3. 定义sql
String sql = "update account set money = 2000 where id = 1 ";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5. 执行sql
int count = stmt.executeUpdate(sql);//受影响的行数
//6. 处理结果
System.out.println(count);
//7. 释放资源
stmt.close();
conn.close();
二、JDBC所有API
2.1 驱动管理类 DriverManager
作用:注册驱动和获取数据库连接
- 注册驱动(告诉程序该使用哪一个数据库驱动)
- 注册给定的驱动程序:static void registerDriver(Driver driver) (DriverManager的方法)
- 我们通过了给forName指定了是mysql的驱动
- 在com.mysql.jdbc.Driver类中存在静态代码块(通过查看源码发现)
//这是com.mysql.jdbc.Driver的静态代码块,只要使用这个类,就会执行这段代码 //而Class.forName("com.mysql.jdbc.Driver")就正好使用到了这个类 static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
-
mysql5之后可以省略注册驱动的步骤。在jar包中,存在一个java.sql.Driver配置文件,文件中指定了com.mysql.jdbc.Driver
获取数据库连接(获取到数据库的连接并返回连接对象)
- static Connection getConnection(String url, String user, String password);
- 返回值:Connection数据库连接对象
- 参数
- url:指定连接的路径。语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对
- user:用户名
- password:密码
- 参数键值对:配置 useSSL=false 参数,禁用安全连接方式,解决警告提示。配置 serverTimezone=UTC参数,防止时区错误,如果没有配置,代码可能报错。配置useServerPrepStmts=true参数,开始事务
2.2 数据库连接对象Connection
作用:获取执行 SQL 的对象和管理事务
-
获取执行 SQL 的对象,用于执行静态SQL语句并返回其生成的结果的对象。
-
获取普通执行者对象:Statement createStatement();
-
获取预编译执行者对象:PreparedStatement prepareStatement(String sql);//后面讲
-
-
管理事务
- 开启事务:setAutoCommit(boolean autoCommit); 参数为false,则开启事务。
- 提交事务:commit();
- 回滚事务:rollback();
2.3 Statement
Statement对象的作用就是用来执行SQL语句。
- Statement:执行sql语句的对象
- 执行DML语句:int executeUpdate(String sql);
- 参数sql:可以执行insert、update、delete语句。
- 执行DQL语句:ResultSet executeQuery(String sql)
- 返回值ResultSet:封装查询的结果。
- 参数sql:可以执行select语句。
- 释放资源
- 立即将执行者对象释放:void close();
2.3.1 结果集对象 ResultSet
作用:封装了SQL查询语句的结果,执行了DQL语句后就会返回该对象。
方法:
boolean next()
将光标从当前位置向下移动一行,并判断当前行是否为有效行
方法返回值说明:
true : 有效行,当前行有数据
false : 无效行,当前行没有数据
xxx getXxx(参数):获取数据
xxx : 数据类型;如: int getInt(参数) ;String getString(参数)
参数
int类型的参数:列的编号,从1开始
String类型的参数: 列的名称
用法:
使用boolean next()方法前,光标是指向第一行的,这个方法和容器的迭代器相似,在用xxx getXxx(参数)获取数据
比如下面代码,获取数据,并封装
ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { int id = rs.getInt("id"); String brandName = rs.getString("brand_name"); String companyName = rs.getString("company_name"); int ordered = rs.getInt("ordered"); String description = rs.getString("description"); int status = rs.getInt("status"); }
2.3.2 SQL注入问题
SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
SQL注入问题模拟:
String sql = "update account set money = 2000 where money='' or '1'='1'";
如果执行这条语句,在mysql上显示的是:
update account set money = 2000 wher money='' or '1'='1'
因为MySQL特殊的标点,where money=' ' or '1'='1' 这个执行情况就发生改变。本来where条件是money等于‘ or ‘1’=‘1,因为是string类型,要加单引号,变成了money=' ' or '1'='1' ,所以where条件money=’ ‘不成立,但’1‘=’1‘成立,or是只要有一个为真,where条件就成立,这就发生sql注入,PreparedStatement对象可以预防sql注入。
2.4 PreparedStatement
2.4.1 概述
作用:预编译SQL语句并执行,预防SQL注入问题。
- 获取 PreparedStatement 对象
// SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
// 通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);
- 设置参数值
上面的sql语句中参数使用 ? 进行占位,在之前之前肯定要设置这些 ? 的值。
PreparedStatement对象:setXxx(参数1,参数2):给 ? 赋值
Xxx:数据类型 ; 如 setInt (1,234)为设置第一个问号值为234
参数:
参数1: ?的位置编号,从1 开始
参数2: ?的值
-
执行SQL语句
executeUpdate(); 执行DDL语句和DML语句
executeQuery(); 执行DQL语句
注意:
-
调用这两个方法时不需要传递SQL语句,因为获取SQL语句执行对象时已经对SQL语句进行预编译了。
-
2.4.2 PreparedStatement原理
PreparedStatement 好处:
预编译SQL,性能更高
防止SQL注入:将敏感字符进行转义
- 为什么预编译性能更高?
- MySQL服务器检查SQL和编译SQL花费的时间比执行SQL的时间还要长。如果我们只是重新设置参数,那么检查SQL语句和编译SQL语句将不需要重复执行。这样就提高了性能。
- PrepareStatement预编译过程:
- 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
执行时就不用再进行这些步骤了,速度更快
如果sql模板一样,则只需要进行一次检查、编译
- 防止SQL注入:将敏感字符进行转义
- 比如:
//3. 定义sql String sql = "select * from account where money=? and name=?"; //4. 获取执行sql的对象 ResultSet PreparedStatement pst = conn.prepareStatement(sql); pst.setString(1,id);//1是第一个?的索引,id是要代替的值 pst.setString(2, pwd); ResultSet count = pst.executeQuery();
将敏感字符进行转义,要填入的字符是自己指定的数据类型,就避免sql注入
三、就到这里了,后面再写关于数据库连接池的总结,请多关注、点赞、收藏!!!