当前位置:Gxlcms > 数据库问题 > 由浅到深学习JDBC一

由浅到深学习JDBC一

时间:2021-07-01 10:21:17 帮助过:26人阅读

2:连接数据库

     user:root----数据库用户名

     password:root------数据库密码

     url: oracle ----协议 :子协议 :thin:@ip:端口:SID(SID数据库的实例名)。

     eg:String url = "jdbc:oracle:thin:@localhost:1521:XE";

     url:mysql ------ 协议:子协议://ip:端口:数据库名

   eg:String url = "jdbc:mysql://localhost:3306/zdx";


3:准备sql

     sql字符串中不能有分号;

4:Statement将sql发送至数据库

      int i=  executeUpdate(sql); //返回受影响的行数

5:如果是查询语句,返回结果集,处理ResultSet。

6:关闭连接,释放资源,按照先打开后关闭的原则。


以上6步骤时开发JDBC程序的标准步骤。


ResultSet结果集简介及使用方法:

     ResultSet结果集:存放查询结果数据。

     ResultSet rs = Statement.executeQuery();

     rs指针初始位置在第一行数据之前

     boolean rs.next(): ,

     将rs的指针向下移动一位,当前行无数据返回false,有数据返回true,并获得查询数据。

     提供一组getXXX(int列序号或String列名)方法用于取得数据


以上是JDBC简介,下面是JDBC例子,例子才是王道。

JDBC1.0版本------是1.0版本。后面还会有更优秀的版本娓娓道来!


JDBC_ResultSet.java

public class JDBC_ResultSet {

       public static void main(String[] args) throws ClassNotFoundException, SQLException {

             //1:加载驱动

             //Class.forName("oracle.jdbc.OracleDriver");

             Class.forName("com.mysql.jdbc.Driver");

             //2:获得数据库连接

             String user = "root";

             String password = "root";

             //String url = "jdbc:oracle:thin:@localhost:1521:XE";

             String url = "jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC";

             Connection conn = DriverManager.getConnection(url,user,password);

             //3:准备sql

             String sql = "select * from student";

             //4:创建Statement,发送sql

             Statement stm = conn.createStatement();//获的statement对象

             //5:如果是查询,处理结果集

             ResultSet rs = stm.executeQuery(sql);

             while(rs.next()){

                    int id = rs.getInt(1);

                    String name = rs.getString(2);

                    int age = rs.getInt(3);

                    String phone = rs.getString(4);

                    System.out.println(id+"---"+name+"---"+age+"---"+phone);

             }

             //6:关闭连接,释放资源,原则,先打开后关闭

             stm.close();

             conn.close();

             

       }

}



到了此处,我们的JDBC1.0已经写完了,但是为什么说是1.0呢,因为这个版本有一个很大的漏洞。

没错,那就是——依赖注入问题。

===================华丽丽的分割线==============================

下面我们可以看这个例子


JDBC_Statement.java


public class JDBC_Statement {

       public static void main(String[] args) throws Exception {

             

             Scanner sc = new Scanner(System.in);

             System.out.println("请输入卡号");

             String card_id = sc.nextLine();

             System.out.println("请输入密码");

             String pwd = sc.nextLine();

             //1:加载驱动

             Class.forName("com.mysql.jdbc.Driver");

             //2:获得数据库连接

             String user = "root";

             String password = "root";

             String url = "jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC";

             Connection conn = DriverManager.getConnection(url,user,password);

             //3:准备sql

             String sql = "select * from account where card_id ="+card_id

                                 +" and password = ‘"+pwd+"‘";

             System.out.println(sql);

             //4:创建Statement,发送sql

             Statement stm = conn.createStatement();//获的statement对象

             //5:如果是查询,处理结果集

             ResultSet rs = stm.executeQuery(sql);

             if(rs.next()){

                    System.out.println("可以取钱了");

             }else{

                    System.out.println("密码账户不正确");

             }

             //6:关闭连接,释放资源,原则,先打开后关闭

             stm.close();

             conn.close();

       }

}



这是一个银行取钱的例子,如代码所写。

数据库有这样一张account表,数据和字段如下:


技术分享

现在在控制台输入卡号密码,卡号密码正确即可取钱,

错误即提示账户不正确。


现在控制台输入正确卡号密码


技术分享

然后,我输入错误的卡号密码竟然也可以取钱!输入错误的卡号 “123 or 1=1 -- ”密码 "zxc"结果如下

技术分享


可见依然能访问数据库,这对于银行可是致命性错误,密码错误还可以取钱。

这就是依赖注入引起的著名错误。

依靠人为输入破坏sql结构.

select * from account where id = 1001 or 1=1 -- and password = ‘xxx‘

这条sql里,其中--是sql里的注释 or 1=1 永远为真并且还是or连接,

所以这条sql只执行到 or 1=1 ,1=1又是恒等。所以跳过了密码。


为了解决这个问题,我们就要说PreparedStatement!


PreparedStatement简介及使用


PreparedStatement构建动态SQL,通过PreparedStatement执行SQL语句,解决注入攻击。

PreparedStatement是Statement的子接口。

通过连接创建PreparedStatement,创建时将SQL语句中发生变化的部分用占位符“?“ 代替。

功能:和statement一样,发送sql语句。 

          但是执行多个同构sql效率高。同构sql能省去①②③步骤。

使用步骤:

     1.创建pstm

     String sql = "select * from account where card_id = ? and password = ?"

     PreparedStateement pstm = conn.prepareStatement(sql);

          ①验证权限

          ②验证语法

          ③将sql转换内部指令

2.绑定参数

     pstm.setInt(1,值);

     pstm.setString(2,值);

3.发送绑定参数至DB数据库

     pstm.executeUpdate();//曾删改

     pstm.executedQuery();//查询

          ④执行内部指令操作数据库

mysql内部执行sql步骤:

          ①验证权限

          ②验证语法

          ③将sql转换内部指令

          ④执行内部指令操作数据库

使用PareparedStatement解决注入攻击问题后的代码如下:

JDBC2.0版本 是2.0版本>_< 。后面还会有更优秀的版本娓娓道来!

JDBC_PreparedStatement.java


public class JDBC_PreparedStatement {

       public static void main(String[] args) throws Exception {

             

             Scanner sc = new Scanner(System.in);

             System.out.println("请输入卡号");

             String card_id = sc.nextLine();

             System.out.println("请输入密码");

             String pwd = sc.nextLine();

             //1:加载驱动

             //Class.forName("com.mysql.jdbc.Driver");

             //2:获得数据库连接

             String user = "root";

             String password = "root";

             String url = "jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC";

             Connection conn = DriverManager.getConnection(url,user,password);

             //3:准备sql

             String sql = "select * from account where card_id =? and password =?";

             PreparedStatement pstm = conn.prepareStatement(sql);

             pstm.setInt(1, Integer.valueOf(card_id));

             pstm.setString(2, pwd);

             //5:如果是查询,处理结果集

             ResultSet rs = pstm.executeQuery();

             if(rs.next()){

                    System.out.println("可以取钱了");

             }else{

                    System.out.println("密码

人气教程排行