目录
一、下载驱动包
二、加载与注册驱动
1、使用driverManager类
2、方式:
3、补充:
三、建立连接
1、URL
2.建立连接的方式
3.事务管理
4.获取Statement语句
1、普通版本
2、防止SQL注入版本
3、获取存储过程
四、Statement
1、概述
2、例子
五、结果集 ResultSet
1、概述
2、RestultSet 里面提供的方法
3、举例实操
需求:获取account表中的全部数据
代码实现:
注意
补充java数据类型和SQL类型对照表
六、SQL注入问题
1、sql注入(由于去改变sql语法结构)
2、preparedStatement 预编译语句补充
1、作用:
2、获取PreparedStatement语句
3、设置参数值
3、PreparedStatement 原理
一、下载驱动包
地址:https://mvnrepository.com
二、加载与注册驱动
1、使用driverManager类
2、方式:
-
Class.forName("com.mysql.cj.jdbc.Driver");
-
//注册驱动 DriverManager.registerDriver(com.mysql.cj.jdbc.Driver);
-
System.setProperty("jdbc.drivers","com.mysql.cj.jdbc.Driver");
注意:方式一和方式三建立的驱动相同,方式一通过反射的方法来设置驱动,方式三直接设置驱动
3、补充:
-
Mysql 驱动包5.0之后的版本,可以省略注册驱动的步骤
三、建立连接
1、URL
1.1表示连接路径
1.2参数说明
String url = "jdbc:mysql://localhost:3306/jdbc";
1.3 JDBC URL的组成
JDBC URL的标准由三部分组成(jdbc:子协议:子名称),各部分之间用 : 隔开
-
协议:JDBC URL 中的协议就是jdbc
-
子协议:用来标识数据库驱动程序
-
子名称:标识数据库的方法。定位数据库需要ip,端口port,数据库名称
1.4 常见数据库的JDBC URL
-
Oracle jdbc:oracle:thin@主机名称:oracle服务端口:Databasename=数据库名称
2.建立连接的方式
String url = "jdbc:mysql://localhost:3306/jdbc";
// 建立连接方式一
// String user = "root";
// String password = "123456";
// Connection connection = DriverManager.getConnection(url,user,password);
// 获取连接的方式二 com.mysql.cj.jdbc.ConnectionImpl@fcd6521
Properties properties = new Properties();
properties.setProperty("user","root");
properties.setProperty("password","123456");
Connection connection = DriverManager.getConnection(url, properties);
3.事务管理
// 开启事务
connection.setAutoCommit(false);
// 事务提交
connection.commit();
4.获取Statement语句
1、普通版本
Statement statement = connection.createStatement();
2、防止SQL注入版本
// 获取预编译语句
connection.prepareStatement();
3、获取存储过程
// 获取存储过程
CallableStatement callableStatement = connection.prepareCall();
注意:
常用预编译语句来操作sql语句,存储过程不常使用,基本不用。
四、Statement
1、概述
-
Statement 对象的作用是用来执行SQL语句,但是不同类型的SQL语句执行语法又不太一样
-
执行DDL/DML 语句 数据定义、数据管理
// 执行DDL/DML 语句 数据定义、数据管理 int i = statement.executeUpdate(); //返回值是受影响行数
-
执行DQL 语句 数据查询
// 执行DDL/DML 语句 数据定义、数据管理 int i = statement.executeUpdate(); //返回值是受影响行数
-
2、例子
public static void main(String[] args) throws Exception {
// 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 建立连接
String url = "jdbc:mysql://localhost:3306/jdbc";
String user = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, user, password);
// 创建statement语句操作sql
Statement statement = connection.createStatement();
// 定义sql语句 修改id=1 的money
String sql = "update account set money = 8000 where id = 1";
// 操作DML语句
int i = statement.executeUpdate(sql);
// 受影响行数
System.out.println(i);
// 关闭资源
statement.close();
connection.close();
}
五、结果集 ResultSet
1、概述
-
封装sql查询结果
-
执行结果集的方法
ResultSet resultSet = statement.executeQuery();
2、RestultSet 里面提供的方法
-
boolean next()
-
将光标从当前位置向前移动一行
-
判断当前行是否有效
-
返回值boolean 说明
-
true:有效当前行有数据
-
false:无效,当前行没有数据
-
-
-
xxxgetXxx(参数) 获取数据
-
xxx:数据类型 (int getInt(参数))
-
参数
-
int 类型 ,列的标号,从1开始
-
String 类型 ,列的名称
-
-
3、举例实操
-
需求:获取account表中的全部数据
-
代码实现:
public static void main(String[] args) throws Exception { // 加载驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 建立连接 String url = "jdbc:mysql://localhost:3306/jdbc"; String user = "root"; String password = "123456"; Connection connection = DriverManager.getConnection(url, user, password); // 创建statement语句操作sql Statement statement = connection.createStatement(); // 定义sql语句 修改id=1 的money String sql = "select * from account"; // 执行DQL ResultSet resultSet = statement.executeQuery(sql); // 处理结果集 //判断是否有下一行 // while (resultSet.next()){ // //根据列序号 // int id = resultSet.getInt(1); // int money = resultSet.getInt(2); // String name = resultSet.getString(3); // System.out.println("id:" + id + " " + "money:" + money + " " + "name:" + name); // } while (resultSet.next()){ //也可以属性名来获取值 int id = resultSet.getInt("id"); int money = resultSet.getInt("money"); String name = resultSet.getString("name"); System.out.println("id:" + id + " " + "money:" + money + " " + "name:" + name); } // 释放资源 statement.close(); connection.close(); }
注意
在通过列名获取值时,列名要和数据库表中的列名对应,且要注意数据类型;
补充java数据类型和SQL类型对照表
六、SQL注入问题
1、sql注入(由于去改变sql语法结构)
String password1 ="'1' or '1'='1'";
// 定义sql
String sql = "select * from user where username='" + userName + "' and password=" + password1+"; ";
D:\roming\Typora\typora-user-images\image-20221226111605174.png
2、preparedStatement 预编译语句补充
1、作用:
预编译SQL语句并执行,预防sql注入
2、获取PreparedStatement语句
// 获取预编译语句
// 定义sql
String sql = "select * from user where username=? and password= ?";
// System.out.println(sql);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
注意:?为占位符
3、设置参数值
(获取sql 语句时使用?占用坑位,在使用时要替换这些坑位)
-
setXxx(参数一,参数二);给?赋值
-
参数
-
参数1: ?的位置编号,从1开始
-
参数2: ?的值
-
-
执行SQL语句时,就不需要传递sql语句了
测试代码:
// 模拟用户登录
String userName="cyc";
String password1 ="'1' or '1'='1'";
// 获取预编译语句
// 定义sql
String sql = "select * from user where username=? and password= ?";
// System.out.println(sql);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//
preparedStatement.setString(1,userName);
preparedStatement.setString(2,password1);
ResultSet resultSet = preparedStatement.executeQuery();
// ResultSet resultSet = statement.executeQuery(sql);
if (resultSet.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
preparedStatement.close();
connection.close();
3、PreparedStatement 原理
-
java将sql语句发送到Mysql服务器
-
Mysql操作
-
检查sql语句语法
-
编译SQL语句,将SQL编译成可执行函数
-
检查SQL和编译SQL时间比执行SQL时间要长,使用预编译语句不需要重复检查SQL语句和编译,还可以提高性能
-
-
执行SQL
-
-
通过查询日志来看原理
-
开启预编译功能(刚才只是解决了SQL注入问题,预编译还没开启)
-
开启:在url加上如下参数 ??userServerPrepStmts=true
-
-
配置Mysql日志文件(.ini文件)
-