JDBC 专栏总集篇

JDBC

概念

Java Data Base Connectivity (Java 连接数据库)
JDBC,其实就是Java定义的一套和数据库建立连接的规范(接口),
那么各家数据库厂商,想要Java去操作各家的数据库,
必须实现这套接口,
我们把数据库厂商写的这套实现类,称之为数据库驱动

没有jdbc之前
我们想用Java连接数据库,需要进行如下步骤:

没有jdbc之前

虽然也不是非常麻烦,但是:

  1. 针对不同的数据库,我们需要编写不同的驱动代码
  2. 每当任意一家数据库更新时,维护起来也是十分麻烦的

正是因为上述两点致命麻烦,Java针对连接数据库,提出了一套机制 —— JDBC

有jdbc之后

因此,JDBC有如下优点
优点

  1. 维护方便
  2. 数据库厂商的底层实现改变,不影响Java应用程序

一般地,jdbc的接口,都存放在:

JDK提供的

  1. java.sql.*
  2. javax.sql.*

包下


那么,现在本人来讲解下使用JDBC的使用步骤:

使用步骤:

使用步骤

  1. 导入数据库的驱动jar包
  2. 加载驱动jar包
  3. 获取连接对象
  4. 获取操作对象
  5. 开始操作
  6. 释放资源

那么,现在本人来展示下JDBC的使用:

package edu.youzg.about_jdbc.core;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class Demo {
    
    public static void main(String[] args) throws Exception {
        //2. 加载驱动jar包
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/dbstudy";
        String userName = "root";
        String password = "123456";
        //3. 获取连接对象
        Connection connection = DriverManager.getConnection(url, userName, password);
        //4. 获取操作对象
        Statement statement = connection.createStatement();
        String sql = "update test set emp_fname='Youzg'";
        //5. 开始操作
        int i = statement.executeUpdate(sql);
        if(i>0){
            System.out.println(i);
            System.out.println("修改成功");
        }else{
            System.out.println("修改失败");
        }
        //6. 释放资源
        connection.close();
        statement.close();
    }
    
}

本人先来展示下运行前的表内容:


运行前 展示

现在,本人来展示下运行后的表中数据:


运行后 展示

那么,本人对上述步骤的第2步进行下讲解:

  • execute(sql):
    用来执行所有的SQL语句
    返回
    如果第一个结果ResultSet 对象,则返回 true
    如果其为更新、计数或者不存在任何结果,则返回 false
  • executeUpdate(sql):
    用来执行DML语句
    用来对表中数据进行增、删、改
    返回值
    影响的行数
  • executeQuery(sql):
    用来执行DQl语句

结果集对象 ResultSet:

概念:
结果集对象,是我们执行了查询语句之后返回的一个查询结果对象
ResultSet 对象具有指向其当前数据行的光标
最初,光标被置于第一行之前
next()方法将光标移动到下一行
因为该方法在 ResultSet 对象没有下一行返回 false
所以可以在 while循环中使用它来迭代结果集

例如:
现在我要查询表中数据:

package edu.youzg.about_jdbc.core;

import java.sql.*;

public class Demo2 {
    
    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbstudy", "root", "123456");
        Statement statement = connection.createStatement();
        String sql = "select * from test";
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()) {
            System.out.println(resultSet.getInt(1)
                    + "==" + resultSet.getString(2)
                    + "==" + resultSet.getString(3)
                    + "==" + resultSet.getString(4));
        }
        connection.close();
        statement.close();
        resultSet.close();
    }
    
}

那么,本人现在来展示下运行结果:


查询结果 展示

那么,还记得本人在《Java SE》专栏最后说的吗?

等我们学习了数据库的相关知识后,
用户登录信息就可以保存在数据库中,就不用用一张配置表来保存了
这样既简化了注册用户的问题,也保证了用户账号信息的安全性

本人来给出一张保存用户登录信息的表:


用户登录表 展示

那么,现在本人仅来展示下检验用户信息的代码:

package edu.youzg.about_jdbc.core;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class LoginDemo {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = sc.nextLine().trim();
        System.out.println("请输入密码");
        String password = sc.nextLine().trim();
        //使用JDBC登录
        Class.forName("com.mysql.jdbc.Driver");
        //建立连接
        Connection conn = DriverManager.getConnection("jdbc:mysql:///dbstudy", "root", "123456");
        //获取操作对象
        Statement statement = conn.createStatement();
        //发送sql语句判断是否登录成功
        String sql="select * from users where username='"+username+"' and password='"+password+"'";

        ResultSet resultSet = statement.executeQuery(sql);
        if(resultSet.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
        //释放资源
        conn.close();
        statement.close();
        resultSet.close();
    }
}

那么,本人来展示下运行结果:


用户登录1 展示

其实,上面的做法也是不安全的
本人现在来展示下为什么说是不安全的

用户登录2 展示

相信同学们这时候就疑惑了:为什么用户登录信息表中并没有保存该登录信息,却能够登陆呢?
答曰

请看我们最后拼出来的sql字符串:
select * from users where username='1' or '1'='1' and password='1' or '1'='1';

相信看到这里,同学们就明白了登陆成功的原因了。
而这种现象,我们也有专门的名词来形容它 —— sql注入

那么,有没有什么办法能够防止sql注入呢?
答曰:

预编译操做对象 PreparedStatement


那么,现在本人来介绍下 预编译操做对象 PreparedStatement

PreparedStatement:

使用步骤

  1. 连接对象.prepareStatement(sql);
  2. sql语句中的字段的值?问号占位
  3. 给sql语句中的问号赋值

本人现在来展示下PreparedStatement的使用:

package edu.youzg.about_jdbc.core;

import java.sql.*;
import java.util.Scanner;

public class LoginDemo1 {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = sc.nextLine().trim();
        System.out.println("请输入密码");
        String password = sc.nextLine().trim();
        //使用JDBC登录
        Class.forName("com.mysql.jdbc.Driver");
        //建立连接
        Connection conn = DriverManager.getConnection("jdbc:mysql:///dbstudy", "root", "123456");
        //获取操作对象
        String sql="SELECT * FROM users WHERE username=? AND PASSWORD=?";
        //获取一个预编译操作对象  PreparedStatement
        PreparedStatement preparedStatement = conn.prepareStatement(sql); //把SQL语句给给这个预编译操作对象
        //下来给问号赋值 参1.问号的顺序,从1开始数 参数2 问号的值
        preparedStatement.setString(1,username);
        preparedStatement.setString(2,password);

        ResultSet resultSet = preparedStatement.executeQuery(); //这里就不要再传入SQL语句
        if(resultSet.next()){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
        //释放资源
        conn.close();
        preparedStatement.close();
        resultSet.close();
    }
}

那么,本人再来进行下sql注入,来展示下运行结果:


防止sql注入 展示

可以看到:预编译操作对象的使用,放置了sql注入!


那么,为了方便我们之后的操作,本人来给出一个方便我们JDBC操作的工具类:

package edu.youzg.about_jdbc.utils;

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

/**
 * 此工具用于实现JDBC的基本 增、删、改、查 操作
 */
public class JDBCUtils {
    private static String url;
    private static String user;
    private static String password;

    private JDBCUtils() {
    }

    static {
        try {
            //读取配置文件中数据库的配置
            Properties properties = new Properties();
            properties.load(new FileInputStream("JDBCStudy/src/jdbcConfig.properties"));
            //注册驱动
            Class.forName(properties.getProperty("driver"));
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password =properties.getProperty("password");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException {
        Connection connection = DriverManager.getConnection(url, user, password);
        return connection;
    }

    public static void close(Connection connection, Statement statement) throws SQLException {
        if (connection != null) {
            connection.close();
        }
        if (statement != null) {
            statement.close();
        }
    }

    public static void close(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
        if (connection != null) {
            connection.close();
        }
        if (statement != null) {
            statement.close();
        }
        if (resultSet != null) {
            resultSet.close();
        }
    }

}

那么,相应地,本人来给出一个配置文件:

driver=com.mysql.jdbc.Driver
#注意:这里的url是本人根据本人的数据库信息配置的,同学们请根据自己的数据库信息来给url赋值
url=jdbc:mysql://localhost:3306/dbstudy
user=root
password=123456

在本篇博文的最后,本人来讲解下如何在JDBC中获取自增长键的值:

获取自增长键的值:

步骤

  1. 要获取自增长键的值,需要在获取操作对象时声明一个参数:
    Statement.RETURN_GENERATED_KEYS
    即:
PreparedStatement preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
  1. 当数据插入成功后,就可以取出这个自增长键的值:
//获取自增长键的结果集
ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
while (generatedKeys.next()){
    keyValue = generatedKeys.getInt(1);
}
  1. 之后就可以对循环中每次取出的自增长键值做处理了

你可能感兴趣的:(JDBC 专栏总集篇)