Jdbc (java database connection) java 数据库连接
Java.sql包下面
Java本身提供了一套数据库操作的接口,然后由数据库厂商去实现该接口进行数据库操作
这些接口的实现都由数据库厂商去完成。Java操作数据库单独时候就可以加上这个驱动就可以操作数据库了。

所以本来是这样的,其实java本身是不能操作数据库的,需要数据库厂商去帮助实现接口,因为数据库厂商实在太多了,必须帮助实现java的接口,java才能操作数据库。下面以mysql为例来写一个实例

在操作mysql的时候要提供一个mysql的数据库驱动(就是一个jar包)

这里用的软件是Eclipse,具体怎么导入驱动包,以及驱动包的下载,由于我一直在赶进度,所以劳烦各位自己百度解决下。我这里还用到了数据库的可视化图形工具Sqlyog,当然了你也可以用Navicat,在我们学习的时候可以用破解版,但是当我们有收入以后还是希望各位支持正版。毕竟都是作为开发者,都是靠这个吃饭的。这里也劳烦各位自己找下资源。

首先书写代码:代码我基本都打上注释了。而后补充一下resultSet.next(),这个东西返回的是一个boolean值,比如select * from
User,表数据如下:

JDBC.java
package mysql_jdbc; import java.sql.Connection; import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.SQLException; import java.sql.
Statement; /** * @author Hercules * @version 创建时间:2020年6月12日 下午3:35:06 * 类说明 */
public class JDBC { public static void main(String[] args) { //jdbc操作步骤 //1 加载驱动
try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e)
{ e.printStackTrace(); } Connection conn = null; Statement statement = null;
ResultSet resultSet= null; //获取连接 try { //1 链接的数据库localhost:3306表示本机的3306端口
test表示数据库名 //2 root数据库账号 //3 root数据库密码 conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test","root","root"); //连接不为null就表示和数据库链接成功了
//书写sql语句 String sql = "select * from User"; //3获取处理器 statement = conn.
createStatement(); //4获取结果集 resultSet = statement.executeQuery(sql); //5处理结果集
while(resultSet.next()) {//循环行 String username = resultSet.getString("username")
; String password = resultSet.getString("password"); int power = resultSet.
getInt("power"); System.out.println(username + "=" + password + "=" + power); }
} catch (SQLException e) { e.printStackTrace(); }finally {//最后要关闭资源 if(resultSet
!= null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace
(); } } if(statement != null) { try { statement.close(); } catch (SQLException e
) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch (
SQLException e) { e.printStackTrace(); } } } } }
最后输出结果如下:

在这里while循环中的代码还可以修改如下:
while(resultSet.next()) {//循环行 String username = resultSet.getString(1);
String password= resultSet.getString(2); int power = resultSet.getInt(3); System
.out.println(username + "=" + password + "=" + power); }
运行结果是一样的:

这里注意,sql的下标是从1开始的并不是从0开始的。

这时候比如用jdbc实现修改赵朔的权限值为2。
比如将sql修改如下:
//先给方法加一个参数: public static void statementcud(String username)
//而后调用的时候给username变量传入"赵朔" //username在这里就是一个变量 String sql = "update user set
power=2 where username='"+username+"'";
不过下面就不能调用executequery了,要调用executeUpdate();
最后返回的是int类型的变量:
如下:
int result = statement.executeUpdate(sql);
这里int类型的变量的意思是影响了多少行数据的意思。
也就是只要这个变量大于0就表示执行成功。
最后再补充一下delete,insert,和update都是类似调用executeUpdate方法

下面来看一个问题
就是上面的一行代码:
String sql = "update user set power=2 where username='"+username+"'";

这个username是一个变量应该是用户传入的。但是假如现在有一个懂程序的用户,注意这种用户肯定不在少数的。这年头首先计算机相关专业的烂大街了。其次好多人看上了这个行业,纷纷转行。
假如有一个人将username这个变量这么写:
赵朔';delete from user where 1=1 or 1='1
假如这个语句真的传入进去会发生什么?
那么这个表里面的所有数据都会被删除,目前对于互联网公司而言,数据是最重要的资产,如果用户传入参数如下,造成的损失是不可估量的。
这种情况称为sql注入攻击,Statement是无法避免的。意味着statement是不安全的。

为了避免这种情况需要使用预处理器也就是如下代码:
/** * 预处理器处理查询 */ public static void preparedStatementquery(String name) {
//jdbc操作步骤 //1 加载驱动 try { Class.forName("com.mysql.jdbc.Driver"); } catch (
ClassNotFoundException e) { e.printStackTrace(); } //2 获取连接 Connection conn =
null; PreparedStatement statement = null; ResultSet resultSet = null; try { //
1 连接的数据库 localhost:3306 表示本机的3306端口 test表示数据库名 // 2 root数据库账号 // 3 root 数据库密码
conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root",
"root"); //连接不为null就表示和数据库连接成功了 String sql = "select * from user where
username=?"; //3 获取预处理器 就需要将sql传入 statement = conn.prepareStatement(sql); //注入值
从1开始 statement.setString(1, name); //4获取结果集 resultSet = statement.executeQuery()
; //5 处理结果集 // while(resultSet.next()) {//循环行 // String username =
resultSet.getString("username"); // String password =
resultSet.getString("password"); // int power = resultSet.getInt("power"); //
System.out.println(username + "=" + password + "=" + power); // } while(
resultSet.next()) {//循环行 //如果使用下标的方式也可以获取,但是jdbc里面下标是从1开始的 String username =
resultSet.getString(1); String password = resultSet.getString(2); int power =
resultSet.getInt(3); System.out.println(username + "=" + password + "=" + power)
; } } catch (SQLException e) { e.printStackTrace(); } finally{ //6关闭资源 if(
resultSet!= null) { try { resultSet.close(); } catch (SQLException e) { e.
printStackTrace(); } } if(statement != null) { try { statement.close(); } catch
(SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(
); } catch (SQLException e) { e.printStackTrace(); } } } }
这里对于代码有必要解释一下:
首先第一行sql
String sql = “select * from user where username=?”;
这里?就是变量,无论用户传什么东西进去,这里始终会把?的部分当成username的值。
而后看下面四句:
//连接不为null就表示和数据库连接成功了 String sql = "select * from user where username=?"; //3
获取预处理器 就需要将sql传入 statement = conn.prepareStatement(sql); //注入值 从1开始 statement.
setString(1, name); //4获取结果集 resultSet = statement.executeQuery();

第二句是将sql传入预处理器,但是这时候?没有值,则需要注入值,这里是根据?的顺序进行值的注入,第一个?注入值name变量。最后再获取结果值。所以这样不管再受到怎样的sql注入攻击。

而后不是查询了,是增删改的信息:
/** * 预处理器处理增删改 */ public static void preparedStatementcud(String username) {
//jdbc操作步骤 //1 加载驱动 try { Class.forName("com.mysql.jdbc.Driver"); } catch (
ClassNotFoundException e) { e.printStackTrace(); } //2 获取连接 Connection conn =
null; PreparedStatement statement = null; try { // 1 连接的数据库 localhost:3306
表示本机的3306端口 test表示数据库名 // 2 root数据库账号 // 3 root 数据库密码 conn = DriverManager.
getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
//连接不为null就表示和数据库连接成功了 String sql = "update user set power=? where username=?";
//delete , insert 和update都是类似调用 executeUpdate 方法 //3 获取处理器 statement = conn.
prepareStatement(sql); //注入值 数字为第几个问号? 从1开始 statement.setInt(1, 3); statement.
setString(2, username); //4获取影响行数 int result = statement.executeUpdate(); //5
处理结果集 System.out.println(result + "大于0即表示执行成功"); } catch (SQLException e) { e.
printStackTrace(); } finally{ //6关闭资源 if(statement != null) { try { statement.
close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) {
try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
主要的代码在于以下几行代码:
//连接不为null就表示和数据库连接成功了 String sql = "update user set power=? where username=?";
//delete , insert 和update都是类似调用 executeUpdate 方法 //3 获取处理器 statement = conn.
prepareStatement(sql); //注入值 数字为第几个问号? 从1开始 statement.setInt(1, 3); statement.
setString(2, username); //4获取影响行数 int result = statement.executeUpdate();

第一个问号是int类型的所以传入了一个int类型的变量。也就是setInt方法,而username是String类型的所以用setString方法。而set类型(),的第一个参数就是第几个问号。而后最后就得到影响的行数。

预处理器会将sql语句预编译存入当前对象中,确认该sql只能做什么事情,即使有sql注入攻击,也不会执行。可以防止sql注入攻击。所以作为平常项目中的编码来说,都用预处理器。说白了就是建议大家使用预处理器不建议使用处理器。

技术
©2019-2020 Toolsou All rights reserved,
java设计模式之桥接模式2018性价比高的笔记本推荐C#关键字之override详解厉害了!除了find命令,还有这么多文件查找命令,高手必备!【倒计时】距奇绩创业营招募截止还有1天!在华为外包的工作体验springboot集成elasticsearch7.2老程序员的忠告:一辈子靠技术前途堪忧LeetCode 初级 - Fizz Buzz当心!TCP本机客户端连接本机服务器