首页 > 其他分享 >JDBC p2 JDBC API

JDBC p2 JDBC API

时间:2023-07-26 17:37:02浏览次数:36  
标签:p2 JDBC java String url Driver API import properties

JDBC API

获取数据库连接5种方式

  1. 通过new创建Driver对象;
  2. 使用反射加载Driver类,动态加载,减少依赖性,更加灵活;
  3. 使用DriverManager 替代 Driver 进行统一管理,有了更好的扩展性;
  4. 使用 Class.forName 自动完成注册驱动,简化代码;
  5. 在方式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[结果集]

  • 基本介绍

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

  • 代码演示:

    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
恭喜,登录成功
*/

预处理(查询和修改)

  1. PreparedStatement 执行的SQL语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数。setXxx() 方法有两个参数,第一个参数都是int,要设置SQL语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值。
  2. 调用 executeQuery(),返回 ResultSet 对象。
  3. 调用 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
对不起,登录失败

*/

标签:p2,JDBC,java,String,url,Driver,API,import,properties
From: https://www.cnblogs.com/zh-Note/p/17583073.html

相关文章

  • kube-apiserver内存溢出问题调查及go tool pprof工具的使用
    问题描述测试集群三台master,每个master上面的kube-apiserver都频繁的重启。登录其中一台master,发现kube-apiserver的内存占用特别高,每次重启完后内存很快就飙到了20G左右,而且还有继续增长的趋势。因为默认kube-apiserver的静态pod是没有设置memeorylimit的,最终api-server会吃光......
  • 洛谷 P2894 [USACO08FEB] Hotel G 题解
    题目链接P2894[USACO08FEB]HotelG-洛谷|计算机科学教育新生态(luogu.com.cn)分析考虑用线段树维护区间信息维护sum(最大连续空房间数)如何合并?sum1为max(sum2,sum3)(1的两个子区间)但我们发现若区间为100001(0表示空房间)sum1=4而max(sum2,sum3)=2所以再维护suml(从左开始的......
  • WebApi-寄宿方式注意事项
    所谓的寄宿方式,就是把服务从原来的容器(iis、appache)中提取出来通过宿主程序来控制其启动,这样的好处就是避免了对服务器(容器)的依赖,实现灵活控制,但在实际开发中尤其是新手容易忽略的地方,这里做个简单的示例,记录一下便于以后自查。首先建立一个公共各类库Common,用于存放实体类。编......
  • 个微微信API
    你可以用微信机器人api实现个性化微信功能(例:营销系统、机器人小助手、客服系统等),用来自动管理微信消息。能开发的功能包括但不限于:**好友管理**:添加好友、删除好友、修改备注、创建标签、获取好友列表、检测僵尸粉**消息管理**:发文本消息、图片消息、名片消息、动图表情、小......
  • JDBC 工具类
    工具类JDBCUtils包括以下方法 项目结构如下 代码如下packagecom.lyl.utils;importjava.io.IOException;importjava.io.InputStream;importjava.lang.reflect.Field;importjava.sql.*;importjava.util.ArrayList;importjava.util.List;importjava.util.Pr......
  • 实习微信机器人API开发
    现在网络上资源聚集复杂,当我们想要实现一个功能时,我们已经没有必要像前辈们那样来进行繁重的造轮子的工作。目前,随着人教育体系的提高,培养出专业性人才,为解决繁重的工作带来质的飞越,也就是微信机器人的开发,帮我们抵抗了绝大部分繁重的压力。接下来向大家介绍的一所微信机器人其功......
  • fastapi文件上传下载
    importosimporttimefromfastapiimportAPIRouter,File,UploadFilefromfastapi.responsesimportFileResponserouter=APIRouter(tags=['Upload'],prefix='/upload')@router.post("",summary='文件上传')defcreate(up......
  • EBS: API创建用户
    EBS账号以员工号作为账号。DECLAREp_employee_idnumber;v_user_namevarchar2(100);v_ownervarchar2(50);v_unencrypted_passwordvarchar2(50)defaultnull;v_session_numbernumberdefaultnu......
  • 我开源了团队内部基于SpringBoot Web快速开发的API脚手架v1.6.0更新
    什么是rest-api-spring-boot-starterrest-api-spring-boot-starter适用于SpringBootWebAPI快速构建让开发人员快速构建统一规范的业务RestFullAPI不在去关心一些繁琐。重复工作,而是把重点聚焦到业务。动机每次WebAPI常用功能都需要重新写一遍。或者复制之前的项目代码......
  • JDBC preparedStatement.executeQuery() 与 preparedStatement.executeQuery(sql)
    preparedStatement.executeQuery()这个方法是执行带占位符、已经预编译的sql命令而它--->preparedStatement.executeQuery(sql)这个方法是执行未预编译、完整的sql命令,而不是预编译的sql命令preparedStatement不是应该执行预编译的sql吗?是这样的,但是preparedStatement还兼......