JDBC

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注入攻击。所以作为平常项目中的编码来说,都用预处理器。说白了就是建议大家使用预处理器不建议使用处理器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值