JDBC - java语言连接数据库、完成增删改查、解决SQL注入问题(详细)

目录

一、基本介绍

1.为什么面向接口编程?

2、JDBC编程六部概述

二、使用JDBC完成增删改查操作

1.完成简单  增加  操作

2.完成简单 删除  操作

3.完成简单 更新  操作

4.完成简单的查询操作

三、从属性资源文件中读取连接到数据库

四、解决SQL注入问题

1.演示SQL注入问题

2.解决SQL注入问题

3.对比PreparedStatement与Statement

五、PreparedStatement完成增删改以及模糊查询

六、JDBC事务机制


一、基本介绍

本质上来说,JDBC本质是SUN公司制定的一套接口(接口都有调用者和实现者)

 

JDBC 接口一套interface可以在API帮助文档下 java.sql找到

1.为什么面向接口编程?

解耦合:降低程序的耦合度,提高程序的扩展力。

(多态机制是非常典型的面向抽象编程)

2、JDBC编程六部概述

背过!!!!!!!!!!!!!!!!!

(1)注册驱动(告诉java程序,告诉java程序即将要连接的是哪个品牌的数据库)

  例子:

方法1:

//          1.注册驱动
//          前后Driver不是同一个Driver
//          Driver driver 是java.sql包下的
            Driver driver = new com.mysql.cj.jdbc.Driver();
            DriverManager.registerDriver(driver);

方法二: 常用

public class JDBCTest03 {
    public static void main(String[] args) {
        try {
//            1.注册驱动  这种经常使用
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Class.forName()会导致类的加载,类加载之后,静态代码块就会执行,我们可以从下图中可以看到,在静态代码块中,我们的驱动就new了,就创建了(这个地方很巧妙) 

(2)获取连接(表示JVM的进程和数据库进程之间的通道打开了,属于进程之间的通信,使用完要关闭)

例子:

//          2.获取连接
            String url="jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT";
            String username="root";
            String password="admin";
            Connection conn = DriverManager.getConnection(url,username,password);

(3)获取数据库操作对象(专门执行SQL语句的对象)

例子:

//           3.获取数据库操作对象(专门执行SQL语句)
             Statement statement= conn.createStatement();

(4)执行SQL语句(DQL、DML等)

例子:

//           4.执行SQL语句
            String sql = "insert into t_book(id,bookName,statue,type) value(44,44,44,44)";
//          专门执行DML语句(增删改)
//          返回值是“影响数据库中的影响条数”
            int count = statement.executeUpdate(sql);

(5)处理查询结果集(只有当第四步执行的是select语句的时候,才执行第五步,否则不执行)

(6)释放资源(使用完资源之后一定要关闭资源。java和数据库属于进程间的通信,开启后一定要关闭)

           为了保证资源一定释放,要在finally代码块中关闭资源,  按照从小到大依次关闭

二、使用JDBC完成增删改查操作

  1.完成简单  增加  操作

import java.sql.*;

public class JDBCConnection {
    public static void main(String[] args) {
        Connection conn =null;
        Statement statement=null;
        try {
//          1.注册驱动
            Driver driver = new com.mysql.cj.jdbc.Driver();
            DriverManager.registerDriver(driver);

//          2.获取连接
            String url="jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT";
            String username="root";
            String password="admin";
            conn = DriverManager.getConnection(url,username,password);


//           3.获取数据库操作对象(专门执行SQL语句)
            statement= conn.createStatement();
//           4.执行SQL语句
            String sql = "insert into t_book(id,bookName,statue,type) value(44,44,44,44)";
//          专门执行DML语句(增删改)
//          返回值是“影响数据库中的影响条数”
            int count = statement.executeUpdate(sql);
            System.out.println("sql命令影响数据库条数:"+count);
//          5.处理查询结果集,因为我们没有执行查询操作,所以第五步省略

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
//          6.释放资源
//            为了保证资源一定释放,要下载finally代码块中关闭资源
//            按照从小到大依次关闭
           if(statement!=null){
               try {
                   statement.close();
               } catch (SQLException e) {
                   e.printStackTrace();
               }
           }
           if(conn!=null){
               try {
                   conn.close();
               } catch (SQLException e) {
                   e.printStackTrace();
               }
           }
        }
    }
}

2.完成简单 删除  操作

import java.sql.*;

public class JDBCTest02 {
    public static void main(String[] args) {
        Connection conn =null;
        Statement statement=null;
        try {
//          1.注册驱动
            Driver driver = new com.mysql.cj.jdbc.Driver();
            DriverManager.registerDriver(driver);

//          2.获取连接
            String url="jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT";
            String username="root";
            String password="admin";
            conn = DriverManager.getConnection(url,username,password);


//           3.获取数据库操作对象(专门执行SQL语句)
            statement= conn.createStatement();
//           4.执行SQL语句
            String sql = "delete from t_book where id=44";
//          专门执行DML语句(增删改)
//          返回值是“影响数据库中的影响条数”
            int count = statement.executeUpdate(sql);
            System.out.println("sql命令影响数据库条数:"+count);
//          5.处理查询结果集,因为我们没有执行查询操作,所以第五步省略

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
//          6.释放资源
//            为了保证资源一定释放,要下载finally代码块中关闭资源
//            按照从小到大依次关闭
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.完成简单 更新  操作

import java.sql.*;

public class JDBCTest02 {
    public static void main(String[] args) {
        Connection conn =null;
        Statement statement=null;
        try {
//          1.注册驱动
            Driver driver = new com.mysql.cj.jdbc.Driver();
            DriverManager.registerDriver(driver);

//          2.获取连接
            String url="jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT";
            String username="root";
            String password="admin";
            conn = DriverManager.getConnection(url,username,password);


//           3.获取数据库操作对象(专门执行SQL语句)
            statement= conn.createStatement();
//           4.执行SQL语句
            String sql = "update t_book set id=44 where id=33 ";
//          专门执行DML语句(增删改)
//          返回值是“影响数据库中的影响条数”
            int count = statement.executeUpdate(sql);
            System.out.println("sql命令影响数据库条数:"+count);
//          5.处理查询结果集,因为我们没有执行查询操作,所以第五步省略

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
//          6.释放资源
//            为了保证资源一定释放,要下载finally代码块中关闭资源
//            按照从小到大依次关闭
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4.完成简单的查询操作

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

public class JDBCTest05 {
    public static void main(String[] args) {
        //      使用资源绑定器绑定属性配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("application");
        String driver=bundle.getString("driver");
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password =bundle.getString("password");

        Connection conn =null;
        Statement statement=null;
        ResultSet rs = null;

        try {
//          1.注册驱动  这种经常使用
            Class.forName(driver);
//          2.获取连接
            conn = DriverManager.getConnection(url,user,password);

//          3.获取数据库操作对象(专门执行SQL语句)
            statement= conn.createStatement();

//           4.执行SQL语句
            String sql = "select id,bookName,statue,type from t_book";
//          返回值是“影响数据库中的影响条数”
//          专门执行DQL语句的方法
            rs = statement.executeQuery(sql);

//          5.处理查询结果集,因为我们没有执行查询操作,所以第五步省略
            while(rs.next()){
/*//          getString()方法特点:不管数据库中的数据类型是什么,都以String形式取出
              String  id =  rs.getString(1);  //数据库表中的第一列
              String  bookName =  rs.getString(2);//数据库表中的第二列
              String  statue =  rs.getString(3);//数据库表中的第三列
              String  type =  rs.getString(4);//数据库表中的第四列*/

//              下面是用方法中的参数是 查询语句中的想要查找的那列的名称,这个地方不需要和数据库中的字段名对应
//              而在select语句中,所查询的字段名要和数据库中的字段名进行对应
                String  id =  rs.getString("id");
                String  bookName =  rs.getString("bookName");
                String  statue =  rs.getString("statue");
                String  type =  rs.getString("type");
//              这个地方的数据不仅仅String
//                int id = rs.getInt("id");
//                double id = rs.getDouble("id");
                System.out.print(id+"   ");
                System.out.print(bookName+"   ");
                System.out.print(statue+"   ");
                System.out.println(type+"   ");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
//          6.释放资源
//            为了保证资源一定释放,要下载finally代码块中关闭资源
//            按照从小到大依次关闭
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 先了解处理结果集 

三、从属性资源文件中读取连接到数据库

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;

public class JDBCTest03 {
    public static void main(String[] args) {
//      使用资源绑定器绑定属性配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("application");
        String driver=bundle.getString("driver");
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password =bundle.getString("password");

        Connection conn =null;
        Statement statement=null;


        try {
//            1.注册驱动  这种经常使用
            Class.forName(driver);
//            2.获取连接
            conn = DriverManager.getConnection(url,user,password);
            //           3.获取数据库操作对象(专门执行SQL语句)
            statement= conn.createStatement();
//           4.执行SQL语句
            String sql = "update t_book set id=33 where id=44 ";
//          专门执行DML语句(增删改)
//          返回值是“影响数据库中的影响条数”
            int count = statement.executeUpdate(sql);
            System.out.println("sql命令影响数据库条数:"+count);
//          5.处理查询结果集,因为我们没有执行查询操作,所以第五步省略
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
//          6.释放资源
//            为了保证资源一定释放,要下载finally代码块中关闭资源
//            按照从小到大依次关闭
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

四、解决SQL注入问题

   1.演示SQL注入问题

    我们可以看下面的一段登录验证代码:

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

public class JDBCTest06 {
    public static void main(String[] args) {
//      初始化一个界面
        Map<String,String> userLoginInfo = initUI();
//      验证用户名和密码
        Boolean  loginSuccess = login(userLoginInfo);
//      最后输出结果
        System.out.println(loginSuccess ? "登录成功.":"登录失败.用户名或密码错误.");
    }

//          编写JDBC代码
    private static Boolean login(Map<String, String> userLoginInfo) {

        Boolean  loginSuccess =false;

        String userName =userLoginInfo.get("userName");
        String password =userLoginInfo.get("password");
        Connection conn = null;
        Statement  stmt = null;
        ResultSet rs = null;
        try {
//          1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
//          2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT","root","admin");
//          3.获取数据库操作对象
            stmt = conn.createStatement();
//          4.执行SQL语句
            String sql ="select * from t_student where userName='"+userName+"' and password= '"+password+"'  ";
            rs=stmt.executeQuery(sql);
            if(rs.next()){
//                登陆成功
                loginSuccess = true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn !=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

          return loginSuccess;
    }

    //    初始化用户界面(通过控制带接受用户信息),返回登陆者的用户名和密码
    private static Map<String, String> initUI() {
        Scanner s = new Scanner(System.in);

        System.out.print("用户名:");
        String userName = s.nextLine(); //一读读一行

        System.out.print("密码:");
        String password = s.nextLine();

        Map<String,String> userLoginInfo = new HashMap<>();
        userLoginInfo.put("password", password);
        userLoginInfo.put("userName", userName);

        return userLoginInfo;
    }
}

我们发现,只要按照上面的格式输入,即是我们数据库中不存在这一组用户名和密码,依然可以登陆成功,这就是SQL注入的问题

2.解决SQL注入问题

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

public class JDBCTest06 {
    public static void main(String[] args) {
//      初始化一个界面
        Map<String,String> userLoginInfo = initUI();
//      验证用户名和密码
        Boolean  loginSuccess = login(userLoginInfo);
//      最后输出结果
        System.out.println(loginSuccess ? "登录成功.":"登录失败.用户名或密码错误.");
    }

//          编写JDBC代码
    private static Boolean login(Map<String, String> userLoginInfo) {

        Boolean  loginSuccess =false;

        String userName =userLoginInfo.get("userName");
        String password =userLoginInfo.get("password");
        Connection conn = null;
        PreparedStatement ps=null;//预编译操作对象
        ResultSet rs = null;
        try {
//          1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
//          2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT","root","admin");
//          3.获取预编译的数据库操作对象
            String sql ="select * from t_student where userName=? and password=?";  //这是SQL语句框架
//           ? 是占位符  一个?代表一个值
            ps = conn.prepareStatement(sql);
//            给占位符传值(第一个?是1,第二个时2,下标从1开始)
            ps.setString(1,userName);
            ps.setString(2,password);
//          4.执行SQL语句
            rs=ps.executeQuery();
//          5.处理结果集
            if(rs.next()){
//                登陆成功
                loginSuccess = true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn !=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

          return loginSuccess;
    }

    //    初始化用户界面(通过控制带接受用户信息),返回登陆者的用户名和密码
    private static Map<String, String> initUI() {
        Scanner s = new Scanner(System.in);

        System.out.print("用户名:");
        String userName = s.nextLine(); //一读读一行

        System.out.print("密码:");
        String password = s.nextLine();

        Map<String,String> userLoginInfo = new HashMap<>();
        userLoginInfo.put("password", password);
        userLoginInfo.put("userName", userName);

        return userLoginInfo;
    }
}

3.对比PreparedStatement与Statement

五、PreparedStatement完成增删改以及模糊查询

增:

删:

 改:

模糊查询:

六、JDBC事务机制

      JDBC事物机制: JDBC中的事物是自动提交的,只要执行一条DML语句,就自动提交一次(这是JDBC默认的事物行为)

    但是在实际的业务中,通常都是N条DML语句共同联合才能够完成,必须保证这些DML语句在同一个事物中同时成功或同时失败

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱布朗熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值