自由的羽毛 发表于 2023-7-26 17:07:23

JDBC p2 JDBC API

JDBC API

获取数据库连接5种方式


[*]通过new创建Driver对象;
[*]使用反射加载Driver类,动态加载,减少依赖性,更加灵活;
[*]使用DriverManager 替代 Driver 进行统一管理,有了更好的扩展性;
[*]使用 Class.forName 自动完成注册驱动,简化代码;
[*]在方式4的基础上改进,增加配置文件,让mysql连接更灵活,最推荐使用;
代码演示:
package com.hspedu.jdbc;

import com.mysql.jdbc.Driver;
import org.junit.jupiter.api.Test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
* 分析java连接mysql的5种方式
*/
public class JdbcConn {
    //方式1
    @Test
    public void connect01() throws SQLException {
      Driver driver = new Driver();
      String url = "jdbc:mysql://localhost:3306/jdbc_learning";
      Properties properties = new Properties();
      properties.setProperty("user", "root");//用户名
      properties.setProperty("password", "root");//密码
      Connection connection = driver.connect(url, properties);
      System.out.println("第一种方式" + connection);
      connection.close();
    }
    //方式2
    @Test
    public void connect02() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
      //使用反射加载Driver类,动态加载,减少依赖性,更加灵活
      Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
      Driver driver = (Driver) aClass.newInstance();

      String url = "jdbc:mysql://localhost:3306/jdbc_learning";
      Properties properties = new Properties();
      properties.setProperty("user", "root");//用户名
      properties.setProperty("password", "root");//密码
      Connection connection = driver.connect(url, properties);
      System.out.println("第二种方式" + connection);
      connection.close();
    }

    //方式3 使用DriverManager 替代 Driver 进行统一管理,有了更好的扩展性
    @Test
    public void connect03() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
      //使用反射加载Driver类
      Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
      Driver driver = (Driver) aClass.newInstance();

      String url = "jdbc:mysql://localhost:3306/jdbc_learning";
      String user = "root";
      String password = "root";

      DriverManager.registerDriver(driver);//注册Driver驱动,DriverManager是Java自带的类

      Connection connection = DriverManager.getConnection(url, user, password);
      System.out.println("第三种方式" + connection);
    }

    //方式4 使用 Class.forName 自动完成注册驱动,简化代码
    //这种方式推荐使用,使用最多
    @Test
    public void connect04() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
      //使用反射加载Driver类
      //在加载 Driver类时,完成注册
      /*
            源码:1. 静态代码块,在类加载时,会执行一次
               2. 因此注册driver的工作在底层已经完成了
            static {
                        try {
                            DriverManager.registerDriver(new Driver());
                        } catch (SQLException var1) {
                            throw new RuntimeException("Can't register driver!");
                        }
                  }
         */
      //1.mysqL驱动5.1.6可以无需CLass.forName("com.mysql.jdbc.Driver");
      //2.从jdk1.5以后使用了jdbc4,不再需要显示调用class.forName()注册驱动而是自动调用驱动
      //jar包下META-INF\services\java.sql.Driver文本中的类名称去注册
      //3.建议还是写上CLass.forName("com.mysql.jdbc.Driver"),更加明确
      Class.forName("com.mysql.jdbc.Driver");//内部有一段静态代码会默认自动注册

      String url = "jdbc:mysql://localhost:3306/jdbc_learning";
      String user = "root";
      String password = "root";

      Connection connection = DriverManager.getConnection(url, user, password);
      System.out.println("第四种方式" + connection);
    }

    //方式5 在方式4的基础上改进,增加配置文件,让mysql连接更灵活,最推荐使用
    @Test
    public void connect05() throws IOException, ClassNotFoundException, SQLException {
      //通过Properties对象获取配置文件的信息
      Properties properties = new Properties();
      properties.load(new FileInputStream("src\\mysql.properties"));
      //获取相关的值
      String user = properties.getProperty("user");
      String password = properties.getProperty("password");
      String driver = properties.getProperty("driver");
      String url = properties.getProperty("url");

      Class.forName(driver);//建议写上

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

      System.out.println("第五种方式" + connection);
    }
} 配置文件mysql.properties:
user=root
password=zyl
url=jdbc:mysql://localhost:3306/jdbc_learning
driver=com.mysql.jdbc.Driver ResultSet[结果集]



[*] 基本介绍

[*]表示数据库结果集的数据表,通常通过执行查询数据库的语句生成;
[*]ResultSet对象保持一个光标指向其当前的数据行。最初,光标位于第一行前;
[*]next方法将光标移动到下一行,并且由于在ResultSet对象中没有更多行时返回false,因此可以在while循环中使用循环来遍历结果集。
https://img2023.cnblogs.com/blog/3008601/202307/3008601-20230726171724383-1169303796.png

[*] 代码演示:
package com.hspedu.jdbc.resultset_;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
* @author: 86199
* @date: 2023/6/14 21:52
* Description: 演示select 语句 返回 ResultSet,并取出结果
*/
@SuppressWarnings({"all"})
public class ResultSet_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
      //通过Properties对象获取配置文件的信息
      Properties properties = new Properties();
      properties.load(new FileInputStream("src\\mysql.properties"));
      //获取相关的值
      String user = properties.getProperty("user");
      String password = properties.getProperty("password");
      String driver = properties.getProperty("driver");
      String url = properties.getProperty("url");

      //1. 注册驱动
      Class.forName(driver);//建议写上

      //2. 得到连接
      Connection connection = DriverManager.getConnection(url, user, password);

      //3. 得到Statement
      Statement statement = connection.createStatement();

      //组织sql语句
      String sql = "select id, name, sex, borndate from actor;";
      /*
      1        周星驰        男        1970-11-11 00:00:00        110
      2        刘德华        男        1970-11-11 00:00:00        110
      3        刘德华        男        1970-11-11 00:00:00        110
         */
      //执行给定的SQL语句,该语句返回单个ResultSet对象
      /*
            源码:
         */
      ResultSet resultSet = statement.executeQuery(sql);

      while (resultSet.next()) {//让光标后移,如果没有更多行,则返回false
            int id = resultSet.getInt(1);//获取该行的第1列
            String name = resultSet.getString(2);//获取该行的第2列
            String sex = resultSet.getString(3);
            String date = resultSet.getString(4);
            System.out.println(id + "\t" + name + "\t" + sex + "\t" + date);
      }


      //关闭资源
      resultSet.close();
      statement.close();
      connection.close();
    }
}





## Statement对象

- **基本介绍**
1. Statement对象,用于执行静态SQL语句并返回其生成的结果的对象。
2. 在连接建立之后,需要对数据库进行访问,执行命名或是SQL语句,可以通过
   - Statement [存在SQL注入]
   - ==PreparedStatement==(预处理)
   - CallableStatement(存储过程)
3. Statement对象执行SQL语句存在==SQL注入==的风险
   - **SQL注入**是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段或命令,恶意攻击数据库。
   - 要防范 SQL注入,只要用 **PreparedStatement**(从Statement扩展而来)取代 Statement 就可以了。

**MySQL代码:**

​```mysql
-- 演示sql注入
-- 创建一张表
CREATE TABLE admin ( -- 管理员表
`name` VARCHAR(32) NOT NULL UNIQUE,
pwd VARCHAR(32) NOT NULL DEFAULT '') CHARACTER SET utf8;

-- 添加数据
INSERT INTO admin VALUES('jac', '123');

-- 查找某个管理员是否存在
SELECT *
FROM admin
WHERE `name` = 'tom' AND pwd = '123';

-- SQL注入
-- 输入用户名 1' or
-- 输入密码 为 or '1' = '1
-- SELECT *
-- FROM admin
-- WHERE `name` = '' AND pwd = '';

SELECT *
FROM admin
WHERE `name` = '1' or' AND pwd = 'or '1' = '1'; Java代码:
package com.hspedu.jdbc.statement_;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;

/**
* @author: 86199
* @date: 2023/6/15 22:24
* Description: 演示 SQL注入的问题
*/
public class Statement_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {

      Scanner scanner = new Scanner(System.in);

      //让用户输入管理员用户名和密码
      System.out.print("请输入管理员名字:");
      String admin_name = scanner.nextLine();
      System.out.print("请输入管理员密码:");
      String admin_pwd = scanner.nextLine();

      //通过Properties对象获取配置文件的信息
      Properties properties = new Properties();
      properties.load(new FileInputStream("src\\mysql.properties"));
      //获取相关的值
      String user = properties.getProperty("user");
      String password = properties.getProperty("password");
      String driver = properties.getProperty("driver");
      String url = properties.getProperty("url");

      //1. 注册驱动
      Class.forName(driver);//建议写上

      //2. 得到连接
      Connection connection = DriverManager.getConnection(url, user, password);

      //3. 得到Statement
      Statement statement = connection.createStatement();

      //组织sql语句
      String sql = "SELECT name, pwd FROM admin where name ='"
                + admin_name + "' and pwd = '" + admin_pwd + "';";

      ResultSet resultSet = statement.executeQuery(sql);

      if (resultSet.next()) {//如果查询到一条记录,说明该管理员存在
            System.out.println("恭喜,登录成功");
      }else{
            System.out.println("对不起,登录失败");
      }

      resultSet.close();
      statement.close();
      connection.close();
    }
}

//运行
/*
请输入管理员名字:1' or
请输入管理员密码:or '1' = '1
恭喜,登录成功
*/ 预处理(查询和修改)


[*]PreparedStatement 执行的SQL语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数。setXxx() 方法有两个参数,第一个参数都是int,要设置SQL语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值。
[*]调用 executeQuery(),返回 ResultSet 对象。
[*]调用 executeUpdate():执行更新,包括增,删,修改
package com.hspedu.jdbc.preparedstatement_;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;

/**
* @author: 86199
* @date: 2023/7/17 20:43
* Description: 演示PreparedStatement使用
*/
public class PreparedStatement_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {

      Scanner scanner = new Scanner(System.in);

      //让用户输入管理员用户名和密码
      System.out.print("请输入管理员名字:");
      String admin_name = scanner.nextLine();
      System.out.print("请输入管理员密码:");
      String admin_pwd = scanner.nextLine();

      //通过Properties对象获取配置文件的信息
      Properties properties = new Properties();
      properties.load(new FileInputStream("src\\mysql.properties"));
      //获取相关的值
      String user = properties.getProperty("user");
      String password = properties.getProperty("password");
      String driver = properties.getProperty("driver");
      String url = properties.getProperty("url");

      //1. 注册驱动
      Class.forName(driver);//建议写上

      //2. 得到连接
      Connection connection = DriverManager.getConnection(url, user, password);


      //sql中的?就相当于占位符
      String sql = "SELECT name, pwd FROM admin where name =? and pwd = ? ;";

      //3. 得到PreparedStatement,这里的statement是实现了PreparedStatement接口的实现类的对象
      PreparedStatement statement = connection.prepareStatement(sql);

      //给 ? 赋值
      statement.setString(1, admin_name);
      statement.setString(2, admin_pwd);

      //执行sql语句,如果执行的是dml语句要用executeUpdate()
      ResultSet resultSet = statement.executeQuery();//()中不能再写sql语句,不然执行的就是带?的,填了sql语句就是调用了父类Statement的方法了

      if (resultSet.next()) {//如果查询到一条记录,说明该管理员存在
            System.out.println("恭喜,登录成功");
      }else{
            System.out.println("对不起,登录失败");
      }

      //关闭链接
      resultSet.close();
      statement.close();
      connection.close();
    }
}
//运行
/*
请输入管理员名字:1' or
请输入管理员密码:or '1' = '1
对不起,登录失败

*/
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: JDBC p2 JDBC API