美文网首页
JDBC 编程学习

JDBC 编程学习

作者: CSeroad | 来源:发表于2021-06-12 16:46 被阅读0次

前言

将最近学习的JDBC编程整理成笔记,做次记录。

mysql 安装

首先安装mysql 8.0.19 版本数据库。
下载地址 https://downloads.mysql.com/archives/community/
下载完成后点击默认安装即可。

image.png image.png

默认安装到了C:\Program Files\MySQL\MySQL Server 8.0\bin目录下。
关于mysql的一些命令:

mysqld.exe --initialize-insecure 初始化数据库,执行后会生成data文件夹
mysqld.exe --install  安装mysql服务
net start mysql  启动mysql服务
set password for root@localhost = password('password');  修改密码
flush privileges 刷新权限

JDBC 简介

JDBC全称是Java DataBase Connectivity的缩写,是Java程序访问数据库的标准接口。
使用java里面提供的一些类和方法,利用程序链接数据库,进行增删改查,这个过程叫JDBC编程。
要实现JDBC编程,除了java.sql标准库,还需要找一个MySQL的JDBC驱动。其实就是一个第三方jar包。

这里下载mysql-connector-java-8.0.23 版本的jar包。 https://dev.mysql.com/downloads/connector/j/

下载后在eclipse 引入jar包。

image.png

并添加到项目库。

image.png

JDBC 编程

JDBC编程主要分为六步操作:

  1. 加载驱动程序
  2. 连接数据库
  3. 获取数据库操作对象
  4. 执行sql语句
  5. 处理查询结果集
  6. 释放连接

举个栗子:
实现最简单的查询语句

package jdbc_test;

import java.sql.*;

public class jdbcdemo01 {
    /**
     * 
     * @param username
     * @param password
     * @throws SQLException 
     */
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        Statement stmt=null;
        ResultSet rs=null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
            
            String url = "jdbc:mysql://localhost:3306/web?useUnicode=true&characterEncoding=UTF8&userSSL=true";
            String user = "root";
            String pass = "";
            conn = DriverManager.getConnection(url,user,pass);//获取连接
            stmt = conn.createStatement();//获取数据库操作对象
            String sql = "select * from user";
            rs = stmt.executeQuery(sql);//执行sql语句
            
            while(rs.next()) {
                System.out.print(rs.getInt(1)+","+rs.getString("username")+","+rs.getString(3)+","+rs.getString(4));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放资源
            rs.close();
            stmt.close();
            conn.close();
        }
    }
}

注意:url地址的完整度,执行查询语句用的是executeQuery方法,以及驱动连接用的是Class.forName()
还有一种方式也可以实现。

DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());// 第二种

new com.mysql.cj.jdbc.Driver()创建对象的时候本质上也执行了DriverManager.registerDriver(driver),这样一来就重复了,所以我们更习惯使用Class.forName()

第二个例子,更新语句

package jdbc_test;

import java.sql.*;

public class jdbcdemo01 {
    /**
     * 
     * @param username
     * @param password
     * @throws SQLException 
     */
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        Statement stmt=null;
        
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
            String url = "jdbc:mysql://localhost:3306/web?useUnicode=true&characterEncoding=UTF8&userSSL=true";
            String user = "root";
            String pass = "";
            conn = DriverManager.getConnection(url,user,pass);//获取连接
            stmt = conn.createStatement();//获取数据库操作对象
            String sql = "update user set loginpwd=123456789 where id=1";
            int count = stmt.executeUpdate(sql);//执行sql语句
            System.out.println(count == 1 ? "更新成功" : "更新失败");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放资源
            stmt.close();
            conn.close();
        }
    }
}

注意:更新方法用的是executeUpdate,包括插入、删除、更新,并返回一个int值,所以自然也没有查询记过集
区分一下这两个方法。

int executeUpdate(insert/delete/update)
Resultset executeQuery(select)

PreparedStatement 对象

在了解PreparedStatement对象之前,先设计一个登录的demo,并尝试一种工具类提取的方式编写代码。
首先新建db.properties文件,提取出连接数据库的信息。

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/web?useUnicode=true&characterEncoding=UTF8&userSSL=true
username=root
password=

再提取出jdbc连接工具类JdbcUtils.java

package jdbc_test;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;

// 提取工具类
public class JdbcUtils {
    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;
    
    
    static {
        InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties = new Properties();
        try {
            properties.load(in);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            
            // 加载驱动
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }
    
    // 释放连接资源
    public static void release(Connection conn,Statement st,ResultSet rs) {
            if(rs!=null) {try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }}
            if(st!=null) {try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }}
            if(conn!=null) {try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }}
    }

}

最后再编写jdbcDemo3.java,来实现用户登录。
jdbcDemo3.java

package jdbc_test;

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


public class jdbcdemo3 {
    
    public static void main(String[] args) {
        Map userlogininfo = loginit();
        String loginName = (String) userlogininfo.get("username");
        String loginPwd = (String) userlogininfo.get("password");
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            stmt = conn.createStatement();
            String sql = "select * from user where loginName='"+loginName+"' and loginPwd='"+loginPwd+"' ";
            rs = stmt.executeQuery(sql);
            if(rs.next()) {
                System.out.print("login success");
            }else {
                System.out.print("login false");
            }
        }catch (Exception e) {
             e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
     private static Map loginit() {
            Scanner s = new Scanner(System.in);
            System.out.print("username:");
            String username = s.nextLine();
            System.out.print("password:");
            String password = s.nextLine();
            Map userlogininfo = new HashMap();
            userlogininfo.put("username",username);
            userlogininfo.put("password",password);
            return userlogininfo;
            
        }
}

尝试登录。

image.png

但是该编写方式存在sql注入问题,当用户输入特殊的用户名、密码时,也可以登录成功。
a' or 1='1

image.png

这是因气真值 or 真值 and 假值 or 真值,结果即为真值。会查询出所有结果。

image.png

那么该如何解决sql注入的问题呢?这就有了PreparedStatement 对象。
该对象用来防止sql注入,是Statement的子类,可对sql进行预编译,从而提高数据库的执行效率。
修改jdbcDemo3.java

package jdbc_test;

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


public class jdbcdemo3 {
    
    public static void main(String[] args) {
        Map userlogininfo = loginit();
        String loginName = (String) userlogininfo.get("username");
        String loginPwd = (String) userlogininfo.get("password");
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select * from user where loginName = ? and loginPwd= ? ";
            //?代表占位符,不能使用单引号括起来
            stmt = conn.prepareStatement(sql);//sql语句的预先编译
            //再给占位符传值,即使再注入,sql语句也没有编译
            stmt.setString(1, loginName);
            stmt.setString(2, loginPwd);
            rs = stmt.executeQuery();//执行sql语句
            if(rs.next()) {
                System.out.print("login success");
            }else {
                System.out.print("login false");
            }
        }catch (Exception e) {
             e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
     private static Map loginit() {
            Scanner s = new Scanner(System.in);
            System.out.print("username:");
            String username = s.nextLine();
            System.out.print("password:");
            String password = s.nextLine();
            Map userlogininfo = new HashMap();
            userlogininfo.put("username",username);
            userlogininfo.put("password",password);
            return userlogininfo;
            
        }
}

注意:无法sql注入就是因为PreparedStatement 对象在执行sql语句时先进行了预编译

image.png

总结

学习了JDBC的基本过程,复习了db.properties文件、代码层的sql注入,蛮有收获,继续加油。

参考资料

https://www.bilibili.com/video/BV1NJ411J79W?p=36

相关文章

  • JDBC 编程学习

    前言 将最近学习的JDBC编程整理成笔记,做次记录。 mysql 安装 首先安装mysql 8.0.19 版本数据...

  • JDBC编程目录

    JDBC编程目录 SQL基础JDBC基础JDBC进阶

  • 第一章 简介

    1.1 The JDBC API jdbctm API提供了从JavaTM编程语言编程访问关系型数据。使用JDBC...

  • Java数据库连接——JDBC编程

    本文概述 本篇文章将分四块内容对JDBC编程进行介绍:一. JDBC编程概述二. JDBC开发步骤三. 工具类撰写...

  • JDBC编程:JDBC高级编程

    事物处理 批量更新 返回自动主键 DAO 1,事物处理 什么是事物? 事务(Transaction):数据库中保证...

  • Mybatis_day01

    1 Mybatis入门 1.1 单独使用jdbc编程问题总结 1.1.1 jdbc程序 上边使用jdbc的原始方法...

  • java_JDBC

    1.JDBC是什么 2.JDBC本质 3.JDBC前期的准备工作 4.JDBC编程六步

  • 1-JDBC是什么

    JDBC概念 JDBC (Java Database Connectivity) API,即Java数据库编程接口...

  • java数据库管理之jdbc

    JDBC的开发步骤 注入攻击(不用这个代码编程序) (用这个代码编程序) 更新操作 JDBC的工具类(代码固定) ...

  • MyBatis详解1.概述

    点击进入我的博客 1 JDBC编程 什么是JDBC Java程序都是通过JDBC(Java Data Base C...

网友评论

      本文标题:JDBC 编程学习

      本文链接:https://www.haomeiwen.com/subject/imjpxltx.html