JDBC链接MySql及查询操作

目录

一:使用JDBC的准备工作

二:连接数据库的简单流程

2.1:注册驱动

2.2:获取连接

2.3:创建发送SQL语句对象

2.4:发送sql语句,并获取返回结果

2.5:结果集解析

​2.6:资源关闭

三:上述操作存在的问题及改进

3.1:注册驱动操作冗余

3.2:Statement语句的危险性

四:查询代码样例


一:准备工作

使用JDBC前需前往MySql官网下载JDBC提供的类文件,下载箭头所指文件并解压,在你的IDEA项目中创建lib文件,并将其解压后的.jar文件放入,并将其中jar文件导入你的工程文件模块即可。最后再创建一个自己的数据库(本篇用mydb作为样例)https://dev.mysql.com/downloads/connector/j/

 安装成功后我选择创建一个名为"mydb"的数据库,其中有一个students表储存了学生信息

二:连接数据库的简单流程

大致分为以下6步:

2.1:注册驱动

使用registerDriver方法进行注册,

DriverManager.registerDriver(new Driver());


2.2:获取连接

getConnection(String url,String user,String password)

Connection connection=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb","root","222222");
//url写法:"jdbc:数据库名://数据库ip,是本机就填127.0.0.1:端口(默认3306)/目标数据库"
    //本机例子:jdbc:mysql://127.0.0.1:3306/mydb  或可简写为 jdbc:mysql:///mydb


2.3:创建发送SQL语句对象

Statement statement=connection.createStatement();


2.4:发送sql语句,并获取返回结果

String inf="select * from students;";
    ResultSet resultSet=statement.executeQuery(inf);


2.5:结果集解析

其所返回的resultSet是一个将数据打包成的类,其中提供了许多定位数据的方法。.next方法会根据下一条的数据内容是否为空来返回boolean类型。.get参数()方法提供了使用脚标返回列元素,使用当前列名返回列元素这两种方法来返回数据。例如目前表中有这样的数据,并且数据解析代码如下

while(resultSet.next()){
            int a=resultSet.getInt(1);
            String b=resultSet.getString("name");
            int c=resultSet.getInt(3);
            String d=resultSet.getString("residence");
            System.out.printf("%d %s %d %s\n",a,b,c,d);
        }

 结果如下:


2.6:资源关闭

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

三:上述操作存在的问题及改进

3.1:注册驱动操作冗余

通关观察DriverManager.registerDriver(new Driver());中的.register()方法和Driver()方法的源代码可见

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }
    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}//Driver方法

public static void registerDriver(java.sql.Driver driver)
        throws SQLException {

        registerDriver(driver, null);
    }//registerDriver方法

当执行上述语句时,执行了两次注册操作,并且在Driver()方法中,注册操作是在静态代码块中,因此我们改为使用反射中的方法.Class.forName("此处传入数据库的Driver方法的类名");用此方法来注册还易于多数据库的更改

Class.forName("com.mysql.cj.jdbc.Driver");//使用反射进行注册驱动

3.2:Statement语句的危险性

我们传入sql语句时,有可能是经过拼接后才传入的,此时如果传入特定字符串会导致sql语句变为一串特殊的动态判断语句,这样可能会引发sql注入攻击导致数据泄漏。

解决方案:使用PreparedStatement(预编译的Statement)代替Statement

使用方法:

        先定义sql语句,再传入PreparedStatement进行预处理,注意这里的sql语句不同于上述sql语句的规范,当我们想对sql语句进行拼接操作时,拼接的内容需要用'?'来进行代替,例如想要查询住在一号楼并且分数小于90的同学的信息

String sql="Select * from students where residence = ? and score< ?";
//声明查询语句,关键词用'?'代替

PreparedStatement preparedStatement= connection.prepareStatement(sql);
//此句与Statement相似,并且要先传入语句进行预处理

preparedStatement.setObject(1,"一号楼");
preparedStatement.setObject(2,90);
//.setObject(int Index,Object x)Index传入的是第n个参数的位置,位置从1开始

ResultSet resultSet=preparedStatement.executeQuery();

由上述代码可知,PreparedStatement发送sql的位置和Statement不同,因为上面建立连接时已经传入。

四:正确查询样例

有一个学生表,先想查询分数小于90并且住在一号楼的学生信息。数据库为mydb,用户为root,密码为222222

public static void main(String[] args)throws Exception{
        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");//会自动激活目标类的静态代码区

        //获取连接
        Connection connection= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb","root","222222");

        //创建连接对象
        String sql="Select * from students where residence = ? and score< ?";
        PreparedStatement preparedStatement= connection.prepareStatement(sql);
        preparedStatement.setObject(1,"一号楼");
        preparedStatement.setObject(2,90);

        //获取结果
        ResultSet resultSet=preparedStatement.executeQuery();

        //解析结果集
        while(resultSet.next()){
            int a=resultSet.getInt(1);
            String b=resultSet.getString("name");
            int c=resultSet.getInt(3);
            String d=resultSet.getString("residence");
            System.out.printf("%d %s %d %s\n",a,b,c,d);
        }
        //进行回收
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }

返回结果如下: